Как сравнить файлы из двух разных веток?

1538

У меня есть скрипт, который отлично работает в одной ветви и сломан в другой. Я хочу взглянуть на две версии бок о бок и посмотреть, что отличается. Есть ли способы сделать это?

Чтобы было ясно, я не ищу инструмент сравнения (я использую Beyond Compare). Я ищу команду git diff, которая позволит мне сравнить основную версию с моей текущей версией ветки, чтобы увидеть, что изменилось. Я не посреди слияния или еще чего-нибудь. Я просто хочу сказать что-то вроде

git diff mybranch/myfile.cs master/myfile.cs
Михей
источник

Ответы:

2208

git diff может показать вам разницу между двумя коммитами:

git diff mybranch master -- myfile.cs

Или, что эквивалентно:

git diff mybranch..master -- myfile.cs

Используя последний синтаксис, если любая из сторон является, HEADэто может быть опущено (например, master..сравнивается masterс HEAD).

Вы также можете быть заинтересованы в mybranch...master(из git diffдокументов ):

Эта форма предназначена для просмотра изменений на ветви, содержащей и вплоть до второй <commit>, начиная с общего предка обоих <commit>. git diff A...Bэквивалентно git diff $(git-merge-base A B) B.

Другими словами, это приведет к разным изменениям, masterпоскольку оно отличается от mybranch(но без новых изменений с тех пор mybranch).


Во всех случаях --разделитель перед именем файла указывает на флаги конца командной строки. Это необязательно, если только Git не запутается, если аргумент ссылается на коммит или файл, но включение в него не является плохой привычкой. См. Https://stackoverflow.com/a/13321491/54249 для нескольких примеров.


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

dahlbyk
источник
44
И если ни одна из двух версий, которые вы хотите сравнить, не является рабочим деревом, вы можете использовать git diff branch1 branch2 myfile.cs. (В --этом больше нет необходимости, поскольку он может принимать до двух аргументов ревизии.)
Каскабель,
8
Я попробовал каждую версию этого, и ничего не происходит. У меня настроен difftool (он работает для слияния). У меня есть файл с именем bd.ps1. Каждая версия вводимой мной команды ничего не делает. Даже не дает ошибаться. WTH!?!?!
Михей
3
@Micah: Вы тоже пробуете это с простым diff? Правильно ли вы вводите путь относительно текущего каталога? (Если файл не существует, он будет молча показывать отсутствие различий, и вы используете --. Распространенную и простую ошибку.)
Cascabel
5
Это не сработало для меня, если я не включил полный путь к файлу, как показано git diff --name-status branch1..branch2(вероятно, очевидно, но подумал, что упомяну об этом на случай, если у кого-то еще возникнут те же проблемы, что и у меня).
hBrent
4
Порядок mybranch и master также важен. Файл в первой ветви будет отображаться с префиксами «-», файл во второй ветви будет отображаться с префиксами «+».
Тимбо
414

Ты можешь сделать это: git diff branch1:path/to/file branch2:path/to/file

Если у вас настроен difftool, вы также можете: git difftool branch1:path/to/file branch2:path/to/file

Смежный вопрос: Как просмотреть вывод git diff с помощью программы diff

Тим Хениган
источник
4
Использование двоеточий не очень хороший способ - это означает, что вы обращаетесь к файлам через древовидные объекты, поэтому вы должны ввести полный путь, а не относительно вашего текущего каталога.
Каскабель
13
@Jefromi, это могло измениться в более поздней версии, но по крайней мере теперь вы можете использовать относительные пути (например branch1:./file). Это также полезно, если файл находится в отдельном месте между ветвями (например git diff branch1:old/path/to/file branch2:new/path/to/file).
Redbmk
4
@redbmk Да, это было где-то между 2010 и сейчас! Тем не менее, если это один и тот же файл в обеих ветках, нет необходимости делать это так, просто git diff branch1 branch2 path/to/file.
Каскабель
3
@jefromi круто, я не был уверен, что сроки, когда это было добавлено. Да, я обычно использовал бы синтаксис, который вы упомянули, но ответ Тима помог мне понять, как сравнивать файлы с разными путями, хотя это не совсем то, о чем спрашивал вопрос
redbmk
1
Хотя мне нравится эта идея, я не могу заставить этот синтаксис работать или найти упоминание о нем в документации по git diff. Что мне не хватает? Спасибо!
йо
160

