git: Как сравнить измененные файлы с предыдущими версиями после извлечения?

117

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

Как это сделать?

Я предполагаю, что это "git diff" с некоторыми параметрами для фиксации x по сравнению с фиксацией y, но я не могу понять синтаксис. Я также нахожу "git log" немного сбивающим с толку и не уверен, где взять идентификатор фиксации моей последней версии файла по сравнению с новой.

Дуг
источник
1
Возможно, вам больше по вкусу графический инструмент gitk.
Crazyscot
stackoverflow.com/questions/61002/… может быть похож на этот
VonC

Ответы:

158

Есть всевозможные замечательные способы указать коммиты - см. Раздел, посвященный указанию ревизий,man git-rev-parse для более подробной информации. В этом случае вам, вероятно, понадобится:

git diff HEAD@{1}

Это @{1}означает «предыдущую позицию ссылки, которую я указал», так что она соответствует тому, что вы проверили ранее - непосредственно перед вытягиванием. Вы можете закрепить HEADтам конец, если у вас также есть некоторые изменения в вашем рабочем дереве, и вы не хотите видеть различия для них.

Я не уверен, что вы просите с «идентификатором фиксации моей последней версии файла» - «идентификатор» фиксации (хэш SHA1) - это 40-символьный шестнадцатеричный код прямо в верхней части каждой записи в выходных данных. журнала git. Это хеш для всего коммита, а не для данного файла. Вам действительно никогда не нужно больше - если вы хотите различать только один файл через пул, сделайте

git diff HEAD@{1} filename

Это общая вещь - если вы хотите знать о состоянии файла в данной фиксации, вы указываете фиксацию и файл, а не идентификатор / хэш, специфичный для файла.

Cascabel
источник
Связанный предыдущий пост VonC говорит, по сути, то же самое, но объяснение немного другое, поэтому я оставлю это пока. (Это также используется @{1}как сокращение для HEAD@{1})
Cascabel
правда, но мне также нравится объяснение. +1
VonC
Это именно то, что я искал. Спасибо за объяснение.
lucapette 05
+1 за то, что гуглил. Было бы здорово, если бы это было выбрано в качестве ответа и поднялось наверх ... :)
longda
@longda Если вы сортируете по голосам (что, как я думал, было по умолчанию), оно уже должно быть наверху.
Cascabel
57

Мне нравится использовать:

git diff HEAD^

Или, если я хочу различать только определенный файл:

git diff HEAD^ -- /foo/bar/baz.txt
кадизм
источник
5
-1: HEAD^это родительская фиксация, а не pull
предыдущая
1
Если HEADэто фиксация слияния, HEAD^это первая родительская фиксация, так что да, это может быть фиксация перед pull. Чтобы получить другого родителя (для двустороннего слияния), используйте HEAD^2. Но тогда, приведенный выше ответ на самом деле не отвечает на вопрос, поэтому оставляю -1 ;-)
Майкл Уайлд,
Спасибо за разъяснения. Не очень внимательно прочитал вопрос, так как я искал что-то еще, и эта ссылка оказалась высоко на странице результатов. Я думал, что вмешаюсь, так как я новый пользователь и у меня нет кармы (если это так на SO). Моя вина =)
cadizm
3
@MichaelWild это могло быть не то, о чем спрашивал спрашивающий, но это было то, что я искал, когда нашел это. Мне это было полезно. Голосование за.
John Dvorak
Это то, что делает TortoiseGit «Отличие от предыдущей версии». И это то, что я искал.
Фабьен Хаддади
15

Если вы сделаете прямой, git pullто вы либо будете «перенаправлены», либо объедините неизвестное количество коммитов из удаленного репозитория. Это происходит как одно действие, поэтому последняя фиксация, в которой вы были непосредственно перед извлечением, будет последней записью в журнале ссылок, и к ней можно будет получить доступ как HEAD@{1}. Это означает, что вы можете:

git diff HEAD@{1}

Однако я настоятельно рекомендую, если вы обнаружите, что много делаете это, тогда вам следует подумать о том, чтобы просто выполнить git fetchи изучить полученную ветку, прежде чем вручную слить или переустановить ее. Например, если вы на мастере и собирались использовать origin / master:

git fetch

git log HEAD..origin/master

 # looks good, lets merge

git merge origin/master
CB Bailey
источник
Хорошее использование git logвместо вместо git diffздесь (даже если синтаксис немного несогласован между '..' for git logи '...' for git diff;) +1 См. Stackoverflow.com/questions/53569/… и stackoverflow.com/questions / 850607 /…
VonC
К счастью, если вы используете синтаксис ".." в команде git diff, git "делает правильные вещи".
CB Bailey,