Wie kann man die git diff
nur den Unterschied zwischen zwei Übertragungen anzeigen, ohne die anderen Übertragungen dazwischen?
Antworten
Zu viele Anzeigen?$git log
commit-1(new/latest/recent commit)
commit-2
commit-3
commit-4
*
*
commit-n(first commit)
$git diff commit-2 commit-1
zeigt alle Änderungen zwischen Commit-2 und Commit-1 an (Patch von Commit-1 allein & äquivalent zu
git diff HEAD~1 HEAD
)
ähnlich $git diff commit-4 commit-1
zeigt alle Änderungen zwischen Commit-4 und Commit-1 an (Patch von Commit-1, commit-2 & commit-3 zusammen. Äquivalent zu
git diff HEAD~3 HEAD
)
$git diff commit-1 commit-2
Durch Ändern der Auftragsbestätigungs-IDs ist es möglich, Folgendes zu erhalten
revert patch
. ("$git diff commit-1 commit-2 > revert_patch_of_commit-1.diff")
Ich habe ein Skript geschrieben, das den Unterschied zwischen zwei Commits anzeigt; es funktioniert gut unter 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)
Lassen Sie mich einen einfachen GUI/idiotensicheren Ansatz vorstellen, den Sie in solchen Situationen wählen können.
- Klonen Sie eine weitere Kopie Ihres Repo in einen neuen Ordner, zum Beispiel
myRepo_temp
- Checken Sie den Commit/Zweig aus, den Sie mit dem Commit in Ihrem ursprünglichen Repo vergleichen möchten (
myRepo_original
). - Nun können Sie mit diesen beiden Ordnern Vergleichswerkzeuge (wie Beyond Compare usw.) verwenden (
myRepo_temp
ymyRepo_original
)
Dies ist zum Beispiel nützlich, wenn Sie einige Änderungen teilweise rückgängig machen wollen, da Sie Dinge von einem in einen anderen Ordner kopieren können.
- See previous answers
- Weitere Antworten anzeigen
19 Stimmen
"git diff" immer zeigt den Unterschied zwischen zwei Commits (oder Commit und Arbeitsverzeichnis usw.).
42 Stimmen
@JakubNarebski, er fragt, wie man den Unterschied zwischen den Änderungen, die durch einen Befehl eingeführt wurden, und den Änderungen, die durch einen anderen Commit eingeführt wurden, erkennen kann. Mit anderen Worten, das Diff von Diffs oder Interdiff.
1 Stimmen
Und wenn Sie den Parameter --dirstat=files zum diff-Befehl hinzufügen, erhalten Sie einen sehr schönen Screenshot der genauen Projekte und Dateien, die geändert wurden, zusammen mit einem Prozentsatz der Änderungen. So geht's: git diff [commit-number] [commit-number] --dirstat=files
1 Stimmen
Diese Frage wäre klarer, wenn Sie ein Beispiel aus der Git-Historie in Form von ASCII-Dateien hinzufügen und genau erklären könnten, welche Commits Sie aus diesem Diagramm ausschließen möchten.
0 Stimmen
Dies mag Ihre Frage direkt beantworten, aber versuchen Sie es mit Meld oder kdiff3 oder einem anderen grafischen Tool
0 Stimmen
@JakubNarebski laut Dokumentation ist die Standardeinstellung "Änderungen zwischen dem Arbeitsbaum und dem Index anzeigen", nicht zwei Übertragungen
0 Stimmen
@simpleuser Ich meinte den Befehl "git diff" im Allgemeinen, nicht speziell
git diff
ohne Parameter; wichtig ist, dass es bei "git diff" immer um zwei Endpunkte geht, und immer überspringt zwischenzeitliche Übertragungen.