Более современный синтаксис:

git diff ..master path/to/file

Префикс с двойной точкой означает «из текущего рабочего каталога в». Вы также можете сказать:

  • master..т.е. обратное вышеописанному. Это так же, как master.
  • mybranch..master, явно ссылаясь на состояние, отличное от текущего рабочего дерева.
  • v2.0.1..masterссылка на тег.
  • [refspec]..[refspec]в основном все, что можно идентифицировать как состояние кода для git.
Джо Ацбергер
источник
33

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

  • Вариант 1. Если вы хотите сравнить файл из n определенной ветви с другой конкретной веткой:

    git diff branch1name branch2name path/to/file
    

    Пример:

    git diff mybranch/myfile.cs mysecondbranch/myfile.cs
    

    В этом примере вы сравниваете файл в ветке «mybranch» с файлом в ветке «mysecondbranch».

  • Вариант 2: Простой способ:

     git diff branch1:file branch2:file
    

    Пример:

     git diff mybranch:myfile.cs mysecondbranch:myfile.cs
    

    Этот пример аналогичен варианту 1.

  • Вариант 3: Если вы хотите сравнить ваш текущий рабочий каталог с какой-то веткой:

    git diff ..someBranch path/to/file
    

    Пример:

    git diff ..master myfile.cs
    

    В этом примере вы сравниваете файл из вашей фактической ветви с файлом в главной ветви.

Хавьер С.
источник
12

Я просто делаю git diff branch1 branch2 path/to/file

Это проверяет различия между файлами. Изменения branch1будут в красном. Изменения branch2будут в зеленом.

Предполагается, что branch1это прошлое и branch2будущее. Вы можете изменить это, изменив порядок ветвей в diff:git diff branch2 branch1

iGbanam
источник
Какая версия git diff может это сделать? Кажется, он не поддерживается в версии, которую я использую (2..9.2.windows.1).
Винс Боудрен
9

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

git diff $BRANCH -- path/to/file

таким образом он будет отличаться от текущей ветви к указанной ветви ( $BRANCH).

Пауло Фидальго
источник
5

Согласиться с ответом, предложенным @dahlbyk. Если вы хотите, чтобы diff записывался в файл diff для проверки кода, используйте следующую команду.

git diff branch master -- filepath/filename.extension > filename.diff --cached
Азад
источник
2

В моем случае я использую следующую команду:

git diff <branch name> -- <path + file name>

Эта команда может помочь вам сравнить один и тот же файл в двух разных ветках

СКТ
источник
1

Лучший способ сделать это с помощью git diff следующее: git diff <source_branch> <target_branch> -- file_path

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

Неша Зорич
источник
1

Используйте хеши коммитов так:

git diff <hash1> <hash2> <filename>

где hash1 может быть любым коммитом из любой ветви, то же самое для hash2 .

Prometeu
источник
1

Существует два сценария сравнения файлов:

Сценарий 1. Сравнение файлов в удаленных ветвях (обе ветки должны существовать в удаленном хранилище)

Сценарий 2: Сравните локальные файлы (в локальной копии рабочей области) с файлами в удаленном хранилище.

Логика проста. Если вы предоставите для diff два имени филиала, он всегда будет сравнивать удаленные ветви, а если вы предоставите только одно имя ветви, он всегда будет сравнивать вашу локальную рабочую копию с удаленным репо (который вы указали). Вы можете использовать диапазон для предоставления удаленных репозиториев.

напр. оформить заказ

git checkout branch1
git diff branch2 [filename]

в этом случае, если вы укажете имя файла, он сравнит вашу локальную копию имени файла с удаленной веткой с именем « branch2 ».

git diff branch1 branch2 [filename]

в этом случае он будет сравнивать имя файла из удаленных веток с именем " branch1 " против " branch2 "

git diff ..branch2 [filename]

в этом случае он также сравнивает имя файла из удаленных веток с именем " branch1 " и " branch2 ". Итак, так же, как и выше. Однако, если вы только что создали ветку из другой ветки, скажем «master», а ваша текущая ветка не существует в удаленном хранилище, она будет сравнивать удаленный « master » с удаленным « branch2 ».

Надеюсь, что это полезно.

Дхармендер Рават
источник
0

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

git diff <Branch name>..master -- Filename.extension   

Эта команда покажет разницу между двумя файлами в самом bash.

Rishav_SO
источник