Wie kann ich den gesamten Git-Inhalt in der Ordnerhierarchie um eine Ebene nach oben verschieben?

78

Ich habe ein Git-Repository, dessen Struktur wie folgt aussieht:

+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+webapp
|
+---------+manage.py
+---------+modules
+---------+templates
+---------+static
+---------+...
+---------+...

Ich möchte den Inhalt des webappOrdners um eine Ebene nach oben verschieben. Mein resultierendes Repo sollte folgendermaßen aussehen:

+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+manage.py
+----+modules
+----+templates
+----+static
+----+...
+----+...

Kann ich dies tun, indem ich einfach alle Dateien des webappVerzeichnisses um eine Ebene nach oben verschiebe, das leere webappVerzeichnis lösche und dann die Änderungen festschreibe? Würde dies den Festschreibungsverlauf der Dateien im webappVerzeichnis beibehalten ?

Obwohl dies für viele von Ihnen eine sehr einfache Frage ist, möchte ich sicher sein. Das Letzte, was ich möchte, ist eine Git-Suppe.


Ich habe versucht, die Dateien zu verschieben, aber ich habe den Commit-Verlauf verloren, da git eine Verschiebung oder Umbenennung nicht wirklich handhabt. Ich weiß, dass es, obwohl es als neue Datei in den Protokollen angezeigt wird, immer noch möglich ist, den Festschreibungsverlauf für die Datei mithilfe einiger Optionen in anzuzeigen git log.

Nach dem, was ich gelesen habe, wäre der beste Weg, dies zu erreichen, die Verwendung git-filter. Ich bin nicht sehr gut mit Shell oder Git, also könnte mir jemand sagen, was ich ausführen müsste, um das oben Genannte zu tun.

Mridang Agarwalla
quelle
1
Wenn die Hashes Ihrer Dateien gleich bleiben, sollte git Dateien erkennen, die ohne git mvverschoben wurden. Sie können dies überprüfen, nachdem Sie die neuen Dateien mit git addusing hinzugefügt haben git status.
Ninjakannon

Antworten:

66

Der richtige Weg, dies zu tun, ist:

