Pokaż różnicę między zatwierdzeniami


236

Korzystam z Git na Ubuntu 10.04 (Lucid Lynx).

Poczyniłem pewne zobowiązania wobec mojego mistrza.

Chcę jednak uzyskać różnicę między tymi zatwierdzeniami. Wszystkie są w mojej głównej gałęzi.

Na przykład:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

Chcę uzyskać różnicę między k73ud a dj374. Jednak gdy wykonałem następujące czynności, nie widziałem zmian, które wprowadziłem k73ud.

git diff k73ud..dj374 > master.patch

Odpowiedzi:


275

Próbować

git diff k73ud^..dj374

aby upewnić się, że uwzględniono wszystkie zmiany k73udw wynikowym pliku różnic.

git diffporównuje dwa punkty końcowe ( zamiast zakresu zatwierdzania ). Ponieważ PO chce zobaczyć zmiany wprowadzone przez k73ud, musi on / ona różnicować między pierwszym zatwierdzeniem przez rodzica k73ud:k73ud^ ( k73ud^1lubk73ud~ ).

W ten sposób diffwyniki będą zawierać zmiany od czasu k73ud nadrzędnego (co oznacza zmiany od k73udsamego siebie), zamiast zmian wprowadzonych od k73ud (do dj374).

Możesz także spróbować:

git diff oldCommit..newCommit
git diff k73ud..dj374 

i (1 spacja, nie więcej):

git diff oldCommit newCommit
git diff k73ud dj374

A jeśli potrzebujesz uzyskać tylko nazwy plików (np. Aby ręcznie skopiować poprawkę):

git diff k73ud dj374 --name-only

I możesz zastosować zmiany do innej gałęzi:

git diff k73ud dj374 > my.patch
git apply my.patch

5
Jesteś pewny? git diff 275e8922ab4e995f47a753b88b75c3027444a54c..a8d9d944c32e945cbb9f60b3f724ecc580da86ae działa, ale git diff 275e8922ab4e995f47a753b88b75c3027444a54c ^ .. a8d9d944c32e945cbb9f60b3f724ecc580da86ae wiadomość get error - "nieznany rewizja lub ścieżka w drzewie pracy"
Demas

@demas: działa na moim komputerze;) możesz również użyć, git diff 275e8^ a8d9d9ponieważ jest taki sam jak wtedy ' ..'.
VonC

4
@VonC W mojej maszynie nie ma potrzeby używania ^
xi.lin

5
@VonC Ubuntu 14.04. Tylko git diff k73ud..dj374jest OK
xi.lin

1
@BradyDowling Zgoda. A jeśli chcesz zobaczyć różnicę PR, możesz to zrobić w wierszu poleceń za pomocą nowego ghinterfejsu CLI: stackoverflow.com/a/62031065/6309
VonC

126

Aby zobaczyć różnicę między:

Twoja kopia robocza i miejsce postoju:

% git diff

Strefa przejściowa i najnowsze zatwierdzenie:

% git diff --staged

Twoja kopia robocza i zatwierdzenie 4ac0a6733:

% git diff 4ac0a6733

Zatwierdź 4ac0a6733 i najnowsze zatwierdzenie:

% git diff 4ac0a6733 HEAD

Zatwierdź 4ac0a6733 i zatwierdź 826793951

% git diff 4ac0a6733 826793951

Więcej informacji znajduje się w oficjalnej dokumentacji .


7
także, jeśli naprawdę chcesz zobaczyć różnice w jednym pliku w tych zatwierdzeniach, git diff {x} {y} -- filenamegdzie {x}i czy {y}podano jeden z tych przykładów. Zobacz także, git log -pponieważ niektóre nakładają się.
Michael

54

Jeśli chcesz zobaczyć zmiany wprowadzone przy każdym zatwierdzeniu, spróbuj „git log -p”


13
  1. gitk --all
  2. Wybierz pierwszy zatwierdzenie
  3. Kliknij drugi prawym przyciskiem myszy , a następnie wybierz różnicę → to

Zaczynam trochę mniej ufać gitk, ponieważ pokazuje innego Autora komisarza niż faktycznego.
Ciasto piekarz

10

Używam gitkzobaczyć różnicę:

gitk k73ud..dj374

Ma tryb GUI, dzięki czemu przeglądanie jest łatwiejsze.


7

Aby zobaczyć różnicę między dwoma różnymi zatwierdzeniami (nazwijmy je ai b), użyj

git diff a..b
  • Zauważ, że różnica między ai bjest przeciwna do bi a.

Aby zobaczyć różnicę między ostatnim zatwierdzeniem a niezatwierdzonymi zmianami, użyj

git diff

Jeśli chcesz później wrócić do różnicy, możesz zapisać ją w pliku.

git diff a..b > ../project.diff

5

Najprostszy do sprawdzenia zmian w ostatnich 2 zatwierdzeniach po ściągnięciu:

git diff HEAD~2 

3

Napisałem skrypt, który wyświetla różnice między dwoma zatwierdzeniami, działa dobrze na Ubuntu.

