Как заставить Git игнорировать изменения режима файла (chmod)?

2311

У меня есть проект, в котором я должен изменить режим файлов chmodна 777 при разработке, но который не должен меняться в основном репо.

Git забирает chmod -R 777 .и помечает все файлы как измененные. Есть ли способ заставить Git игнорировать изменения режима, которые были внесены в файлы?

Маркус Вестин
источник
17
Это полезно при работе с Git на Windows + Bash на Ubuntu на Windows
Элазар
4
Для тех , кто хочет просто игнорировать изменения прав доступа для конкретного вызова git diff, и кто поэтому не хочет изменять свои файлы конфигурации Git: вы можете использовать git diff -G.в Zed в ответ здесь .
Сампаблокупер

Ответы:

3824

Пытаться:

git config core.fileMode false

Из git-config (1) :

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

-cФлаг может быть использован для установки этой опции для разовых команд:

git -c core.fileMode=false diff

И --globalфлаг сделает это поведение по умолчанию для вошедшего в систему пользователя.

git config --global core.fileMode false

Изменения глобального параметра не будут применены к существующим репозиториям. Кроме того, git cloneи в git initявном виде установить core.fileModeдля trueв конфигурации репо , как описано в Git глобальной core.fileMode ЛОЖЬ переопределяется локально на клоне

Предупреждение

core.fileModeэто не лучшая практика и должна использоваться осторожно. Этот параметр охватывает только исполняемый бит режима и никогда не считывает / записывает биты. Во многих случаях вы думаете, что вам нужен этот параметр, потому что вы сделали что-то вроде chmod -R 777, сделав все ваши файлы исполняемыми. Но в большинстве проектов большинство файлов не нужно и не должно быть исполняемым по соображениям безопасности .

Правильный способ решения такой ситуации - отдельно обрабатывать права доступа к папкам и файлам, например:

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

Если вы сделаете это, вам никогда не придется использовать core.fileMode, кроме как в очень редких условиях.

Грег Хьюгилл
источник
203
Если вы это git config --global core.filemode falseсделаете, вам нужно будет сделать это только один раз для всех репозиториев.
Грег
13
это не работало для меня, пока я не исправил случай, это должен быть fileMode вместо filemode
tishma
8
@tishma: Раздел конфигурации Git и имена переменных не зависят от регистра в соответствии с документацией, см. раздел КОНФИГУРАЦИОННЫЙ ФАЙЛ , так что, если вышеописанное не сработало для вас, то это было по другой причине.
Грег Хьюгилл
11
@donquixote: git configкоманда записывает настройки в правильный файл конфигурации ( .git/configтолько для текущего репозитория или ~/.gitconfigпри использовании с --global).
Грег Хьюгилл
8
@ zx1986: это не важно. Из git config : «Имена переменных не чувствительны к регистру, ...»
Грег Хьюгилл,
277

изменение режима отмены в рабочем дереве:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

Или в Mingw-Git

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x
Yoda
источник
42
На OS X Lion пропустите -d'\n'часть, xargsпоскольку это недопустимый аргумент (и не нужен).
Паскаль
9
Вы можете игнорировать любые ошибки, связанные с "chmod: отсутствует операнд после` + x '"
Кейси Уотсон,
5
это актуально? Я получаю 'chmod: слишком мало аргументов' в mingw
Hammett
7
@Pascal @pimlottc -d определяет разделитель как новую строку вместо любых пробелов. В BSD xargs такой опции нет, но вместо этого вы можете направить вывод tr '\n' '\0'и затем использовать -0arg для xargs, чтобы использовать NUL в качестве разделителя.
Марк Ауффлик
10
Круто, trвещь сработала! Вот полная команда для OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye
135

Если вы хотите установить эту опцию для всех своих репозиториев, используйте эту --globalопцию.

git config --global core.filemode false

Если это не работает, вы, вероятно, используете более новую версию git, поэтому попробуйте эту --addопцию.

git config --add --global core.filemode false

Если вы запустите его без опции --global и ваш рабочий каталог не будет репозиторием, вы получите

error: could not lock config file .git/config: No such file or directory
Adrien
источник
5
Похоже, что позже GIT использует --add, как вgit config --add --global core.filemode false
mgaert
14
Если локальная конфигурация репозитория уже имеет filemode = true, то изменение глобальной конфигурации не поможет, так как локальная конфигурация переопределит глобальную конфигурацию. Придется менять местный конфиг каждого репо машины один раз
Ракиб
3
ПОЖАЛУЙСТА: обновите этот ответ предупреждением syedrakib! Все было безумно, пока я не нашел это, и имело смысл после.
Джеркларке
88

Если

git config --global core.filemode false

у вас не работает, делайте это вручную:

cd into yourLovelyProject folder

Перейдите в папку .git:

cd .git

отредактируйте файл конфигурации:

nano config

изменить истину на ложь

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

сохранить, выйти, перейти в верхнюю папку:

cd ..

переосмыслить мерзавца

git init

вы сделали!

