Datei und Verzeichnis zusammen mit dem Commit-Verlauf in ein Unterverzeichnis verschieben

Lesezeit: 7 Minuten

Datei und Verzeichnis zusammen mit dem Commit Verlauf in ein Unterverzeichnis
erste.ptl

Wie kann ich ein Verzeichnis und Dateien zusammen mit dem Commit-Verlauf in ein Unterverzeichnis verschieben?

Zum Beispiel:

  • Quellverzeichnisstruktur: [project]/x/[files & sub-dirs]

  • Zielverzeichnisstruktur: [project]/x/p/q/[files & sub-dirs]

  • Ich verstehe die meisten Antworten auf diese Frage nicht, ich habe alle Möglichkeiten ausprobiert, ich habe immer entweder einen Fehler bekommen oder einfach nichts passiert, also habe ich einfach den .git-Ordner ausgeschnitten und in einen Unterordner eingefügt … weißt du was? Es funktionierte!

    – Ayyash

    6. Dezember 2016 um 11:11 Uhr

  • Siehe verwandte/doppelte Frage stackoverflow.com/q/33002612/421049. Meine Antwort stackoverflow.com/a/50547331/421049 behandelt dort Windows.

    – Garret Wilson

    26. Mai 2018 um 22:05 Uhr

  • Weiß jemand wie man es andersherum macht. Haben Sie eine Repro in einem Unterordner und fügen Sie dieser Repro dann einige übergeordnete Dateien/Ordner hinzu?

    – Martin Krung

    20. August 2018 um 11:26 Uhr

Datei und Verzeichnis zusammen mit dem Commit Verlauf in ein Unterverzeichnis
VonC

Um den Kommentar von bmargulies zu ergänzen, lautet die vollständige Sequenz:

