2010-08-19 10 views
17

Ich verstehe gut, wie Git Dateibewegungen unterstützen kann: da es Datei-Hash verwendet, wird eine "hinzugefügte" Datei leicht als die "entfernte" Datei erkannt.Wie verfolgt Git den Verlauf während eines Refactorings?

Meine Frage ist über Refactoring: unter Berücksichtigung von Java ändert sich die Paketdeklaration, so dass der Inhalt der Datei nicht identisch sein wird. Wie bestimmt Git in diesem Fall, dass die "hinzugefügte" Datei den Verlauf mit dem "entfernten" teilt? Wird nach "ähnlichstem Inhalt" gesucht, vorausgesetzt, ich habe nur geringfügige Änderungen oder ähnliche nichtdeterministische Lösungen vorgenommen?

+0

Warten Sie eine Minute ... Das "Apache Maven" Buch gerade vor mir hat man den Namen des Autors auf unheimliche Weise vertraut ... – VonC

+0

Recht, bin ich das Typ: D –

+0

Ich wusste es! Ich versuche immer noch, das Bild eines verrückten Freds von "C'est pas sorcier" zu vergessen, der über maven3 Migration bei einem kürzlich stattgefundenen JUG spricht ... Gute Zeiten;) Willkommen auf SO. – VonC

Antwort

20

Wie in Git FAQ erwähnt, wird es ähnliche Inhalte basierend auf einer Heuristik erkennen.

Git muss mit vielen verschiedenen Workflows zusammenarbeiten, z. B. können einige Änderungen von Patches stammen, bei denen Umbenennungsinformationen möglicherweise nicht verfügbar sind. Sich auf das explizite Umbenennungs-Tracking zu verlassen, macht es unmöglich, zwei Bäume zusammenzuführen, die genau das Gleiche gemacht haben, außer einem als Patch (create/delete) und einmal mit einer anderen Heuristik.

Eine zweite Anmerkung, Tracking-Umbenennungen ist wirklich nur ein Spezialfall der Verfolgung, wie sich Inhalte in der Struktur bewegen. In einigen Fällen sind Sie möglicherweise an einer Abfrage interessiert, wenn eine Funktion hinzugefügt oder in eine andere Datei verschoben wurde. Indem es sich nur auf die Fähigkeit stützt, diese Informationen bei Bedarf neu zu erstellen, zielt Git darauf ab, eine flexiblere Möglichkeit zu bieten, um zu verfolgen, wie sich Ihr Baum verändert.

Dies bedeutet jedoch nicht, dass Git keine Umbenennungen unterstützt.
Die Diff-Maschine in Git unterstützt die automatische Erkennung von Umbenennungen. Dies wird durch den Schalter '-M' in die Befehlsfamilie git-diff-* aktiviert.
Die Umbenennungserkennungsmaschinerie wird von git-log (1) und git-whatchanged (1) verwendet, so dass zum Beispiel 'git log -M' den Commit-Verlauf mit Umbenennungsinformationen angibt.
Git unterstützt auch eine eingeschränkte Form der Zusammenführung von Umbenennungen.
Die beiden Tools zum Zuweisen von Schuldzuweisungen, git-blame(1) und git-annotate(1), verwenden beide den automatischen Umbenennungs-Erkennungscode, um Umbenennungen zu verfolgen.


git log gibt Ihnen einige Details über diese Heuristik:

-B[<n>][/<m>] 

Pause komplett neu geschrieben Änderungen in Lösch- und erstellen. Dies dient zwei Zwecken:

  • Es die Art und Weise eine Änderung wirkt sich das aus einer Datei nicht als eine Reihe von Löschen und Einfügen zusammen gemischt mit sehr wenigen Linien auf insgesamt Rewrite Beträge, die textlich als Kontext anzupassen passieren , aber als eine einzige Löschung von allem alt gefolgt von einer einzigen Einfügung von allem neu, und die Zahl m steuert diesen Aspekt der -B Option (standardmäßig 60%).
    -B/70% gibt an, dass weniger als 30% des Originals im Ergebnis bleiben sollten, damit git es als vollständig umgeschrieben betrachtet (dh andernfalls wird der resultierende Patch eine Reihe von Lösch- und Einfügemischungen zusammen mit Kontextlinien sein)).

  • Bei der Verwendung mit -M wird eine vollständig neu geschriebene Datei ebenfalls als Quelle für eine Umbenennung angesehen (normalerweise betrachtet -M nur eine Datei, die als Quelle einer Umbenennung verschwindet), und die Zahl n steuert diesen Aspekt der -B Option (standardmäßig 50%).
    -B20% gibt an, dass eine Änderung mit Hinzufügung und Löschung im Vergleich zu 20% oder mehr der Dateigröße als mögliche Quelle für eine Umbenennung in eine andere Datei ausgewählt werden kann.

-M[<n>] 

Wenn diffs zu erzeugen, erkennen und Bericht für jede umbenennt begehen. Weitere Informationen zum Umbenennen von Dateien finden Sie unter --follow.
Wenn n angegeben ist, ist a ein Schwellenwert für den Ähnlichkeitsindex (d. H. Menge an Hinzufügungen/Löschungen im Vergleich zur Dateigröße).
Zum Beispiel bedeutet -M90%, dass git ein Lösch/hinzufügen-Paar als Umbenennung betrachten sollte, wenn mehr als 90% der Datei nicht geändert wurden.


Weitere Referenzen:

+0

OK, aber gibt es eine einfache Antwort in einfacher Sprache auf die ursprüngliche Situation? Wenn ich eine Java-Klasse umgestalten will, indem ich sie in ein anderes Paketverzeichnis verschiebe, so dass außerhalb von (z. B.) 100 Zeilen eine einzige Zeile geändert wurde, die das Java-Paket angibt, wird das _default_-Protokoll und die Schuld die Verschiebung/Umbenennung erkennen. Werde ich GitHub/BitBucket noch immer die Schuld geben? Mit anderen Worten, werden die Dinge "einfach funktionieren" mit den Standardeinstellungen von allem, wenn ich diese (sehr, sehr, sehr) häufige Aktivität mache? –

+0

@GarretWilson ja, es wird auf der lokalen Seite (wo Sie 'git log --follow' (wie in http://stackoverflow.com/q/2314652/6309) oder 'git Schuld -C 'aufrufen. Das hat gewonnen auf der Seite des Git-Hosting-Servers (GitHub: http://Stackoverflow.com/a/5647721/6309) (oder BitBucket: https://bitbucket.org/site/master/issues/589/file- Geschichte-sollte-folgen-Kopien-und) – VonC

+0

Danke für die schnelle Klärung mit den Links! Ich werde meine Kommentare zu Git zurückhalten, die es scheint, ich habe keine andere Wahl als zu verwenden ... :) –

Verwandte Themen