Git diff каже, що підпроект забруднений


227

Я щойно запустив 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

Що це означає? Як це виправити?

Відповіді:


268

Як вже згадувалося в блозі Марка Лонгейра, пояснення Git Submodules Explained ,

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

Значення знаку плюс ( +) у виході підмодуля git змінилося, і коли ви вперше стикаєтесь з цим, потрібно трохи часу, щоб з'ясувати, що відбувається не так, наприклад, переглянувши журнали змін або використовуючи біт біт на git .git, щоб знайти зміни. Користувачам було б набагато приємніше вводити інший символ "у вказаній версії, але брудно".

Ви можете виправити це:

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

    dotnetCarpenter коментує, що ви можете:git submodule foreach --recursive git checkout .

  • або додати --ignore-submodulesдо своїх git diff, щоб тимчасово ігнорувати ці "брудні" підмодулі.

Нове у версії 1.7 Git

Як зауважує Ноам нижче , це питання зазначає, що, оскільки версія git 1.7.2, ви можете ігнорувати брудні підмодулі за допомогою:

git status --ignore-submodules=dirty

2
Також непогано знати: ви все одно можете виконувати, git commit -aне турбуючись, додаючи ці зміни. Хоча вони позначені Mспереду, вони не закінчаться у ваших зобов'язаннях.
gitaarik

1
Для мене мені довелося зайти в кожен брудний підмодуль і бігти git clean -id.
ВВП2

1
@ GDP2, який ви можете зробити в одному рядку, git submodule foreach --recursive git clean -id(щоб бути тестованим в резервному репо;)
VonC

1
У випадку, коли я це незрозуміло бачив, то, що відбувалося, було те, що у мене були відкручені файли, які не були в підмодулі .gitignore. Додавання їх туди або до мого глобального списку ігнорованих фіксованих речей.
Бен-

21

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


1
Це спрацювало для мене, коли я перетворив деякі існуючі папки на підмодулі, а потім перетягнув на іншу машину, у якій були ще старі папки.
Роджер Ліпскомб

18

Щоб ігнорувати всі відслідковувані файли в будь-якому підмодулі, використовуйте наступну команду, щоб ігнорувати ці зміни.

git config --global diff.ignoreSubmodules dirty

Він додасть наступний параметр конфігурації у ваш локальний git config:

[diff]
  ignoreSubmodules = dirty

Додаткову інформацію можна знайти тут


16

EDIT : Ця відповідь (і більшість інших) застаріла; див замість відповіді Devpool .


Спочатку не було параметрів конфігурації, щоб зробити " git diff --ignore-submodules" і " git status --ignore-submodules" глобальний за замовчуванням (але див. Також Налаштування прапорів git за замовчуванням для команд ). Альтернативно - встановити 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також ігнорувати. Мабуть, немає способу підкреслити це для всіх підмодулів.


13

Це так, тому що покажчик, який ви маєте для підмодуля, не є тим, що є насправді в каталозі субмодулів. Щоб виправити це, потрібно запустити git submodule updateще раз:


9
git submodule foreach --recursive git checkout .

Це не зробило для мене хитрощів, але воно дало мені список файлів (у моєму випадку лише один), які були змінені в підмодулі (без цього я нічого не робив).

Тож я міг перейти до підмодулю, і статус git показав мені, що мій HEAD був відокремлений -> git checkout master, git status, щоб ще раз переглянути модифікований файл, git checkout> ім'я файлу <, git pull і все знову добре.


9

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

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

4
Я б швидше зрозумів, що сталося, але це також було єдиним, що працювало на мене ...
smilebomb

6

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

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

[core]
  filemode = false

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


1

У моєму випадку я не був впевнений, що спричинило це, але я знав, що просто хочу, щоб підмодулі були скинуті до їх останніх віддалених фіксованих передач і зробити це з ним. Це стосувалося комбінування відповідей з декількох різних питань тут:

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

Джерела:

Як повернути свої зміни до підмодулю git?

Простий спосіб витягнути останні з усіх підмодулів git

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.