Verschieben eines Git-Repositorys um eine Hierarchieebene


77

Git Anfängerfrage:

Ich habe ein kleines privates Webprojekt, das lokal mit msysgit versioniert ist. Es gibt kein externes Repository, da es nur für mich ist, sodass ich grundsätzlich tun kann, was ich will.

Ich habe dies im Projektverzeichnis eingerichtet, dh in "webroot".

Nun musste ein zweites Verzeichnis erstellt werden, das parallel zur Webroot platziert wurde. Nennen wir es Vermögenswerte.

Die Struktur ist nun also wie folgt:

\ project directory
----\webroot
----\assets

Ich würde dieses neue Verzeichnis gerne in das Git-Repository aufnehmen, damit ich auch Versionsänderungen an dort gespeicherten Dateien vornehmen kann, aber natürlich kann ich "git add ../assets" nicht verwenden. Ich bin auch nicht geneigt, ein neues Git-Projekt in project_directory zu erstellen, da dies alle meine vorherigen Commits verlieren würde.

Wie verschiebe ich das Repository von "webroot" nach oben in "project_directory", behalte meine Commits bei und kann dann "Assets" einschließen?


nicht genau das, was Sie fragen, aber Sie können einen Zweig erstellen und Assets hinzufügen.
Herr L

Antworten:


75

Sie möchten also, dass Ihr Git-Repo so aussieht:

<projectdir>
    /.git
    /webroot
    /assets

Dazu müssen Sie die vorhandenen Dateien in Ihrem Repo in ein neues webrootUnterverzeichnis verschieben.

cd <git repo root>
mkdir webroot
git mv <all your files> webroot
git commit --all -m "moved all existing files to new 'webroot' directory"

Dann möchten Sie auf Ihrem lokalen Dateisystem Ihren Klon in ein Verzeichnis verschieben, in dem er sich jetzt befindet:

cd <projectdir>
mv webroot/* .
rmdir webroot

Dann möchten Sie das assetsVerzeichnis (und die Dateien) zum Git-Repo hinzufügen :

git add assets
git commit -m "added assets to the repo"

2
Okay, anscheinend habe ich nicht genug Informationen gegeben. Das Repository befindet sich bereits in / projectdir / webroot /, da es hier ursprünglich erstellt wurde. Da das Assets-Verzeichnis zustande gekommen ist, würde ich es vorziehen, wenn sich das Repository so verhält, als ob es in / projectdir / erstellt wurde, was leider nicht der Fall war. Mit git mv kann ich keine Dateien außerhalb des Repositorys verschieben.
Sorcy

@ Sorcy: Ich glaube ich verstehe was du tun willst. Ich habe meine Antwort aktualisiert, um sie zu klären.
Tim Henigan

Danke, das ist genau die Lösung, nach der ich gesucht habe. :)
Sorcy

2
Ich fand, dass diese Lösung auch benötigt mv webroot/.* ., um die Repo- und .gitignore-Dateien zu verschieben.
Katriel

git mv * webrootfunktioniert nicht, da der Bash-Platzhalter * auch durch Webroot ersetzt wird, wodurch der Befehl ausgeführt wird git mv webroot webroot. Git wird daran scheitern. Der andere Ordner, mit dem es Probleme gab, war .git. Daher musste ich eine spezielle bash env-Variable verwenden, GLOBIGNORE=webroot:.gitdamit * nicht durch diese beiden Verzeichnisse ersetzt wird. Dank dessen musste ich nicht Dutzende von manuellen Git MV erstellen - mein Verzeichnis enthält viele Ordner und Dateien. Ich musste den .git-Ordner nur manuell verschieben.
Koshmaar

18

Sie können Ihr .git-Verzeichnis auch einfach um eine Ebene nach oben verschieben und Ihren Arbeitsbaum aktualisieren.

cd projectdir
mv ./webroot/.git ./.git
git config core.worktree /absolute-path-to-project-dir
git add assets
git commit -m 'adding assets folder'

Nicht positiv, aber ich bin mir ziemlich sicher, dass der Weg zu core.worktree absolut sein muss.


Hier ist die Reihenfolge, die für mich funktioniert hat. Während ich in dem Ordner bin, in den ich die mv .git / ../
.git-

Ich habe dies in einer ähnlichen Situation getan und musste dem Repo, das bereits hinzugefügt wurde, als sie sich am vorherigen Speicherort befanden, erneut Dateien hinzufügen. Im Grunde genommen habe ich den Git-Verlauf für diese Dateien verloren.
aneccodeal

11

Ich nehme an, Sie wollten den Verlauf so umschreiben, dass er alle Dateien in allen Revisionen enthält, als wären sie immer in einem Unterverzeichnis webroot / statt im Stammverzeichnis gewesen

Die git Filter-Branch-Manpage hat die Antwort, hier eine verbesserte Version, die alle vorhandenen Refs (Zweige) und Tags neu schreibt:

time git filter-branch --index-filter 'git ls-files -s |
         sed "s-\t\"*-&webroot/-" |
         GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && 
     mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' --tag-name-filter cat -- --all

Es wurde darauf geachtet, dass dies nur ein Index ist, damit der Prozess auch bei großen Repos schnell abläuft. Denken Sie daran, (wenn Sie zufrieden sind) die ursprünglichen Refs (.git / refs / original / *) zu entfernen und das Repo neu zu verpacken, um die veralteten Baumobjekte zu verlieren.


2
Können Sie erklären, wie Sie die Original-Refs entfernen und das Repo neu verpacken können? Ist es nur GC oder etwas anderes?
NateS

5

Ihre Commits sind nicht lokal an den "Webroot" -Ordner gebunden, den sie im Git-Repo gespeichert haben.

Sie können einfach das Webroot-Verzeichnis entfernen, indem Sie das Repository am neuen Speicherort "/ project directory" erneut überprüfen. Fügen Sie das Assets-Verzeichnis hinzu und schreiben Sie es fest.

rm -Rf webroot
git clone path-to-repo
git add assets 
git commit -m "Added assets directory"
git push

0

Der folgende Befehl würde Ihren Git-Verlauf neu schreiben. Es würde so aussehen, als ob der Inhalt die webrootganze Zeit drin wäre. Normalerweise ist das Umschreiben des Verlaufs problematisch, wenn mehrere Personen mit einem Repo arbeiten. Da Sie alleine daran arbeiten, sollte es in Ordnung sein.

git filter-branch --index-filter '
    git read-tree --prefix="webroot/" $GIT_COMMIT && \
    git ls-files \
      | sed "s/\/.*//" \
      | sort \
      | uniq \
      | grep -v "^webroot" \
      | xargs -L1 git rm -r --cached > /dev/null'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.