Jak sprawić, aby git diff
pokazywała tylko różnicę między dwoma zatwierdzeniami, wyłączając pozostałe zatwierdzenia pomiędzy nimi?
Jak sprawić, aby git diff
pokazywała tylko różnicę między dwoma zatwierdzeniami, wyłączając pozostałe zatwierdzenia pomiędzy nimi?
Odpowiedzi:
możesz po prostu przekazać 2 zatwierdzenia do git diff, takie jak:
-> git diff 0da94be 59ff30c > my.patch
-> git apply my.patch
my.patch
w innym oddziale?
Pytanie o różnicę / między / dwoma zatwierdzeniami bez uwzględnienia między nimi nie ma sensu. Zatwierdzenia to tylko migawki zawartości repozytorium; pytanie o różnicę między dwoma koniecznie obejmuje je. Pytanie zatem brzmi: czego tak naprawdę szukasz?
Jak sugerował William, wybieranie wiśni może dać ci deltę jednego zatwierdzenia opartego na drugim. To jest:
$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached
Pobiera zatwierdzenie „abcdef”, porównuje go do jego bezpośredniego przodka, a następnie stosuje tę różnicę do „012345”. Ta nowa różnica jest następnie pokazana - jedyną zmianą jest kontekst pochodzi od „012345”, a nie od bezpośredniego przodka abcdef. Oczywiście możesz mieć konflikty itp., Więc w większości przypadków nie jest to bardzo przydatny proces.
Jeśli jesteś zainteresowany samym abcdef, możesz:
$ git log -u -1 abcdef
To porównuje abcdef do jego bezpośredniego przodka, samego i jest zwykle tym, czego chcesz.
I oczywiście
$ git diff 012345..abcdef
daje wszystkie różnice między tymi dwoma zatwierdzeniami.
Pomogłoby to uzyskać lepszy obraz tego, co próbujesz osiągnąć - jak już wspomniałem, proszenie o różnicę między dwoma zatwierdzeniami bez tego, co pomiędzy, nie ma sensu.
origin/featurebranch#HEAD
z local/featurebranch#HEAD
może pomóc ci upewnić się, że nic nie zepsułeś podczas rozwiązywania konfliktu.
Aby porównać dwa git zatwierdza 12345 i abcdef jako łaty, można użyć polecenia diff jako
diff <(git show 123456) <(git show abcdef)
git diff <(git show 123456) <(git show abcdef)
nie działa; diff <(...) <(...)
robi. (Właśnie tego spróbowałem).
git diff 123456 abcdef
.
diff
otrzymując wynik z dwóch diff
s. Obejmuje to odczytywanie i porównywanie dwóch strumieni wejściowych. diff
(GNU lub Unix diff
) może to zrobić, podczas gdy git diff
nie. Niektórzy mogą się zastanawiać, dlaczego ktoś chciałby to zrobić. Jestem w trakcie robienia tego teraz, usuwając połączenie, które poszło nie tak.
Aby sprawdzić pełne zmiany:
git diff <commit_Id_1> <commit_Id_2>
Aby sprawdzić tylko zmienione / dodane / usunięte pliki:
git diff <commit_Id_1> <commit_Id_2> --name-only
UWAGA : Aby sprawdzić różnicę bez zatwierdzenia pomiędzy, nie musisz umieszczać identyfikatorów zatwierdzenia.
Powiedzmy, że masz to
A
|
B A0
| |
C D
\ /
|
...
I chcesz się upewnić, że A
to samo A0
.
To załatwi sprawę:
$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff
Załóżmy, że chcesz zobaczyć różnicę między zatwierdzeniami 012345 a abcdef. Następujące czynności powinny robić, co chcesz:
$ git Checkout 012345 $ git cherry-pick -n abcdef $ git diff --cached
A co z tym:
git diff abcdef 123456 | less
Przydatne jest po prostu zmniejszanie go, jeśli chcesz porównywać wiele różnych różnic w locie.
Od wersji Git 2.19 możesz po prostu używać:
git range-diff rev1...rev2
- porównaj dwa drzewa zatwierdzeń, zaczynając od ich wspólnego przodka
lub
git range-diff rev1~..rev1 rev2~..rev2
- porównaj zmiany wprowadzone przez 2 dane zmiany
Moje alias
ustawienia w ~/.bashrc
pliku dla git diff
:
alias gdca='git diff --cached' # diff between your staged file and the last commit
alias gdcc='git diff HEAD{,^}' # diff between your latest two commits
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 getTool():
for tool in TOOLS:
try:
out = subprocess.check_output(['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 = subprocess.check_output(['git', '-C', name, 'log', '--oneline', '--reverse']).split('\n')
if first_index >= 0:
commit1 = logs[first_index].split(' ')[0]
if second_index >= 0:
commit2 = logs[second_index].split(' ')[0]
except ValueError:
if first != '0':
commit1 = first
if second != '0':
commit2 = second
return commit1, commit2
def validateCommitIds(name, commit1, commit2):
if commit1 == None and commit2 == None:
print "Nothing to do, exit!"
return False
try:
if commit1 != None:
subprocess.check_output(['git', '-C', name, 'cat-file', '-t', commit1]).strip()
if commit2 != None:
subprocess.check_output(['git', '-C', name, 'cat-file', '-t', commit2]).strip()
except subprocess.CalledProcessError:
return False
return True
def cleanup(commit1, commit2):
subprocess.check_output(['rm', '-rf', '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])
def checkoutCommit(name, commit):
if commit != None:
subprocess.check_output(['git', 'clone', name, '/tmp/'+commit])
subprocess.check_output(['git', '-C', '/tmp/'+commit, 'checkout', commit])
else:
subprocess.check_output(['mkdir', '/tmp/0'])
def compare(tool, commit1, commit2):
subprocess.check_output([tool, '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])
if __name__=='__main__':
tool = getTool()
if tool == None:
print "No GUI diff tools"
sys.exit(0)
if len(sys.argv) != 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 not validateCommitIds(name, commit1, commit2):
sys.exit(0)
cleanup(commit1, commit2)
checkoutCommit(name, commit1)
checkoutCommit(name, commit2)
try:
compare(tool, commit1, commit2)
except KeyboardInterrupt:
pass
finally:
cleanup(commit1, commit2)
sys.exit(0)