Как различить один файл в произвольной версии в Git?

324

Как я могу передать файл, скажем pom.xml, из основной ветки в произвольную более старую версию в Git?

Крис К
источник

Ответы:

347

Ты можешь сделать:

git diff master~20:pom.xml pom.xml

... чтобы сравнить ваш текущий pom.xmlс тем из master20 ревизий назад через первого родителя. master~20Конечно, вы можете заменить его именем объекта (SHA1sum) коммита или любым другим способом указания ревизии .

Обратите внимание, что это на самом деле сравнение старого pom.xmlс версией в вашем рабочем дереве, а не с версией, зафиксированной в master. Если вы хотите этого, тогда вы можете сделать следующее:

git diff master~20:pom.xml master:pom.xml
Марк Лонгэйр
источник
12
Обратите внимание, что это работает не только для файлов, но и для (под) каталогов, например git diff <revision>:foo/ HEAD:foo/.
2
Также обратите внимание, что в Windows вам нужно использовать прямую косую черту для каталогов, если вы используете спецификатор ревизии, или git выдаст вам ошибку о файле / каталоге, которого нет в этой ревизии.
Дилан Ниссли
1
@DylanNissley или он не даст вам никакой ошибки и различий. Вот что я вижу. В любом случае, спасибо за подсказку об использовании прямых, а не обратных.
Гэри С.
С файлами Windows я нашел, что проще сменить каталог и затем вызвать git diff master ~ 20: ./ pom.xml ./pom.xml
lloyd
Некоторые версии git требуют "-" между <revision> & <path>
Джош,
140
git diff <revision> <path>

Например:

git diff b0d14a4 foobar.txt
Бенджамин Поллак
источник
не работает для версии 1.7.11, если файл не находится в текущем каталоге. Пример: «git diff f76d078 test / Config» выдает «ошибку: не удалось получить доступ к« test / f76d078 »»
simpleuser
1
@ user1663987 просто пройти полный путь относительно корня проекта: git diff <revision> root/path/file.
1
test / Config относится к корню (так как в тесте есть подкаталог корня). но тогда ваш пример root / путь / файл, кажется, включает корень?
simpleuser
41

Если вы хотите увидеть разницу между последним коммитом одного файла, вы можете сделать:

git log -p -1 filename

Это даст вам разницу в файле в git, не сравнивая ваш локальный файл.

Херардо
источник
2
это ничего не возвращает
Андрей Кристиан Продан
@AndreiCristianProdan Тогда у вас нет никаких изменений там. Вы можете увеличивать -1шаг за шагом, пока не получите изменения.
Кайзер
Это очень мило. Я создал функцию bash, которая может быть полезна: gitlog () { git log -${3:-p} -${2:-1} $1; } используется как: gitlog Rakefileили gitlog Rakefile 5и gitlog Rakefile 10 s. Первый показывает один diff; второй показывает пять различий; третий показывает десять --no-patch.
auxbuss
18

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

git diff HEAD~1 path/to/file.

Вы можете изменить число (~ 1) на n-й коммит, с которым вы хотите получить разницу.

Juampy NR
источник
Этот ответ на самом деле является лишь частным случаем этого более общего ответа , где HEAD~1его подставляют <revision>, что делает этот ответ дубликатом.
1
это не работает! fatal: неоднозначный аргумент 'HEAD ~ 1': неизвестная ревизия или путь не в рабочем дереве. Используйте '-', чтобы отделить пути от ревизий
Андрей Кристиан Продан
Этот ответ прост и функциональн для меня.
Дуглас Фрари
6

Общий синтаксис:

$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt

для всех файлов с именем «FileName.xml» в любом месте вашего репо.

Обратите внимание на пробел между "-" и "**"

Ответьте на свой вопрос:

$git checkout master
$git diff oldCommit..HEAD -- **pom.xml 
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml 

как всегда с git, вы можете использовать тэг / sha1 / "HEAD ^", чтобы идентифицировать коммит.

Протестировано с git 1.9.1 на Ubuntu.

soundslikeodd
источник
6

Если ни один из коммитов не является вашим HEAD, то расширение скобок bash оказывается действительно полезным, особенно если ваши имена файлов длинные, пример выше:

git diff master~20:pom.xml master:pom.xml

Станет

git diff {master~20,master}:pom.xml

Подробнее о расширении Brace с помощью bash.

robstarbuck
источник
6

Для сравнения 5-ти коммитов с текущим, обоими master, просто сделайте:

git diff master~5:pom.xml master:pom.xml

Также вы можете обратиться к хэш-номеру коммита, например, если хеш-номер равен x110bd64, вы можете сделать что-то вроде этого, чтобы увидеть разницу:

git diff x110bd64 pom.xml
Алиреза
источник
4

git diff -w HEAD origin / master path / to / file

CatalinBerta
источник
2
git diff master~20 -- pom.xml

Работает, если вы тоже не в мастер ветке.

Гунар Гесснер
источник
2

Если вы хорошо используете графический инструмент (или даже предпочитаете его), вы можете:

gitk pom.xml

В gitk вы можете затем щелкнуть любой коммит (чтобы «выбрать» его) и щелкнуть правой кнопкой мыши любой другой коммит, чтобы выбрать «Разбросить это - выбранный» или «Разбросить выбранный -> этот», в зависимости от того, какой порядок вы предпочитаете.

Мартин Г
источник
0

Если вам нужно сравнить один файл в тайнике, например, вы можете сделать

git diff stash@{0} -- path/to/file
lacostenycoder
источник
-1

Если вы ищете diff для определенного коммита и хотите использовать пользовательский интерфейс github вместо командной строки (скажем, вы хотите связать его с другими людьми), вы можете сделать:

https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>

Например:

https://github.com/grails/grails-core/commit/02942c5b4d832b856fbc04c186f1d02416895a7e/grails-test-suite-uber/build.gradle

Обратите внимание на ссылки «Предыдущая» и «Следующая» в правом верхнем углу, которые позволяют перемещаться по всем файлам в коммите.

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

Schmick
источник