Jak różnicować zatwierdzenie z rodzicem?

460

Czy oprócz pisania aliasu lub skryptu istnieje krótsze polecenie pobierania różnic dla konkretnego zatwierdzenia?

git diff 15dc8^..15dc8

Jeśli podasz tylko jeden identyfikator zatwierdzenia git diff 15dc8, różni się on od zatwierdzenia względem HEAD.

Brian L.
źródło
Najfajniejszą rzeczą w tym byłoby to, że działałoby to z „git difftool”, używając narzędzi do pokazania diff.
orip
Dla porównania, odpowiedź na to drugie pytanie ilustruje, w jaki sposób można skonfigurować alias oparty na bash, aby uprościć powyższe: stackoverflow.com/questions/3321492/...
Nick

Odpowiedzi:

641

Zastosowanie git show $COMMIT. Pokaże ci komunikat dziennika dla zatwierdzenia i różnicę dla tego konkretnego zatwierdzenia.

mipadi
źródło
45
Szkoda, że ​​nie można użyć difftool :(
orip
1
@orip zawsze możesz ustawić GIT_EXTERNAL_DIFF na skrypt, który robi to samo co twój difftool.
slacy
7
Wolę odpowiedź Jakuba Narebskiego, ponieważ podane tam wyrażenie zatwierdzenia będzie działać w wielu kontekstach: stackoverflow.com/a/449128/992887
RichVel
1
Jeśli nie pokazany jest diff, prawdopodobnie istnieją żadne rzeczywiste zmiany, jak na scaleniu popełnić
Devin G Rhode
6
@PTWithy: Pytanie brzmiało: „Czy istnieje krótsze polecenie uzyskania różnic dla określonego zatwierdzenia?”, Na które to pytanie odpowiada.
mipadi
439

Posługiwać się:

git diff 15dc8^!

jak opisano w poniższym fragmencie strony man git-rev-parse (1) (lub we współczesnej stronie gitrevisions (7) man ):

Istnieją dwa inne skróty do nazwania zestawu utworzonego przez zatwierdzenie i jego zatwierdzenia nadrzędne. Notacja r1 ^ @ oznacza wszystkich rodziców r1. r1 ^! obejmuje zatwierdzenie r1, ale wyklucza wszystkich jego rodziców.

Oznacza to, że możesz używać go 15dc8^!jako stenografii w 15dc8^..15dc8dowolnym miejscu w git, gdzie potrzebne są poprawki. Dla polecenia diffgit diff 15dc8^..15dc8 rozumiane jest jako git diff 15dc8^ 15dc8, co oznacza różnicę między rodzicem funkcji commit ( 15dc8^) i commit ( 15dc8).

Uwaga : opis na stronie git-rev-parse(1)podręcznika mówi o zakresach wersji , w których musi działać również w przypadku zatwierdzeń łączenia, z więcej niż jednym rodzicem. Następnie r1^!jest „ r1 --not r1^@” tj. „ r1 ^r1^1 ^r1^2 ...


Możesz także użyć, git show COMMITaby uzyskać opis zatwierdzenia i różnicę dla zatwierdzenia. Jeśli chcesz tylko różnicę, możesz użyćgit diff-tree -p COMMIT

Jakub Narębski
źródło
7
To powinna być zaakceptowana odpowiedź, jest o wiele ładniejsza. Jednak ostatnie zdanie wyciągu z git-rev-parse jest dość mylące - wydaje się, że oznacza „zakres od rodzica tego zatwierdzenia do tego zatwierdzenia”.
RichVel
1
@RichVel: jest to nieco mylące, ponieważ próbuje opisać również sytuację, w której zatwierdzenie ma więcej niż jednego rodzica (jest zatwierdzeniem scalania). r1 ^! działa wtedy również zgodnie z oczekiwaniami.
Jakub Narębski
@ JakubNarębski: dobrze, być może mógłbyś zredagować swoją odpowiedź, aby podsumować swoje rozumienie spraw dotyczących jednego i wielu rodziców - oddzielne stwierdzenia na każdym z nich mogą być łatwiejsze do zrozumienia.
RichVel,
1
@ JakubNarębski: tak, znacznie lepiej! Teraz używam tego skrótu cały czas - dzięki.
RichVel
1
^!Notacja rodzic skrótowym działa poprawnie z difftool dla normalnych zobowiązuje ale diff jest odwrócony do zatwierdzeń seryjnej. Dlaczego tak?
hIpPy
56

Jeśli wiesz, jak daleko wstecz, możesz spróbować czegoś takiego:

# Current branch vs. parent
git diff HEAD^ HEAD

# Current branch, diff between commits 2 and 3 times back
git diff HEAD~3 HEAD~2

Wcześniejsze zatwierdzenia działają mniej więcej tak:

# Parent of HEAD
git show HEAD^1

# Grandparent
git show HEAD^2

Istnieje wiele sposobów określania zatwierdzeń:

# Great grandparent
git show HEAD~3

Zobacz tę stronę, aby uzyskać szczegółowe informacje .

Paul Vincent Craven
źródło
2
HEAD ^ 2 nie jest dziadkiem, jeśli HEAD ^ 1 jest tatusiem, HEAD ^ 2 to mama. Użyj HEAD ~ 2 dla tatusia tatusia.
Binarian
11

Jak wskazuje @mipadi, możesz użyć git show $COMMIT, ale pokazuje to także niektóre nagłówki i komunikat zatwierdzenia. Jeśli chcesz mieć prosty diff, użyj git show --pretty=format:%b $COMMIT.

To oczywiście nie jest krótka ręka, więc zachowuję ten alias w moim .gitconfig

    [alias]
      sd = show --pretty=format:%b

To pozwala mi używać git sd $COMMITdo pokazywania różnic .

Øystein Steimler
źródło
1
Ten alias może zawierać --color, który ułatwia czytanie: sd = pokaż --color --pretty = format:% b
RichVel
@RichVel Rzeczywiście! Bardzo dobra uwaga. Jeśli masz włączone domyślnie kolory w git, ten przełącznik nie będzie ci potrzebny. Tak zwykle robię.
Øystein Steimler
5

Wiele z wymienionych przykładów (np. git diff 15dc8^!Lub git diff 15dc8^..15dc8) nie działa, jeśli używasz zsh i masz extendedglobustawione opcje. Możesz to naprawić na jeden z następujących trzech sposobów:

  1. unsetopt extendedglob (i / lub usuń go z .zshrc)

  2. setopt NO_NOMATCH (i / lub ustaw w .zshrc)

  3. uciekaj z karetki i uderzaj za każdym razem odwrotnym ukośnikiem, np git diff 15dc8\^\!

Ville
źródło
3
git diff 15dc8 15dce~1

~ 1 oznacza „rodzic”, ~ 2 „dziadek itp.

John Lawrence Aspden
źródło
2

Powyższe rozwiązanie Paula zrobiło to, na co liczyłem.

$ git diff HEAD^1

Przydatne jest również dodawanie aliasów, takich jak wspomniane płyty grzewcze, jeśli umieścisz poniższe w sekcji [alias] pliku ~ / .gitconfig, możesz użyć skrótu, aby wyświetlić różnice między głową a poprzednią.

[alias]
    diff-last = diff HEAD^1

Następnie uruchomienie $ git diff-last da ci wynik. Pamiętaj, że obejmie to także wszelkie zmiany, których jeszcze nie zatwierdziłeś, a także różnicę między zatwierdzeniami. Jeśli chcesz zignorować zmiany, których jeszcze nie zatwierdziłeś, możesz użyć diff, aby bezpośrednio porównać HEAD z jego rodzicem:

$ git diff HEAD^1 HEAD
Graham R. Armstrong
źródło
0

Używa aliasów, więc nie odpowiada dokładnie na twoje pytanie, ale uważam, że są przydatne do robienia tego, co zamierzasz ...

alias gitdiff-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"

alias gitlog-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
płyty grzewcze
źródło