2016-06-05 5 views
0

Wenn zwei Revisionen Difference, wie kann ich git richtig folgen einem Verlauf, wo eine Datei ersetzt wurde?How to git richtig diff eine ersetzte Datei

Hier ist ein Beispiel. Ich erstelle eine Datei [commit], verschiebe sie [commit] und erstelle dann eine andere Datei mit dem gleichen Namen [commit].

echo "original" > test.txt 
git add . 
git commit -m "First commit" 
mv test.txt test2.txt 
git add --all . 
git commit -m "Rename" 
echo "replace" > test.txt 
git add . 
git commit -m "Replace" 

Wenn zwischen HEAD^^ und HEAD diffing, wie kann ich git erkennen, dass test.txt wirklich eine Datei brandneu? Der beste Befehl, den ich finden konnte, war etwas wie git diff -M100% -C100% HEAD^^, aber das liefert nicht die Ergebnisse, nach denen ich suche.

git diff -M100% -C100% HEAD^^ 
diff --git a/test.txt b/test.txt 
index 4b48dee..6e8b374 100644 
--- a/test.txt 
+++ b/test.txt 
@@ -1 +1 @@ 
-original 
+replace 
diff --git a/test.txt b/test2.txt 
similarity index 100% 
copy from test.txt 
copy to test2.txt 

Gibt es einen besseren Befehl, um diese erwartete Ausgabe zu bekommen?

diff --git a/test.txt b/test.txt 
index 4b48dee..6e8b374 100644 
--- /dev/null 
+++ b/test.txt 
@@ -0,0 +1 @@ 
+replace 
diff --git a/test.txt b/test2.txt 
similarity index 100% 
copy from test.txt 
copy to test2.txt 

Antwort

1

Leider gibt es nicht. Git übernimmt immer die heuristische Umbenennungserkennung und, zumindest momentan, unabhängig von einem aus der Commit-DAG berechenbaren Ancesspfad, wenn Sie git diff zwei Commits geben, vergleicht es sie einfach direkt. In diesem Fall vergleicht es HEAD^^ vs HEAD und beide haben eine test.txt und die zweite hat eine test2.txt, so dass seine Heuristiken sagen, dass test2.txt kann oder nicht eine Kopie einer anderen Datei sein, test.txt wird nicht umbenannt.

(Wenn HEAD^^ vs HEAD^ Vergleich, gibt es keine test.txt in HEAD^, so dass ihr Umbenennungserkennungscode wird sehen, ob vielleicht test2.txt die vorherigen test.txt übereinstimmt. Daher, wenn es durch die Abstammung Weg von HEAD^^ durch HEAD^-HEAD führenden gescannt, sein Aktuelle Heuristiken würde erkennen die Umbenennung.Aber es tut das nicht.Oder, wenn Git hatte die Option, eine rechenintensive O (n) Vergleich zwischen allen Dateien, anstatt nur diejenigen, die keine Gegenstücke haben auf jeder "Seite" des Diff, das könnte auch das Umbenennen entdecken, aber auch nicht.)

+0

Vielen Dank für die direkte und durch die Antwort! Ich frage mich, ob jemand ein Skript erstellt hat, um entweder die Geschichte zu begehen oder einen teuren Vergleich zu machen. – m35

+1

Michael Haggerty schrieb 'git-imerge' als ein Skript, das iterative Merge oder Rebase ausführen kann, die den History-Lauf bei diesen Operationen behandelt. Es hat jedoch eigene Probleme. Siehe http://softwareswirl.blogspot.com/2013/05/git-imerge-practical-introduction.html – torek