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

Wie kann ich den Verlauf so umschreiben dass sich alle
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!

Wie kann ich den Verlauf so umschreiben dass sich alle
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:

git filter-branch --prune-empty --tree-filter '
if [ ! -e foo/bar ]; then
    mkdir -p foo/bar
    git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files foo/bar
fi'

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

Wie kann ich den Verlauf so umschreiben dass sich alle
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.

    – Skarrlot

    29. Mai 2020 um 16:23 Uhr

Installieren Sie git-filter-repo:

git clone https://github.com/newren/git-filter-repo/

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

868990cookie-checkWie kann ich den Verlauf so umschreiben, dass sich alle Dateien, außer denen, die ich bereits verschoben habe, in einem Unterverzeichnis befinden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy