2012-10-08 10 views
12

Fragen zum Umbenennen von Dateien in Git havebeenasked vor, aber ich kann nicht eine Lösung für mein spezifisches Problem erarbeiten.Get Git umbenannt und bearbeitet Dateien

Ich habe mehrere Dateien verschoben und bearbeitet (ich habe git mv nicht verwendet - leider ist es jetzt zu spät dafür). Jetzt möchte ich es, wenn mein Kollege aus meinem Repository zieht, nachdem er selbst diese Dateien bearbeitet hat (ohne sie zu verschieben), fügt er meine Änderungen erfolgreich in den neuen Speicherort der Datei ein. Um erfolgreich zusammenzuführen, muss Git klar wissen, dass es sich um dieselben Dateien handelt.

Ist Git clever genug, um das selbst auszuarbeiten? Es scheint schwer zu glauben. Und wenn ja, wie kann ich sicher sein, dass eine bestimmte Dateiverschiebung von Git übernommen wird - auch wenn sich der Inhalt geändert hat?

+1

Dies ist der Zweck von 'git mv'. – ezod

+0

Okay, aber wie sage ich git, dass eine Datei * verschoben * wurde? Ich habe die Dateien in Visual Studio verschoben, jetzt möchte ich sicherstellen, dass Git weiß. Ich habe 'git mv --cached' versucht, aber das existiert nicht. Wenn ich 'git mv' versuche, bekomme ich' fatal: bad source, source = ... ' –

+0

Wenn du noch nicht committed hast, kannst du die Dateien einfach in ihre ursprünglichen Pfade zurückversetzen und dann' git mv' an sie die neuen Wege. – ezod

Antwort

16

Git verfolgt die Umbenennungen im Repository nicht wirklich, sondern verwendet eine Diff-Heuristik, um festzustellen, ob Sie eine Datei in eine andere umbenannt haben. Das heißt, wenn Sie eine Datei git mv und dann den Inhalt vollständig ersetzen, ist es nicht als eine Umbenennung angesehen, und Sie tun nicht müssen git mv für die Erkennung von Umbenennungen verwenden.

Zum Beispiel:

% mv d.txt e.txt 
% git rm d.txt 
rm 'd.txt' 
% git add e.txt 
% git commit -m"rename without git mv" 
[master f70ae76] rename without git mv 
1 file changed, 0 insertions(+), 0 deletions(-) 
rename d.txt => e.txt (100%) 
% git diff --summary --find-renames HEAD~1 HEAD 
rename d.txt => e.txt (100%) 

ähnlich git mv bedeutet nicht, dass die Datei umbenannt wird, wird es noch den Diff-Algorithmus verwenden:

% git mv e.txt f.txt 
% echo "Completely replacing f.txt" > f.txt 
% git add f.txt 
% git commit -m"git mv doesn't help here" 
[master 068d19c] git mv doesn't help here 
2 files changed, 1 insertion(+), 14 deletions(-) 
delete mode 100644 e.txt 
create mode 100644 f.txt 
% git diff --summary --find-renames HEAD~1 HEAD 
delete mode 100644 e.txt 
create mode 100644 f.txt 
7

Standardmäßig überprüft git jedes Mal, wenn eine Datei zwischen den Commits entfernt wurde, auf Umbenennungen - es muss nicht manuell angegeben werden. Wenn Sie eine Datei tatsächlich verschieben (mit git mv, anstatt sie manuell zu entfernen und erneut hinzuzufügen), ignoriert sie den Hinweis. Aus Performance-Gründen laufen die Heuristiken nicht ständig - wenn Sie eine Datei aus dem Weg schieben und dann eine neue mit dem ursprünglichen Namen hinzufügen, wird die Bewegung möglicherweise nicht erkannt.

Beachten Sie, dass git nur den Baum so speichert, wie er in jeder Revision vorhanden war: Er speichert keine Tracking-Informationen über Änderungen, die zwischen Revisionen vorgenommen wurden.

Wenn Sie sehen möchten, was erkannt wurde, können Sie den Umschalter -M (--find-renames) auf git diff umbenennen. Dieser Schalter schaltet auch die Heuristik ein, was nützlich ist, wenn Sie einen Commit haben, der sie nicht auslöst.

Dieser Heuristik-basierte Ansatz ist ein guter Grund (wenn Sie einen anderen benötigen), um Commits klein und in sich abgeschlossen zu halten, da dies die Arbeit von git erleichtert.

1

git diff nicht, dass ich auf auswählte 'd umbenannte Dateien und änderten ihren Inhalt. Mein Szenario war, dass ich die Dateien A, B, C hatte und ein neues B einfügte, also war das alte B jetzt C und das alte C war jetzt D. git diff sagte mir, dass B und C jetzt völlig anders wären!

Die Lösung, die ich verwendete, war mühsam und manuell, aber hat die Arbeit erledigt.

  1. Die Dateien umbenannt, so gut ich konnte. I.e. B bis Bneu, C bis B, D bis C.
  2. Hat das diff, um keine Fehler zu überprüfen.
  3. Committed das.
  4. Verwendet git mv, um die Dateien zurück zu ihren neuen Namen zu benennen. B zu C, C zu D.
  5. Engagiert das.
  6. Hat der andere umbenannt und als neue Dateien übernommen. I.e. Bnew to B.
Verwandte Themen