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

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

11 ответов

Решение

Как упомянуто в сообщении Марка Лонгаира в Git Submodules Explained,

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

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

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

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

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

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

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

Как Noam комментирует ниже, этот вопрос упоминает, что начиная с git версии 1.7.2, вы можете игнорировать грязные субмодули с помощью:

git status --ignore-submodules=dirty

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

git config --global diff.ignoreSubmodules dirty

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

[diff]
  ignoreSubmodules = dirty

Дополнительную информацию можно найти здесь

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

К сожалению, кажется, что нет параметров конфигурации, чтобы сделать "git diff --ignore-submodules" и "git status --ignore-submodules" глобальным значением по умолчанию (но см. Также Установка флагов git default в командах). Однако вы можете установить значение по умолчанию ignore опция конфигурации для каждого отдельного подмодуля, который вы хотите игнорировать (для обоих 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 показало, что мой HEAD был отсоединен -> мастер git checkout, статус git, чтобы снова увидеть измененный файл, git checkout >filename<, git pull и все снова в порядке.

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

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

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

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

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

[core]
  filemode = false

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

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

git submodule update --recursive --remote --init

Источники:

Как мне вернуть мои изменения в подмодуль git?

Простой способ получить последние из всех подмодулей git

У вас есть соответствующие разрешения для вашего репо?

Мое решение не было связано, однако я видел те же сообщения об ошибках и грязный статус подмодулей.

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

У тебя та же проблема?

Из корневой папки вашего репозитория используйте find для вывода списка файлов, принадлежащих пользователю root [необязательно]

      find .git -user root

Решение [Linux]

Измените все файлы в .gitпапка, чтобы вы были ее владельцем

      sudo chown -R $USER:$USER .git

# alternatively, only the files listed in the above command...
sudo find .git -user root -exec chown $USER:$USER {} +

Как это случилось?

В моем случае я построил библиотеки в подмодулях из контейнера докеров, демон докера традиционно запускается как, поэтому созданные файлы попадают в root:root владение.

У моего пользователя есть права root через прокси-сервер через эту службу, поэтому, хотя я не sudo ничего, в моем репозитории git все еще были изменения, принадлежащие root.

Надеюсь, это кому-то поможет, убирайся отсюда.

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

Другие вопросы по тегам