Як я відрізняю один і той же файл між двома різними комітами в одній гілці?


1143

Як я можу порівняти один і той же файл між двома різними комітами (не суміжними) в одній гілці (наприклад, master) у Git?

Я шукаю функцію порівняння, як та у Visual SourceSafe (VSS) або Team Foundation Server (TFS).
Чи можливо це в Git?

Відповіді:


1475

На сторінці сторінки git-diff:

git diff [--options] <commit> <commit> [--] [<path>...]

Наприклад, щоб побачити різницю файлу "main.c" між тепер і двома поверненнями назад, ось три еквівалентні команди:

$ git diff HEAD^^ HEAD main.c
$ git diff HEAD^^..HEAD -- main.c
$ git diff HEAD~2 HEAD -- main.c

43
..Чи не є необхідним, хоча він буде працювати з ним ( за винятком досить старих версій, може бути). Ви також можете використовувати git logабо gitkзнаходити SHA1, які слід використовувати, якщо два комітети будуть дуже далеко один від одного. gitkу своєму контекстному меню також є "diff selected -> this" та "diff this -> selected".
Каскабель

17
Чи спрацює це, навіть якщо ім'я файлу було змінено між двома комітами?
reubenjohn

26
Отже, яка мета "-"
користувача64141

29
@ user64141 Це --корисно, наприклад, коли у вас є ім'я файлу -p. Добре використовувати в сценаріях, тільки в рідкісних випадках, необхідних на практиці.
Палець

13
Примітка: вам потрібно використовувати шляхи відносно кореня репо. Шляхи відносно поточного робочого каталогу не працюватимуть.
Кевін Вілер

280

Ви також можете порівняти два різних файли у двох різних редакціях, таких як:

git diff <revision_1>:<file_1> <revision_2>:<file_2>


25
зверніть увагу , що це виглядає , як якщо <file_1>і <file_2>знаходяться в поточному каталозі, а нема на рівень верхнього мерзотник керованого каталогу, один повинен препенд ./на Unix:<revision_1>:./filename_1
Андре Holzner

7
<revision>: можна пропустити, тож ви можете відрізнятись від файлу, який ще не був зроблений.
Ярослав Нікітенко

2
Зауважте, що в Windows потрібно використовувати "/" для шляхів до файлів, а не "\".
np8

87

Якщо ви налаштували "difftool", ви можете використовувати його

git difftool revision_1:file_1 revision_2:file_2

Приклад: Порівняння файлу з його останнього присвоєння з попереднім фіксацією на тій самій гілці: припустимо, що якщо ви знаходитесь у кореневій папці вашого проекту

$git difftool HEAD:src/main/java/com.xyz.test/MyApp.java HEAD^:src/main/java/com.xyz.test/MyApp.java

У вашому ~ / .gitconfig або у файлі project / .git / config ви повинні мати такі записи. Встановіть p4merge [Це мій кращий інструмент розрізнення та злиття]

[merge]
    tool = p4merge
    keepBackup = false
[diff]
    tool = p4merge
    keepBackup = false
