Wie lässt sich git diff
nur der Unterschied zwischen zwei Commits anzeigen, ausgenommen die anderen dazwischen liegenden Commits?
Wie lässt sich git diff
nur der Unterschied zwischen zwei Commits anzeigen, ausgenommen die anderen dazwischen liegenden Commits?
Antworten:
Sie können einfach die 2 Commits an git diff übergeben, wie:
-> git diff 0da94be 59ff30c > my.patch
-> git apply my.patch
my.patch
einer anderen Branche bewerben ?
Nach dem Unterschied / zwischen / zwei Commits zu fragen, ohne die dazwischen liegenden Commits einzubeziehen, macht wenig Sinn. Commits sind nur Momentaufnahmen des Inhalts des Repositorys. Nach dem Unterschied zwischen zwei zu fragen, schließt sie notwendigerweise ein. Die Frage ist also, wonach suchen Sie wirklich?
Wie William vorgeschlagen hat, kann das Kirschernten Ihnen das Delta eines einzelnen Commits geben, das auf einem anderen basiert. Das ist:
$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached
Dies erfordert Commit 'abcdef', vergleicht es mit seinem unmittelbaren Vorfahren und wendet diesen Unterschied dann auf '012345' an. Dieser neue Unterschied wird dann gezeigt - die einzige Änderung ist, dass der Kontext eher von '012345' als von 'abcdefs unmittelbarem Vorfahren' stammt. Natürlich kann es zu Konflikten usw. kommen, daher ist dies in den meisten Fällen kein sehr nützlicher Prozess.
Wenn Sie nur an abcdef selbst interessiert sind, können Sie Folgendes tun:
$ git log -u -1 abcdef
Dies vergleicht abcdef mit seinem unmittelbaren Vorfahren allein und ist normalerweise das, was Sie wollen.
Und natürlich
$ git diff 012345..abcdef
gibt Ihnen alle Unterschiede zwischen diesen beiden Commits.
Es würde helfen, eine bessere Vorstellung davon zu bekommen, was Sie erreichen möchten - wie ich bereits erwähnt habe, macht es keinen Sinn, nach dem Unterschied zwischen zwei Commits zu fragen, ohne dass das dazwischen liegt.
origin/featurebranch#HEAD
, local/featurebranch#HEAD
können Sie sicherstellen, dass Sie während der Konfliktlösung nichts durcheinander gebracht haben.
Um zwei Git-Commits 12345 und abcdef als Patches zu vergleichen, kann der Befehl diff als verwendet werden
diff <(git show 123456) <(git show abcdef)
git diff <(git show 123456) <(git show abcdef)
funktioniert nicht; diff <(...) <(...)
tut. (Ich habe es gerade versucht).
git diff 123456 abcdef
.
diff
die Ausgabe von zwei diff
s. Dies beinhaltet das Lesen und Vergleichen von zwei Eingabeströmen. diff
(GNU oder Unix diff
) kann das, während git diff
es nicht geht. Einige mögen sich fragen, warum man das tun möchte. Ich bin gerade dabei, das zu tun und eine Fusion zu bereinigen, die schlecht gelaufen ist.
So überprüfen Sie vollständige Änderungen:
git diff <commit_Id_1> <commit_Id_2>
Zum Überprüfen nur der geänderten / hinzugefügten / gelöschten Dateien:
git diff <commit_Id_1> <commit_Id_2> --name-only
ANMERKUNG : Um diff ohne Commit dazwischen zu überprüfen, müssen Sie die Commit-IDs nicht eingeben.
Nehmen wir an, Sie haben das
A
|
B A0
| |
C D
\ /
|
...
Und Sie möchten sicherstellen, dass dies A
dasselbe ist wie A0
.
Dies wird den Trick machen:
$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff
Angenommen, Sie möchten den Unterschied zwischen den Commits 012345 und abcdef sehen. Folgendes sollte tun, was Sie wollen:
$ git checkout 012345 $ git cherry-pick -n abcdef $ git diff --cached
Was ist damit:
git diff abcdef 123456 | less
Es ist praktisch, es auf weniger zu pfeifen, wenn Sie viele verschiedene Unterschiede im laufenden Betrieb vergleichen möchten.
Seit Git 2.19 können Sie einfach verwenden:
git range-diff rev1...rev2
- Vergleichen Sie zwei Commit-Bäume, beginnend mit ihrem gemeinsamen Vorfahren
oder
git range-diff rev1~..rev1 rev2~..rev2
- Vergleich von Änderungen, die durch 2 gegebene Commits eingeführt wurden
Meine alias
Einstellungen in der ~/.bashrc
Datei für 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
Ich habe ein Skript geschrieben, das Unterschiede zwischen zwei Commits anzeigt und unter Ubuntu gut funktioniert.
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)