git mv repo.git/webapp/* repo.git/.
git rm repo.git/webapp
git add * 
git commit -m "Folders moved out of webapp directory :-)"
Sumeet Pareek
quelle
5
Das funktioniert bei mir nicht. In welchem ​​Verzeichnis haben Sie das ausgeführt?
Wharding28
6
Das hat bei mir perfekt funktioniert, danke! Nur um klar zu sein: Wenn Sie sich derzeit im Git-Verzeichnis befinden, müssen Sie nur tun, git mv /path/new/old/* /path/new/.wo path/new/oldsich die Dateien befinden und /path/newwo sie sich befinden sollen. Das *repräsentiert die Dateien selbst und nicht das Verzeichnis.
Lucy Bain
Herzlich willkommen bei @LucyBain und +1, wenn Sie anderen eine hilfreiche Erklärung hinterlassen.
Sumeet Pareek
51
Ich bekomme fatal: bad source, source=webapp/*, destination=*Das funktioniert überhaupt nicht; (
Andrew Savinykh
4
@ AndrewSavinykh, wie JLRishe in einer anderen Antwort erwähnt hat, scheint dies ein Problem zu sein, das für die Windows-Shell isoliert ist, aber wenn es in Git Bash ausgeführt wird, sollte es funktionieren.
Alec
31

Eine andere Variante von Sumeets Antwort: Führen Sie im Repository-Verzeichnis über "webapp" den folgenden Befehl aus:

git mv webapp/* ./ -k

-k - enthält Dateien, die noch nicht der Versionskontrolle unterliegen, andernfalls erhalten Sie:

fatal: not under version control, source=webapp/somefile, destination=somefile
Alex
quelle
2
Tödlich. Ich habe diese Dateien zuerst manuell entfernt, bevor ich Ihre Antwort gesehen habe ;-)
GhostCat
1
Was ist mit anderen Branchen? Muss ich sie auch neu gründen? Vielen Dank!
Matifou
1
> Was ist mit anderen Branchen? Muss ich sie auch neu gründen? - Antwort: Sie nehmen diese Änderungen in einem bestimmten Zweig vor, daher müssten Sie ähnliche Änderungen für jeden Zweig separat vornehmen.
Alex
7

In Windows können Sie Folgendes tun:

Während Sie sich im untergeordneten Ordner befinden

for /f %f in ('dir /b') do git mv %f ../

Das Ergebnis, dass sich alle Objekte im untergeordneten Ordner im übergeordneten Ordner befinden

Bitte beachten Sie: Einige Fehler können auftreten, wenn Sie ein Objekt im untergeordneten Ordner haben, dessen Name dem untergeordneten Ordner entspricht

Ammaroff
quelle
Dies ist die einzige Antwort, die in Win10 für mich funktioniert hat ... ohne Powershell. +1
Alan
1
habe dies: fatal: '../' ist außerhalb des Repository
mrapi
7

Ich konnte es einfach aus dem Zielordner zum Laufen bringen:

git mv webapp/* .

Es scheint dies nicht in der Windows - Shell funktioniert (nicht mit einem Fehler Bad source), aber es wird in Windows arbeiten , wenn Sie die Git Bash - Shell verwenden, die die erweitert *Wildcard.

JLRishe
quelle
5

Die von Ihnen erwähnte Lösung sollte funktionieren, da Git Änderungen zuerst basierend auf dem Hash der Dateien und dann ihrem Speicherort verfolgt.

Dies funktioniert nicht, wenn Sie beim Verschieben der Datei den Inhalt der Dateien ändern.

Probieren Sie es aus, und wenn es nicht funktioniert, können Sie die Änderungen rückgängig machen, bevor Sie die Änderungen in das Master-Repo übertragen :). Dies ist einer der Gründe, warum ich Git wirklich mag.

Bearbeiten

Ich habe vergessen zu erwähnen, dass Sie den Parameter '--follow' verwenden müssen, um die Änderungen nach einer Umbenennung zu sehen. Überprüfen Sie dieses Beispiel

Zuerst habe ich ein neues Git Repo erstellt

94:workspace augusto$ mkdir gittest
94:workspace augusto$ cd gittest/
94:gittest augusto$ git init
Initialized empty Git repository in /Volumes/Data/dev/workspace/gittest/.git/

Dann erstellte eine Datei in Ordner / Test

94:gittest augusto$ mkdir folder
94:gittest augusto$ vi folder/test
94:gittest augusto$ git add folder/test
94:gittest augusto$ git commit -am "added file"
[master (root-commit) 7128f82] added file
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 folder/test

Dann wurde die Datei in den neuen Ordner / Test verschoben

94:gittest augusto$ mkdir newfolder
94:gittest augusto$ mv folder/test newfolder/
94:gittest augusto$ git add newfolder/test 
94:gittest augusto$ git commit -am "moved/renamed file"
[master 4da41f5] moved/renamed file
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename {folder => newfolder}/test (100%)

Und git log --follow newfolder/testzeigt den vollständigen Verlauf an (ich habe den Parameter -p hinzugefügt, um weitere Informationen anzuzeigen, z. B. den Pfad).

94:gittest augusto$ git log --follow -p newfolder/test 
commit 4da41f5868ab12146e11820d9813e5a2ac29a591
Author: Augusto Rodriguez <[email protected]>
Date:   Sat Aug 20 18:20:37 2011 +0100

    moved/renamed file

diff --git a/folder/test b/newfolder/test
similarity index 100%
rename from folder/test
rename to newfolder/test

commit 7128f8232be45fd76616f88d7e164a840e1917d5
Author: Augusto Rodriguez <[email protected]>
Date:   Sat Aug 20 18:19:58 2011 +0100

    added file

diff --git a/folder/test b/folder/test
new file mode 100644
index 0000000..3b2aed8
--- /dev/null
+++ b/folder/test
@@ -0,0 +1 @@
+this is a new file

Ich hoffe das hilft!

Augusto
quelle
Hallo! Bitte überprüfen Sie die aktualisierte Antwort. Ich habe ein Beispiel hinzugefügt, wie Sie die Änderungen verfolgen können.
Augusto
2

Wenn Sie PowerShell verwenden, können Sie diesen Befehl von Ihrem Projektstamm aus ausführen und den Inhalt der Webanwendung dort platzieren.

Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
Nick
quelle
1

Ja, Sie können die Dateien einfach verschieben. Sie müssen git jedoch mitteilen, dass die alten Dateien im Webapp-Ordner verschwunden sind, dh, git muss den Index der fertigen / festgeschriebenen Dateien aktualisieren.

Sie können also verwenden git add -A ., um git auf alle Änderungen aufmerksam zu machen, oder verwenden git mv <files>, um git anzuweisen, die Verschiebung selbst durchzuführen. Siehe die git mv manpage .

--aktualisieren.

Sie haben bemerkt, dass Sie dachten ".. git handhabt einen Zug oder eine Umbenennung nicht wirklich .." - Ich war zuerst auch verwirrt und hatte die Funktionsweise des Index nicht vollständig verstanden. Einerseits sagen die Leute, dass git nur Schnappschüsse macht und keine Umbenennungen verfolgt, aber dann werden Sie beim Aktualisieren .gitignoreoder bei mveiner Datei usw. als "fehlgeschlagen" eingestuft. Dieser "Fehler" ist eine Verwirrung über die Funktionsweise des Index.

Meine Visualisierung ist, dass der Index- / Staging-Bereich ein Ort wie eine Storyboard-Wand ist, an dem Sie eine Kopie Ihrer neuesten und besten "fertigen" Datei einschließlich ihres Pfads (unter Verwendung git add) platzieren, und es ist diese Kopie, die festgeschrieben wird. Wenn Sie diese Kopie nicht von der Storyboard-Wand (dh git rm) entfernen, wird sie von git weiterhin festgeschrieben, und es herrscht große Verwirrung (siehe viele SO-Fragen ...). Der Index wird mergein ähnlicher Weise auch von git während s verwendet

Philip Oakley
quelle
1

Unter Windows mit Bash hat Folgendes funktioniert:

git mv /c/REPO_FOLDER/X_FOLDER/Y_FOLDER/Z_FOLDER/* /c/REPO_FOLDER/X_FOLDER/Y_FOLDER
arupjbasu
quelle
0

Ja, git verfolgt die Änderungen in früheren Inhalten. Es werden Hashes des Dateiinhalts verwendet, sodass es sich unabhängig davon, wo sie sich in der Verzeichnisstruktur befinden, um dieselbe Datei handelt.

Daher sollten Sie die Verschiebung in einem Commit durchführen und dann alle Änderungen in einem nachfolgenden Commit korrigieren. Dadurch kann Git die Umleitung mit maximaler Effizienz bestimmen und hat keinen Einfluss auf die im Repository gespeicherte Datenmenge (da Sie diese Änderungen sowieso vornehmen würden).

AlBlue
quelle