Подтвердить что ты не робот

Как сравнить рабочее дерево с фиксацией?

Я использую

git diff mycommit

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

git init
echo A > A.txt; git add .; git commit -m A; git branch A
echo B > B.txt; git add .; git commit -m B; git branch B
git reset --hard A
echo BB > B.txt
git diff B

Выход (с git версия 1.7.3.3) пуст. Использование --diff-filter=ACDMRTUXB показывает "удаленный файл", что также неверно, так как файл B.txt существует как в рабочем дереве, так и в commit B. IMHO, файл должен быть указан как измененный. Удивительно, но он работает после добавления файла в индекс, хотя это не индекс, который сравнивается. Как я могу получить правильный diff без него?

4b9b3361

Ответ 1

manojlds написал в своем ответе

В принципе, diff не учитывает файлы без следа. Вот почему вы видите, что файл удален, поскольку diff совпадает с git diff B A

Это верно и стоит того, чтобы оправдать меня, но это меня не удовлетворило, поскольку он говорит, что ни "как я могу его сравнить" не дал ему более глубокой причины. Я все еще думал, что это ошибка, поэтому я спросил на форуме git и получил длинный ответ тем, кто точно знает. Для меня важны следующие детали:

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

и

..., который даст чистую семантику "git diff HEAD": какое изменение я буду записывать, если я сказал "git commit -a" в этот момент?

Ответ 2

Простая графика может помочь:

enter image description here

Итак, вы можете запросить три типа различий:

  • git diff --cached В этом разница между тем, что находится в индексе и последней фиксацией. Он показывает вам, что изменения будут в следующем фиксации.

  • git diff Это показывает разницу между индексом и рабочим деревом. Это изменения, внесенные вами в файлы с момента последнего добавления их в индекс. Вот почему я не получал никаких результатов. У меня не было никаких изменений между индексом и рабочим деревом.

  • git diff HEAD Это показывает разницу между файлами в рабочем дереве и последним фиксацией. Здесь есть информация: если вы внесли изменения, добавили их в индекс, а затем отменили эти изменения в рабочем дереве, вы не получите никаких результатов для git diff HEAD (потому что нет никакой разницы), но вы получите результат для git diff --cached, поскольку в индексе все еще есть изменения.

И если вы хотите сравнить его с предыдущими коммитами:

enter image description here

Это просто сравнивается с предыдущими коммитами, но вы можете заменить HEAD~ на любую другую ссылку на фиксацию.

Ответ 3

Вопрос в том, что я добавил файл в свое рабочее дерево, существующее в другом коммите. Почему git diff <commit> не показывает разницу между содержимым файла, которое существует в моем рабочем дереве, и содержимым файла, находящегося в другом коммите.

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

Попробуйте git diff HEAD, вы не увидите, что вы добавили B.txt в свое рабочее дерево.

В принципе, diff не учитывает файлы без следа. Вот почему вы видите, что файл удален, потому что diff совпадает с git diff B A

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

Скажем, вы передали файл, а затем изменили содержимое в рабочем дереве:

Теперь git diff HEAD покажет разницу между рабочим деревом и HEAD, показывая изменение, которое вы сделали в своем рабочем дереве в отслеживаемых файлах. То же самое с git diff B

Ответ 4

Если все, что вам нужно, это вернуть изменения в рабочем дереве в ветку/коммит B, вы можете сделать:

git diff B | git apply -R

Это создаст разницу между B и рабочим деревом и применит его в обратном порядке.