mkdir -p x/p/q      # make sure the parent directories exist first
git mv x/* x/p/q    # move folder, with history preserved
git commit -m "changed the foldername x into x/p/q"

Probieren Sie es zuerst aus, um eine Vorschau des Umzugs zu sehen:

git mv -n x/* x/p/q

Wolfgang kommentiert:

Wenn Sie bash verwenden, können Sie das Problem vermeiden, dass Sie versuchen, einen Ordner in sich selbst zu verschieben, indem Sie einen erweiterten Glob wie diesen verwenden (mit der shopt eingebaut):

shopt -s extglob; git mv !(folder) folder

Captain Man berichtet in den Kommentaren zu tun:

mkdir temp 
git mv x/* temp
mkdir -p x/p/q
git mv temp x/p/q
rmdir temp;

Kontext:

Ich bin auf Windows mit Cygwin.
Mir wurde gerade klar, dass ich das getan habe shopt -s extglob Beispiel falsch, also war mein Weg vielleicht nicht notwendig, aber ich verwende normalerweise zsh anstelle von bash, und es hatte nicht den Befehl shopt -s extglob (obwohl ich mir sicher bin, dass es eine Alternative gibt), also sollte dieser Ansatz Shell-übergreifend funktionieren (Subbing in Ihrer Shell mkdir und rmdir wenn es besonders fremd ist)


Als Alternative erwähnt spanky in den Kommentaren die -k Option von git mv:

Aktionen zum Verschieben oder Umbenennen überspringen, die zu einer Fehlerbedingung führen würden.

git mv -k * target/

Das würde die “can not move directory into itself” Error.

  • Du kannst dich nicht bewegen x in ein Unterverzeichnis von sich selbst. git mv ... macht den Job, muss nicht git add ... nichts, wenn es keine weiteren Änderungen gibt.

    – Vonbrand

    4. Februar 2014 um 18:28 Uhr

  • Wie verwende ich hier git mv? Es beschwert sich, dass ich ein Verzeichnis nicht in ein Unterverzeichnis von sich selbst verschieben kann.

    – Abhinav Manchanda

    18. Oktober 2015 um 22:38 Uhr

  • Wenn Sie Bash verwenden, können Sie das Problem vermeiden, einen Ordner in sich selbst zu verschieben, indem Sie einen erweiterten Glob wie folgt verwenden: shopt -s extglob; git mv !(folder) folder

    –Wolfgang

    16. November 2015 um 19:17 Uhr

  • Ich habe gerade erfahren, dass Sie verwenden können git mv -k * target/ um den Fehler “Verzeichnis kann nicht in sich selbst verschoben werden” zu vermeiden.

    – Spanky

    7. August 2017 um 21:20 Uhr

  • @Spanky Interessant. Ich habe Ihren Kommentar zur besseren Sichtbarkeit in die Antwort aufgenommen.

    – VonC

    7. August 2017 um 21:40 Uhr

1645907289 114 Datei und Verzeichnis zusammen mit dem Commit Verlauf in ein Unterverzeichnis
PiQuer

Git leistet sehr gute Arbeit, um Inhalte zu verfolgen, auch wenn sie verschoben werden git mv ist eindeutig der richtige Weg, wenn Sie Dateien verschieben, weil sie früher dazu gehörten xaber jetzt gehören sie rein x/p/q weil sich das Projekt so entwickelt hat.

Manchmal gibt es jedoch einen Grund, Dateien im Verlauf eines Projekts in ein Unterverzeichnis zu verschieben. Zum Beispiel, wenn die Dateien versehentlich irgendwo abgelegt wurden und seitdem einige weitere Commits durchgeführt wurden, aber die intermittierenden Commits keinen Sinn ergeben, wenn die Dateien am falschen Ort sind. Wenn das alles in einem lokalen Zweig passiert ist, wollen wir das Chaos aufräumen, bevor wir pushen.

Die Frage lautet “zusammen mit dem Commit-Verlauf”, was ich als Umschreiben des Verlaufs auf genau diese Weise interpretieren würde. Dies kann mit erfolgen

git filter-branch --tree-filter "cd x; mkdir -p p/q; mv [files & sub-dirs] p/q" HEAD

Die Dateien erscheinen dann im p/q Unterverzeichnis im gesamten Verlauf.

Der Baumfilter eignet sich gut für kleine Projekte, sein Vorteil ist, dass der Befehl einfach und leicht verständlich ist. Für große Projekte lässt sich diese Lösung nicht sehr gut skalieren. Wenn es auf die Leistung ankommt, sollten Sie einen Indexfilter verwenden, wie in dieser Antwort beschrieben.

Bitte beachten Sie, dass das Ergebnis nicht auf einen öffentlichen Server gepusht werden sollte, wenn das Umschreiben Commits berührt, die bereits zuvor gepusht wurden.

  • danke, hat mir den tag versüßt! Ich wollte alle Dateien eines Baumes in ein neues Unterverzeichnis “verschieben” und habe deinen Ansatz mit genutzt mv * ./the-subdir bekam aber den Fehler: “the-subdir kann nicht in ein Unterverzeichnis von sich selbst verschoben werden. Meine Lösung ist zu verwenden mv the-subdir /tmp; mv * /tmp/the-subdir mv /tmp/the-subdir ./ innerhalb des Baumfilterbefehls. Klappt wunderbar.

    – Alexander

    22. Mai 2014 um 7:40 Uhr


  • Ich könnte das nicht zum Laufen bringen, wenn ich nicht git mv [files & sub-dirs] p/q anstatt ein Raw zu nennen mv; Läuft auf einem Mac. Aber es hat am Ende gut für mich funktioniert, also danke!

    – d4vidi

    19. Februar 2018 um 16:51 Uhr

  • ich benutzte mv * .* the/subdir/ || true Dateien und Punktdateien zu verschieben und die Fehlermeldungen zu ignorieren.

    – joeytwiddle

    18. Oktober 2019 um 10:21 Uhr

Datei und Verzeichnis zusammen mit dem Commit Verlauf in ein Unterverzeichnis
peroyhav

Ich sehe, dass dies eine alte Frage ist, aber ich fühle mich dennoch verpflichtet, mit meiner aktuellen Lösung des Problems zu antworten, die ich aus einem der Beispiele in abgeleitet habe Git-Buch. Anstatt ein ineffizientes zu verwenden --tree-filter Ich schiebe die Dateien direkt auf den Index mit an --index-filter.

git filter-branch -f --index-filter 'PATHS=`git ls-files -s | sed "s/^<old_location>/<new_location>/"`;GIT_INDEX_FILE=$GIT_INDEX_FILE.new; echo -n "$PATHS" | git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- --all

Dies ist eine Spezialisierung eines der Beispiele aus dem Buch. Ich habe das gleiche Beispiel auch verwendet, um in einem speziellen Fall Dateien in der Commit-Historie massenhaft umzubenennen. wenn Sie Dateien in Unterverzeichnisse verschieben: Denken Sie daran, das /-Zeichen in den Pfaden mit einem \ zu maskieren, damit der sed-Befehl wie erwartet funktioniert.

Beispiel:

Project Directory
                 |-a
                 |  |-a1.txt
                 |  |-b
                 |  |  |-b1.txt

So verschieben Sie das b-Verzeichnis in das Projektstammverzeichnis:

git filter-branch -f --index-filter 'PATHS=`git ls-files -s | sed "s/a\/b\//b\//"`;GIT_INDEX_FILE=$GIT_INDEX_FILE.new; echo -n "$PATHS" | git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- --all

Ergebnis:

Project Directory
                 |-a
                 |  |-a1.txt
                 |
                 |-b
                 |  |-b1.txt

  • Mit Ihrer Befehlszeile habe ich fatal: malformed index info -n 100644. Mit git filter-branch -f --index-filter 'git ls-files -s | sed "s/<old_location>/<new_location>/" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD es hat in meinem Fall funktioniert. Vergessen Sie nicht zu entkommen / mit \/.

    – Tanguy_k

    25. Februar 2019 um 23:10 Uhr


  • @tanguy_k Wenn Sie verwenden : als Trennzeichen für seddann müssen Sie sich keine Sorgen um die Flucht machen /.

    – Mateen Ulhaq

    2. Oktober 2019 um 23:43 Uhr

Der Befehl git mv ist der einfachste Weg. Zumindest auf meiner Linux-Box musste ich jedoch das Flag -k angeben, um zu vermeiden, dass eine Fehlermeldung zurückgegeben wird, dass ein Ordner nicht in sich selbst verschoben werden kann. Ich konnte die Aktion ausführen, indem ich …

mkdir subdirectory
git mv -k ./* ./subdirectory
# check to make sure everything moved (see below)
git commit

Als Warnung wird dies übersprungen alle Verschiebungen, die zu einem Fehlerzustand führen würden, daher möchten Sie wahrscheinlich überprüfen, ob nach der Verschiebung und vor einem Commit alles richtig funktioniert hat.

Hier ist ein alternativer Weg, wenn Sie aus irgendeinem Grund den Befehl git mv nicht verwenden möchten:

  • Stellen Sie sicher, dass Sie keine nicht festgeschriebenen Änderungen haben.

    Git-Status

  • Verschieben Sie einfach den Ordner, der den .git-Ordner enthält, in den neuen Ordner:

    mkdir neuer_ordner mv alter_ordner neuer_ordner

  • Verschieben Sie dann die .git old_folder aus dem verschobenen Ordner zurück in den Basisordner:

    mv neuer_ordner/alter_ordner/.git neuer_ordner/

  • Stellen Sie dann alle erkannten Änderungen bereit und schreiben Sie sie fest (aufgeführt als Hinzufügen von Dateien zu ihrem neuen Speicherort und Entfernen von Dateien von ihrem alten Speicherort).

1645907291 982 Datei und Verzeichnis zusammen mit dem Commit Verlauf in ein Unterverzeichnis
Eduard Falk

Mein eigener Vorschlag: git fast-export Bearbeiten Sie dann die Exportdatei git fast-import.

867890cookie-checkDatei und Verzeichnis zusammen mit dem Commit-Verlauf in ein Unterverzeichnis verschieben

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

Privacy policy