[difftool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
[mergetool]
    keepBackup = false
[difftool]
    keepBackup = false
[mergetool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
    cmd = p4merge.exe \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"

50

Перевірте $ git log, скопіюйте ідентифікатор SHA-1 двох різних комітетів і запустіть git diffкоманду з цими ідентифікаторами. наприклад:

$ git diff (sha-id-one) (sha-id-two)

18
Якщо ви хочете, щоб diff для певного файлу, додайте шлях до нього в кінці команди.
hBrent

Також виконайте "git pull", щоб завантажити повну інформацію про дерево, якщо два коміти перебувають через різні гілки. Інакше ви отримаєте помилку "фатальний: поганий предмет".
user238607

4
git diff (sha-id-one) (sha-id-two) -- filename.ext без імені файлу він відображатиме різницю всіх файлів у цих двох комітах.
SherylHohman

40

Якщо ви хочете побачити всі зміни у файлі між двома комісіями на принципі "виконувати", ви також можете зробити це

git log -u $start_commit..$end_commit -- path/to/file


Що таке "$ start_commit" і "$ end_commit"? Вони буквальні, чи ні, чи можете ви навести приклад?
Пітер Мортенсен

Це змінні оболонки, які містять перегляд початку та кінця, які замість цього можуть бути sha1 літералами чи refs
cxreg

21

Ось сценарій Perl, який виводить команди Git diff для даного файлу, як це знайдено в команді журналу Git.

Напр

git log pom.xml | perl gldiff.pl 3 pom.xml

Врожайність:

git diff 5cc287:pom.xml e8e420:pom.xml
git diff 3aa914:pom.xml 7476e1:pom.xml
git diff 422bfd:pom.xml f92ad8:pom.xml

який потім можна вирізати та вставити у вікно сеансу оболонки або прокласти в нього /bin/sh.

Примітки:

  1. число (у цьому випадку 3) вказує, скільки рядків для друку
  2. файл (pom.xml в цьому випадку) повинен узгоджуватися в обох місцях (ви можете його обернути у функції оболонки, щоб забезпечити один і той же файл в обох місцях) або помістити його у двійковий каталог як скрипт оболонки

Код:

# gldiff.pl
use strict;

my $max  = shift;
my $file = shift;

die "not a number" unless $max =~ m/\d+/;
die "not a file"   unless -f $file;

my $count;
my @lines;

while (<>) {
    chomp;
    next unless s/^commit\s+(.*)//;
    my $commit = $1;
    push @lines, sprintf "%s:%s", substr($commit,0,6),$file;
    if (@lines == 2) {
        printf "git diff %s %s\n", @lines;
        @lines = ();
    }
    last if ++$count >= $max *2;
}

14

Якщо ви хочете зробити різницю з більш ніж одним файлом, за допомогою методу, визначеного @mipadi:

Наприклад відмінностей між HEADі ваш master, щоб знайти всі .coffeeфайли:

git diff master..HEAD -- `find your_search_folder/ -name '*.coffee'`

Це дозволить рекурсивно шукати your_search_folder/всі .coffeeфайли та робити різницю між ними та їх masterверсіями.


13

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

Зробити тимчасову гілку ( "перегляд" у цьому прикладі)

git checkout -b revision

Перемотайтеся на першу ціль фіксації

git reset --hard <commit_target>

Вишня вибирає на тих, хто цікавиться

git cherry-pick <commit_interested> ...

Застосувати розл

git diff <commit-target>^

Коли ви зробили

git branch -D revision

2
Дякую за це рішення. Це добре працювало для мого використання. Єдине, що я хотів би оновити, це те, що коли ви закінчите, ви не можете видалити гілку, поки не вимкнете її.
Стівен Дікс

9

Ще один спосіб використовувати дивовижність Гіта ...

git difftool HEAD HEAD@{N} /PATH/FILE.ext

Я визначив псевдонім з цієї відповіді, який працює з bash:difftool-file = "!git difftool HEAD@{\"$2\"} HEAD \"$1\" #"
blueogive

2

Якщо ви хочете просте візуальне порівняння в Windows, наприклад, ви можете отримати в Visual SourceSafe або Team Foundation Server (TFS), спробуйте це:

  • клацніть правою кнопкою миші на файлі в Провіднику файлів
  • виберіть "Історія Git"

Примітка. Після оновлення до Windows 10 я втратив параметри контекстного меню Git. Однак ви можете досягти того ж, використовуючи 'gitk' або 'gitk filename' у вікні команд.

Після виклику "Історії Git" запуститься інструмент Git GUI з історією файлу у верхній лівій області. Виберіть одну з версій, яку ви хочете порівняти. Потім клацніть правою кнопкою миші другу версію і виберіть будь-яку

Відмінніть це -> вибрано

або

Виділено різницю -> це

На нижній лівій панелі відображаються кольорові відмінності.


Зверніть увагу на поточні фактори: це просте рішення, яке легко здійснити і вирішує проблему ОП. Він працює у Windows, який ОП чітко використовує (див. Посилання на TFS та VSS у запитанні).
Ресурс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.