Синан Элдем
источник
11
Вместо редактирования .git/configдостаточно простого git config core.fileMode falseкорня вашего проекта. Если вы отредактируете файл конфигурации, вам лучше полностью удалить директиву, чтобы была выбрана глобальная.
Феликс
6
-1 если git config --global не работает, это означает, что у вас нет прав для этого на системном уровне, удаление globalопции делает то же самое, что и ручное редактирование .git / config
CharlesB
Неправильный @CharlesB - ответ дал обходной путь, поместив опцию прямо в проект, сделав его специфичным для проекта. Это не будет работать с другими git-проектами, которые вы делаете / извлекаете в будущем, но работает для проекта, над которым вы работаете. (давайте удостоверимся, что мы устраняем неоднозначность ~/.gitconfig, и ~/project/.git/config)
ddavison
После того, как это запустится, git initмы должны установить для filemode значение true?
Иордания
53

Добавление к ответу Грега Хьюгилла (об использовании core.fileModeпеременной config):

Вы можете использовать --chmod=(-|+)xопцию git update-index (низкоуровневая версия «git add»), чтобы изменить разрешения на выполнение в индексе, откуда он будет взят, если вы используете «git commit» (а не «git commit -a»). «).

Якуб Наребски
источник
2
Это должно было быть отредактировано в ответе Грега Хьюгилла, а не добавлено как отдельный ответ, таким образом создавая один высший ответ с единственным однозначным представлением.
Грег
6
@ Грег: Нужно иметь достаточно очков, чтобы редактировать не собственный ответ; Я думаю, что мне не хватало прав на редактирование в то время.
Якуб Наребски
1
@Jakub Я думаю, у тебя достаточно репутации :) Как будет выглядеть эта команда для файла примера?
Алекс Холл
38

Вы можете настроить его глобально:

git config --global core.filemode false

Если вышеприведенное не работает для вас, причина может заключаться в том, что ваша локальная конфигурация переопределяет глобальную конфигурацию.

Удалите локальную конфигурацию, чтобы глобальная конфигурация вступила в силу:

git config --unset core.filemode

В качестве альтернативы вы можете изменить локальную конфигурацию на правильное значение:

git config core.filemode false

Тайлер Лонг
источник
4
Если основной ответ вам не поможет - попробуйте этот. Если вы хотите проверить свою локальную конфигурацию, не изменяя ее, проверьте git config -l(перечислите текущую конфигурацию - как локальную, так и глобальную)
Krzysztof Bociurko
23

Если вы уже использовали команду chmod, проверьте разницу в файле. Она показывает предыдущий режим файла и текущий режим файла, например:

новый режим: 755

старый режим: 644

установить старый режим всех файлов, используя команду ниже

sudo chmod 644 .

Теперь установите для core.fileMode значение false в файле конфигурации, используя команду или вручную.

git config core.fileMode false

затем примените команду chmod, чтобы изменить права доступа ко всем файлам, таким как

sudo chmod 755 .

и снова установите для core.fileMode значение true.

git config core.fileMode true

Для лучшей практики не оставляйте core.fileMode false всегда.

Кишор Витекар
источник
Вы говорите, что весь проект (в разработке, постановке и производстве) должен быть 755?
Даниил
@Daniel Feb: Нет. Изменить режим только необходимых файлов.
Кишор Витекар
For best practises don't Keep core.fileMode false alwaysчто вы имеете в виду, вы должны это объяснить.
bg17aw
For best practises don't Keep core.fileMode false always.Некоторые файловые системы (например, FAT) не поддерживают права доступа к файлам, поэтому ОС сообщит значение по умолчанию (в любом случае 766 в моей системе). В этом случае core.filemodeэто абсолютно необходимо в локальной конфигурации, если только вы не хотите раздувать историю коммитов с ненужными и непреднамеренными изменениями разрешений
KevinOrr
Кроме того, почему вы вообще не хотите менять перманент? Если вы установили, core.filemode=falseто git будет игнорировать изменения битов выполнения, не нужно менять локальные права доступа. Если вы уже не добавили изменения разрешений в индекс, в этом случае вы пропускаете шаг, который вам понадобится git addпосле выключения core.filemode.
KevinOrr
18

Определив следующий псевдоним (в ~ / .gitconfig), вы можете легко временно отключить команду fileMode per git:

[alias]
nfm = "!f(){ git -c core.fileMode=false $@; };f"

Когда этот псевдоним добавляется к команде git, изменения режима файла не будут отображаться с командами, которые в противном случае отображали бы их. Например:

git nfm status
Виль
источник
14

Если вы хотите установить для filemode значение false в файлах конфигурации рекурсивно (включая подмодули): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'

dryobs
источник
5
Это не будет работать, если этой строки нет в файле конфигурации. Если вы хотите изменить его для подмодулей, попробуйте это:git submodule foreach git config core.fileMode false
courtlandj
4

Простое решение:

Нажмите эту простую команду в папке проекта ( она не удалит ваши исходные изменения) ... она удалит только те изменения , которые были сделаны, пока вы изменили разрешение папки проекта

Команда ниже:

git config core.fileMode false

Почему все эти ненужные файлы модифицируются: потому что вы изменили права доступа к папке проекта с помощью commend sudo chmod -R 777 ./yourProjectFolder

когда вы будете проверять изменения, что вы не сделали? вы нашли как показано ниже при использовании git diff filename

old mode 100644
new mode 100755
Шашват Гупта
источник
1

Это работает для меня:

find . -type f -exec chmod a-x {} \;

или наоборот, в зависимости от вашей операционной системы

find . -type f -exec chmod a+x {} \;
Мартин Волек
источник
1
Это изменит права доступа к файлу, но не заставит git игнорировать права доступа к файлу.
домдамброгия
Ну, вы правы, что не разрешает git игнорировать вещи.
Мартин Волек