Git diff говорит, что подпроект грязный

Я только что запустил git diff, и я получаю следующий вывод для всех моих приблизительно 10 подмодулей

diff --git a/.vim/bundle/bufexplorer b/.vim/bundle/bufexplorer
--- a/.vim/bundle/bufexplorer
+++ b/.vim/bundle/bufexplorer
@@ -1 +1 @@
-Subproject commit 8c75e65b647238febd0257658b150f717a136359
+Subproject commit 8c75e65b647238febd0257658b150f717a136359-dirty

что это значит? Как это исправить?

9 ответов


как уже упоминалось в блоге Марк Longair после Git Submodules Explained,

версии 1.7.0 и более поздние версии git содержат раздражает изменение в поведении подмодуля git.
подмодули теперь считаются грязными, если у них есть какие-либо измененные файлы или неотслеженные файлы, тогда как раньше это было бы только в том случае, если HEAD в подмодуле указал на неправильный фиксатор.

смысл знака "плюс" (+) на выходе подмодуля git изменился, и в первый раз, когда вы сталкиваетесь с этим, требуется некоторое время, чтобы понять, что происходит не так, например, просматривая списки изменений или используя git bisect на git.git, чтобы найти изменение. Пользователям было бы гораздо добрее ввести другой символ для "в указанной версии, но грязный".

вы можете исправить это:

  • либо совершение, либо отмена изменения / эволюции внутри каждого из ваших подмодулей, прежде чем вернуться к родительскому РЕПО (где diff больше не должен сообщать о "грязных" файлах). Чтобы отменить все изменения в вашем подмодуле просто cd в корневой каталог вашего подмодуля и do git checkout .

    dotnetCarpenter комментарии что вы можете сделать:git submodule foreach --recursive git checkout .

  • или добавить --ignore-submodules на git diff, чтобы временно игнорировать эти "грязные" подмодули.

новое в Git версии 1.7.2

As Ноам комментариях ниже., этот вопрос упоминает, что с Git версии 1.7.2, вы можете игнорировать грязные подмодули с:

git status --ignore-submodules=dirty

также удаление подмодуля, а затем запуск git submodule init и git submodule update, очевидно, сделает трюк, но не всегда может быть подходящим или возможным.


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


к сожалению, нет параметров конфигурации, чтобы сделать" git diff --ignore-submodules "и" git status --ignore-submodules " глобальным по умолчанию (но см. также установка флагов git по умолчанию для команд). Однако вы можете установить значение по умолчанию ignore параметр config для каждого отдельного подмодуля, который вы хотите игнорировать (для обоих git diff и git status), либо .git/config файл (только локальный) или .gitmodules (будет версионным git). Например:

[submodule "foobar"]
    url = git@bitbucket.org:foo/bar.git
    ignore = untracked

ignore = untracked в игнорировать только неотслеженные файлы,ignore = dirty также игнорировать измененные файлы, и ignore = all игнорировать также совершает. По-видимому, нет способа подстановки для всех подмодулей.


git submodule foreach --recursive git checkout .

это не сделало трюк для меня, но он дал мне список файлов (в моем случае только один), которые были изменены в подмодуле (без меня там ничего не делать).

таким образом, я мог отправиться в подмодуль, и статус git показал мне, что моя голова была отделена -> git checkout master, git status, чтобы снова увидеть измененный файл, git checkout >filename


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

чтобы отключить filemode в подмодуле, вы можете редактировать /.git / modules / path/to/your/submodule / config и добавить

[core]
  filemode = false

Если вы хотите игнорировать все измененные состояния, вы можете либо установить ignore = dirty в собственность /.gitmodules file, но я думаю, что лучше отключить только filemode.


Я закончил тем, что удалил каталог подмодулей и инициализировал его еще раз

cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule update


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

git config --global diff.ignoreSubmodules dirty

Он добавит следующий параметр конфигурации в локальную конфигурацию git:

[diff]
  ignoreSubmodules = dirty

дополнительная информация здесь