Ich möchte einen Projekt-Teilbaum in Git umbenennen / verschieben, von dem aus er verschoben wird
/project/xyz
zu
/components/xyz
Wenn ich eine Ebene verwende git mv project components
, geht der gesamte Festschreibungsverlauf für die xyz project
verloren. Gibt es eine Möglichkeit, dies so zu verschieben, dass die Historie erhalten bleibt?
git mv
: stackoverflow.com/questions/1094269/whats-the-purpose-of-git-mvAntworten:
Git erkennt Umbenennungen, anstatt den Vorgang mit dem Commit fortzusetzen. Es spielt also keine Rolle , ob Sie ihn verwenden
git mv
odermv
nicht.Der
log
Befehl verwendet ein--follow
Argument, das den Verlauf vor einer Umbenennungsoperation fortsetzt, dh er sucht mithilfe der Heuristik nach ähnlichen Inhalten:http://git-scm.com/docs/git-log
Verwenden Sie den folgenden Befehl, um den vollständigen Verlauf abzurufen:
quelle
git config alias.logf "log --follow"
und einfach zu schreibengit logf ./path/to/file
.Es ist möglich , eine Datei umzubenennen und den Verlauf beizubehalten, obwohl dadurch die Datei im gesamten Verlauf des Repositorys umbenannt wird. Dies ist wahrscheinlich nur für die obsessiven Git-Log-Liebhaber und hat einige schwerwiegende Auswirkungen, einschließlich dieser:
Jetzt, da Sie noch bei mir sind, sind Sie wahrscheinlich ein Solo-Entwickler, der eine vollständig isolierte Datei umbenennt. Verschieben wir eine Datei mit
filter-tree
!Angenommen, Sie verschieben eine Datei
old
in einen Ordnerdir
und geben ihr den Namennew
Dies könnte getan werden
git mv old dir/new && git add -u dir/new
, aber das bricht die Geschichte.Stattdessen:
wird Redo jeden in dem Zweig commit, für jede Iteration den Befehl in die Zecken ausführt. Wenn Sie dies tun, können viele Dinge schief gehen. Normalerweise teste ich, ob die Datei vorhanden ist (andernfalls ist sie noch nicht zum Verschieben vorhanden), und führe dann die erforderlichen Schritte aus, um den Baum nach meinen Wünschen zu beschlagen. Hier können Sie Dateien durchsuchen, um Verweise auf die Datei usw. zu ändern. Sich selbst umhauen! :) :)
Nach Abschluss wird die Datei verschoben und das Protokoll ist intakt. Du fühlst dich wie ein Ninja-Pirat.
Ebenfalls; Das Verzeichnis mkdir ist natürlich nur erforderlich, wenn Sie die Datei in einen neuen Ordner verschieben. Das if verhindert , dass dieser Ordner früher im Verlauf erstellt wird, als Ihre Datei vorhanden ist.
quelle
--index-filter
for-Umbenennungen viel schneller, da der Baum nicht bei jedem Commit ausgecheckt und wieder eingefügt werden muss.--index-filter
wirkt direkt auf jeden Commit-Index.Nein.
Die kurze Antwort lautet NEIN . Es ist nicht möglich, eine Datei in Git umzubenennen und sich den Verlauf zu merken. Und es ist ein Schmerz.
Gerüchten zufolge wird es
git log --follow
--find-copies-harder
funktionieren, aber es funktioniert bei mir nicht, selbst wenn der Dateiinhalt nicht geändert wurde und die Verschiebungen mit vorgenommen wurdengit mv
.(Anfangs habe ich Eclipse verwendet, um Pakete in einem Vorgang umzubenennen und zu aktualisieren, was Git möglicherweise verwirrt hat. Aber das ist eine sehr häufige Sache.
--follow
Scheint zu funktionieren, wenn nur a ausgeführtmv
wird und dann acommit
und dasmv
nicht zu weit ist.)Laut Linus sollten Sie den gesamten Inhalt eines Softwareprojekts ganzheitlich verstehen und nicht einzelne Dateien nachverfolgen müssen. Nun, leider kann mein kleines Gehirn das nicht.
Es ist wirklich ärgerlich, dass so viele Leute die Aussage, dass Git Bewegungen automatisch verfolgt, sinnlos wiederholt haben. Sie haben meine Zeit verschwendet. Git macht so etwas nicht. Mit Absicht (!) Verfolgt Git überhaupt keine Bewegungen.
Meine Lösung besteht darin, die Dateien wieder an ihren ursprünglichen Speicherort umzubenennen. Ändern Sie die Software entsprechend der Quellcodeverwaltung. Mit Git müssen Sie es einfach gleich beim ersten Mal richtig "git".
Leider bricht das Eclipse, das zu verwenden scheint
--follow
.git log --follow
Manchmal wird nicht der vollständige Verlauf von Dateien mit komplizierten Umbenennungsverläufen angezeigt, obwohl dies dergit log
Fall ist. (Keine Ahnung warum.)(Es gibt einige zu clevere Hacks, die zurückgehen und alte Arbeiten wieder aufnehmen, aber sie sind ziemlich beängstigend. Siehe GitHub-Gist: emiller / git-mv-with-history .)
quelle
zeigt Ihnen den Verlauf durch Umbenennen.
quelle
git mv
Grunde agit rm && git add
. Es gibt Optionen wie-M90
/--find-renames=90
, um eine Datei als umzubenennen zu betrachten, wenn sie zu 90% identisch ist.Ich mache:
quelle
-A
stattdessen das Verhalten von ? Siehe auch hier: git-scm.com/docs/git-addgit add -u
. Die Git-Dokumente sind in der Regel nicht hilfreich und der letzte Ort, an dem ich nachsehen möchte. Hier ist ein Beitraggit add -u
in Aktion: stackoverflow.com/a/2117202 .Nein (8 Jahre später, Git 2.19, Q3 2018), da Git die Umbenennung des Verzeichnisses erkennt und dies nun besser dokumentiert ist.
Siehe Commit b00bf1c , Commit 1634688 , Commit 0661e49 , Commit 4d34dff , Commit 983f464 , Commit c840e1a , Commit 9929430 (27. Juni 2018) und Commit d4e8062 , Commit 5dacd4a (25. Juni 2018) von Elijah Newren (
newren
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit 0ce5a69 , 24. Juli 2018)Das wird jetzt erklärt in
Documentation/technical/directory-rename-detection.txt
:Beispiel:
Aber es gibt viele andere Fälle, wie:
Um die Erkennung von Verzeichnisumbenennungen zu vereinfachen, werden diese Regeln von Git erzwungen:
Bei der Erkennung der Umbenennung von Verzeichnissen gelten einige grundlegende Regeln:
Sie können viele Tests in sehen
t/t6043-merge-rename-directories.sh
, die auch darauf hinweisen, dass:quelle
Zielsetzung
git am
Verjährung
Zusammenfassung
git log --pretty=email -p --reverse --full-index --binary
cat extracted-history | git am --committer-date-is-author-date
1. Extrahieren Sie den Verlauf im E-Mail-Format
Beispiel: Extrahieren Sie den Verlauf von
file3
,file4
undfile5
Ziel festlegen / reinigen
Extrahieren Sie den Verlauf jeder Datei im E-Mail-Format
Leider Option
--follow
oder--find-copies-harder
kann nicht mit kombiniert werden--reverse
. Aus diesem Grund wird der Verlauf beim Umbenennen der Datei (oder beim Umbenennen eines übergeordneten Verzeichnisses) abgeschnitten.Temporärer Verlauf im E-Mail-Format:
Dan Bonachea schlägt vor, die Schleifen des Befehls zur Generierung des Git-Protokolls in diesem ersten Schritt umzukehren : Anstatt das Git-Protokoll einmal pro Datei auszuführen, führen Sie es genau einmal mit einer Liste von Dateien in der Befehlszeile aus und generieren Sie ein einzelnes einheitliches Protokoll. Auf diese Weise bleiben Commits, die mehrere Dateien ändern, ein einziges Commit im Ergebnis, und alle neuen Commits behalten ihre ursprüngliche relative Reihenfolge bei. Beachten Sie, dass dies auch Änderungen im zweiten Schritt unten erfordert, wenn Dateinamen im (jetzt einheitlichen) Protokoll neu geschrieben werden.
2. Ordnen Sie den Dateibaum neu an und aktualisieren Sie die Dateinamen
Angenommen, Sie möchten diese drei Dateien in diesem anderen Repo verschieben (kann dasselbe Repo sein).
Organisieren Sie daher Ihre Dateien neu:
Ihre vorübergehende Geschichte ist jetzt:
Ändern Sie auch Dateinamen innerhalb des Verlaufs:
3. Wenden Sie einen neuen Verlauf an
Dein anderes Repo ist:
Übernehmen Sie Commits aus temporären Verlaufsdateien:
--committer-date-is-author-date
behält die ursprünglichen Festschreibungszeitstempel bei (Kommentar von Dan Bonachea ).Dein anderes Repo ist jetzt:
Verwenden Sie
git status
diese Option, um die Anzahl der Commits anzuzeigen, die zum Pushing bereit sind :-)Zusätzlicher Trick: Überprüfen Sie umbenannte / verschobene Dateien in Ihrem Repo
So listen Sie die umbenannten Dateien auf:
Weitere Anpassungen: Sie können den Befehl
git log
mit den Optionen--find-copies-harder
oder ausführen--reverse
. Sie können die ersten beiden Spalten auch mitcut -f3-
dem vollständigen Muster '{. * =>. *}' Entfernen und erfassen.quelle
Ich folgte diesem mehrstufigen Prozess, um Code in das übergeordnete Verzeichnis zu verschieben und den Verlauf beizubehalten.
Schritt 0: Erstellt einen Zweig 'Verlauf' von 'Master' zur sicheren Aufbewahrung
Schritt 1: Verwendet das Git-Filter-Repo- Tool, um den Verlauf neu zu schreiben. Dieser Befehl unten hat den Ordner 'FolderwithContentOfInterest' auf eine Ebene nach oben verschoben und den entsprechenden Commit-Verlauf geändert
Schritt 2: Zu diesem Zeitpunkt hat das GitHub-Repository seinen Remote-Repository-Pfad verloren. Remote-Referenz hinzugefügt
Schritt 3: Informationen zum Repository abrufen
Schritt 4: Verbinden Sie den lokalen verlorenen Zweig mit dem Ursprungszweig
Schritt 5: Adresszusammenführungskonflikt für die Ordnerstruktur, wenn Sie dazu aufgefordert werden
Schritt 6: Drücken Sie !!
Hinweis: Der geänderte Verlauf und der verschobene Ordner scheinen bereits festgeschrieben zu sein.
enter code here
Erledigt. Der Code wird in das übergeordnete / gewünschte Verzeichnis verschoben, wobei der Verlauf erhalten bleibt!
quelle
Während der Kern von Git, die Git-Installation, die Umbenennungen nicht verfolgt, kann der Verlauf, den Sie mit dem Git-Protokoll "Porzellan" anzeigen, diese erkennen, wenn Sie möchten.
git log
Verwenden Sie für eine bestimmte Option die Option -M:Mit einer aktuellen Version von Git.
Dies funktioniert für andere Befehle wie
git diff
.Es gibt Optionen, um die Vergleiche mehr oder weniger streng durchzuführen. Wenn Sie eine Datei umbenennen, ohne gleichzeitig wesentliche Änderungen an der Datei vorzunehmen, können Git-Protokoll und Freunde die Umbenennung leichter erkennen. Aus diesem Grund benennen einige Benutzer Dateien in einem Commit um und ändern sie in einem anderen.
Die CPU-Nutzung ist mit Kosten verbunden, wenn Sie Git fragen, wo Dateien umbenannt wurden. Ob Sie sie verwenden oder nicht und wann, liegt bei Ihnen.
Wenn Sie möchten, dass Ihr Verlauf immer mit Umbenennungserkennung in einem bestimmten Repository gemeldet wird, können Sie Folgendes verwenden:
Dateien, die von einem Verzeichnis in ein anderes verschoben werden, werden erkannt. Hier ist ein Beispiel:
Bitte beachten Sie, dass dies immer dann funktioniert, wenn Sie diff verwenden, nicht nur mit
git log
. Zum Beispiel:Als Test habe ich eine kleine Änderung an einer Datei in einem Feature-Zweig vorgenommen und diese festgeschrieben. Im Master-Zweig habe ich die Datei umbenannt, festgeschrieben und dann eine kleine Änderung an einem anderen Teil der Datei vorgenommen und diese festgeschrieben. Als ich zum Feature-Zweig ging und vom Master zusammengeführt wurde, benannte die Zusammenführung die Datei um und führte die Änderungen zusammen. Hier ist die Ausgabe der Zusammenführung:
Das Ergebnis war ein Arbeitsverzeichnis, in dem die Datei umbenannt und beide Textänderungen vorgenommen wurden. So ist es Git möglich, das Richtige zu tun, obwohl Umbenennungen nicht explizit verfolgt werden.
Dies ist eine späte Antwort auf eine alte Frage, sodass die anderen Antworten zu diesem Zeitpunkt möglicherweise für die Git-Version korrekt waren.
quelle
Erstellen Sie zunächst ein eigenständiges Commit mit nur einer Umbenennung.
Eventuelle Änderungen am Dateiinhalt werden dann in das separate Commit übernommen.
quelle
So benennen Sie ein Verzeichnis oder eine Datei um (ich weiß nicht viel über komplexe Fälle, daher kann es einige Einschränkungen geben):
So benennen Sie ein Verzeichnis in Dateien um, in denen es erwähnt wird (es ist möglich, Rückrufe zu verwenden, aber ich weiß nicht wie):
expressions.txt
ist eine Datei, die mit Zeilen wie gefüllt istliteral:OLD_NAME==>NEW_NAME
(es ist möglich, Pythons RE mitregex:
oder glob mit zu verwendenglob:
).So benennen Sie ein Verzeichnis in Commit-Nachrichten um:
Die regulären Ausdrücke von Python werden ebenfalls unterstützt, müssen jedoch manuell in Python geschrieben werden.
Wenn das Repository original ist, ohne Remote, müssen Sie hinzufügen
--force
, um ein Umschreiben zu erzwingen. (Möglicherweise möchten Sie zuvor eine Sicherungskopie Ihres Repositorys erstellen.)Wenn Sie keine Refs beibehalten möchten (diese werden im Zweigverlauf der Git-GUI angezeigt), müssen Sie hinzufügen
--replace-refs delete-no-add
.quelle
Verschieben Sie einfach die Datei und inszenieren Sie mit:
Vor dem Festschreiben können Sie den Status überprüfen:
Das wird zeigen:
Ich habe mit Git Version 2.26.1 getestet.
Aus der GitHub- Hilfeseite extrahiert .
quelle
Ich mache das Verschieben der Dateien und mache es dann
die in den Sättigungsbereich alle gelöschten / neuen Dateien legen. Hier erkennt git, dass die Datei verschoben wird.
Ich weiß nicht warum, aber das funktioniert bei mir.
quelle