https://gist.github.com/jacobabrahamb4/a60624d6274ece7a0bd2d141b53407bc

#!/usr/bin/env python
import sys, subprocess, os

TOOLS = ['bcompare', 'meld']

def execute(command):
    return subprocess.check_output(command)

def getTool():
    for tool in TOOLS:
        try:
            out = execute(['which', tool]).strip()
            if tool in out:
                return tool
        except subprocess.CalledProcessError:
            pass
    return None

def printUsageAndExit():
    print 'Usage: python bdiff.py <project> <commit_one> <commit_two>'
    print 'Example: python bdiff.py <project> 0 1'
    print 'Example: python bdiff.py <project> fhejk7fe d78ewg9we'
    print 'Example: python bdiff.py <project> 0 d78ewg9we'
    sys.exit(0)

def getCommitIds(name, first, second):
    commit1 = None
    commit2 = None
    try:
        first_index = int(first) - 1
        second_index = int(second) - 1
        if int(first) < 0 or int(second) < 0:
            print "Cannot handle negative values: "
            sys.exit(0)
        logs = execute(['git', '-C', name, 'log', '--oneline', '--reverse']).splitlines()
        if first_index >= 0:
            commit1 = logs[first_index].split(' ')[0]
        if second_index >= 0:
            commit2 = logs[second_index].split(' ')[0]
    except ValueError:
        if first is not '0':
            commit1 = first
        if second is not '0':
            commit2 = second
    return commit1, commit2

def validateCommitIds(name, commit1, commit2):
    if not commit1 and not commit2:
        print "Nothing to do, exit!"
        return False
    try:
        if commit1:
            execute(['git', '-C', name, 'cat-file', '-t', commit1])
        if commit2:
            execute(['git', '-C', name, 'cat-file', '-t', commit2])
    except subprocess.CalledProcessError:
        return False
    return True

def cleanup(commit1, commit2):
        execute(['rm', '-rf', '/tmp/'+(commit1 if commit1 else '0'), '/tmp/'+(commit2 if commit2 else '0')])

def checkoutCommit(name, commit):
    if commit:
        execute(['git', 'clone', name, '/tmp/'+commit])
        execute(['git', '-C', '/tmp/'+commit, 'checkout', commit])
    else:
        execute(['mkdir', '/tmp/0'])

def compare(tool, commit1, commit2):
        execute([tool, '/tmp/'+(commit1 if commit1 else '0'), '/tmp/'+(commit2 if commit2 else '0')])

if __name__=='__main__':
    tool = getTool()
    if not tool:
        print "No GUI diff tools, install bcompare or meld"
        sys.exit(0)
    if len(sys.argv) is not 4:
        printUsageAndExit()

    name, first, second = None, 0, 0
    try:
        name, first, second = sys.argv[1], sys.argv[2], sys.argv[3]
    except IndexError:
        printUsageAndExit()

    commit1, commit2 = getCommitIds(name, first, second)

    if validateCommitIds(name, commit1, commit2) is False:
        sys.exit(0)

    cleanup(commit1, commit2)

    try:
        checkoutCommit(name, commit1)
        checkoutCommit(name, commit2)
        compare(tool, commit1, commit2)
    except KeyboardInterrupt:
        pass
    finally:
        cleanup(commit1, commit2)
    sys.exit(0)

1
Ciekawy scenariusz. +1
VonC,

2

Zaakceptowana odpowiedź jest dobra.

Wystarczy umieścić go tutaj ponownie, aby łatwo było go zrozumieć i wypróbować w przyszłości

git diff c1...c2 > mypatch_1.patch  
git diff c1..c2  > mypatch_2.patch  
git diff c1^..c2 > mypatch_3.patch  

Mam te same różnice dla wszystkich powyższych poleceń.

Powyżej pomaga
1. zobaczyć różnicę między zatwierdzeniem c1 a innym zatwierdzeniem c2
2. zrobieniem pliku łatki, który pokazuje diff i może być użyty do zastosowania zmian w innej gałęzi

Jeśli nie pokazuje poprawnie różnicy,
wówczas c1 i c2 mogą być źle wzięte
więc dostosuj je do zatwierdzenia przed, jak c1 do c0, lub do jednego po, jak c2 do c3

Posługiwać się gitk aby zobaczyć zatwierdzenia SHA, wystarczy 8 pierwszych znaków, aby użyć ich jako c0, c1, c2 lub c3. Możesz także zobaczyć identyfikatory zatwierdzeń z Gitlab> Repozytorium> Zatwierdzenia itp.

Mam nadzieję, że to pomaga.


0

Powiedzmy, że masz jeszcze jedno zatwierdzenie na dole (najstarsze), a wtedy staje się to dość łatwe:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

commit oldestCommit
made changes

Teraz użycie poniższej opcji z łatwością pozwoli serwerowi cel.

git diff k73ud oldestCommit

-2

Użyj tego polecenia, aby uzyskać różnicę między zatwierdzaniem a nieetapowaniem:

git difftool --dir-diff
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.