Wie kann ich den Verlauf so umschreiben, dass sich alle Dateien, außer denen, die ich bereits verschoben habe, in einem Unterverzeichnis befinden?
Lesezeit: 4 Minuten
Alexander Sandler
Ich habe ein Projekt unter git. Eines Tages habe ich alle Projektdateien aus dem aktuellen Verzeichnis nach verschoben foo/bar/ unter dem Projekt. Ich habe es mit gemacht git mv. Dann habe ich weitere Dateien hinzugefügt und einige Änderungen an bereits vorhandenen Dateien vorgenommen.
Als Ergebnis jetzt, wenn ich mir die Geschichte anschaue foo/bar/file.ckann ich nur Änderungen sehen, die ich vorgenommen habe, nachdem ich die Datei verschoben habe.
Ich habe versucht, dies auf verschiedene Weise zu beheben (filter-branch mit Unterverzeichnisfilter usw.), aber nichts hat geholfen, also bin ich hier ziemlich gestapelt. Ich freue mich über jede Hilfe, die Sie mir geben können. Danke!
Dan Formen
So schreiben Sie den Verlauf mit den verschobenen Dateien neu:
Wenn Sie möchten, dass der Verlauf des Projekts so aussieht, als wären alle Dateien schon immer im Verzeichnis gewesen foo/bar, dann müssen Sie eine kleine Operation durchführen. Verwenden git filter-branch Mit dem “Baumfilter” können die Commits damit überall umgeschrieben werden foo/bar nicht existiert, wird es erstellt und alle Dateien werden dorthin verschoben:
Jetzt wird der Verlauf so aufgezeichnet, als ob alle Dateien vorhanden wären immer gelegen in foo/bar.
So zeigen Sie den Verlauf einer verschobenen Datei an:
Wenn Sie nur den Verlauf einer Datei sehen möchten, die irgendwann in der Vergangenheit verschoben oder umbenannt wurde, verwenden Sie einfach die --follow Option zu git log:
git log --follow foo/bar/file.c
@Alexander: Vielleicht möchten Sie versuchen, den Einzeiler (alles in einfachen Anführungszeichen) in ein tatsächliches Skript mit einer Bash-Shebang-Zeile einzufügen. Ich denke filter-branch versucht wahrscheinlich, dies einzufügen shnicht bash.
– Kaskabel
28. Oktober 2010 um 14:51 Uhr
Ich habe einige Fortschritte gemacht. Es scheint, dass doppelte Klammern in der if-Anweisung diesen Fehler verursacht haben. Einzelne Klammern funktionieren besser, aber es funktioniert immer noch nicht. Das Problem ist, dass ich, bevor ich alles nach foo/bar/ verschoben habe, ein Verzeichnis namens foo mit einigen Inhalten im Projekt hatte. Jetzt beschwert es sich “kann sich nicht bewegen foo' to a subdirectory of itself, foo/bar/foo'”.
– Alexander Sandler
28. Oktober 2010 um 15:05 Uhr
@Alexander: Sie müssen nur das Skript entsprechend anpassen. Etwas wie: if [[ ! -e foo/bar ]]; then mkdir -p foo/bar; git ls-tree --name-only $GIT_COMMIT | grep -v ^foo$ | xargs -I files mv files foo/bar; fi Das verwendet grep zum Herausfiltern foo aus der Liste der zu verschiebenden Dateien. Beachten Sie, dass ich auch davon ausgehe, dass die bar Unterverzeichnis existierte nie, bis Sie alles darunter verschoben haben. Wenn dies nicht der Fall ist, müssen Sie dies ebenfalls im Skript berücksichtigen.
– Dan Formen
28. Oktober 2010 um 17:31 Uhr
Verwenden [[ caused a problem for me, as there is no such command (it is a shell bulitin), using [ and ] löst das Problem.
– Aularon
22. April 2014 um 13:06 Uhr
@TTT ja, es kann leicht rückgängig gemacht werden. git filter-branch wird Kopien der ursprünglichen Branches unter refs/original behalten. Während du also auf branch foo bist, kannst du so etwas tun git reset --hard original/foo um die Dinge wieder so zu machen, wie sie waren.
– Dan Formen
19. Januar 2019 um 4:48 Uhr
Alexander Sandler
Zum Abschluss hier eine kurze Zusammenfassung dessen, was ich getan habe. Der Befehl, der für mich funktionierte, war:
if [ ! -e foo/bar ]; then mkdir -p foo/bar; git ls-tree --name-only $GIT_COMMIT | grep -v ^foo$ | xargs -I files mv files foo/bar || echo ""; fi
Der Echo-Befehl, den ich am Ende hinzugefügt habe, hat dafür gesorgt, dass der gesamte Befehl auch dann weiter ausgeführt wird, wenn mv fehlschlägt. Es hat den Inhalt von foo/bar/foo nicht verschoben, aber damit kann ich leben.
Vielen Dank an Dan Moulding (!!!) und Jefromi für die Hilfe.
Verwenden || true anstatt || echo "" ist schneller.
Fügen Sie die ausführbare Datei git-filter-repo zu Ihrem $PATH hinzu (siehe INSTALL.MD für andere Optionen):
# this is just an example, you probably want to edit bashrc,
# or add a symlink to ~/bin or /usr/local/bin
PATH=$PATH:${PWD}/git-filter-repo
Jetzt cd zu dem Git-Repo, das Sie ändern möchten, und führen Sie Folgendes aus:
git filter-repo --to-subdirectory-filter foo/bar
8689900cookie-checkWie kann ich den Verlauf so umschreiben, dass sich alle Dateien, außer denen, die ich bereits verschoben habe, in einem Unterverzeichnis befinden?yes