2015-09-25 23 views
12

bewegen Ich habe folgendes git StrukturGit: Submodule rekursiv (verschachtelt Submodule)

- git-repo a 
-- subdirectory 2015 
--- git-submodule b 
-- git-submodule c 
--- git-submodule d 

Ich mag würde die git Submodul c in den Ordner 2015. Ich weiß von „schmutzigen Wege“ bewegen, dies zu tun (dh beinhalten .git/config Modifizieren und Ändern gitdir in mehreren der Dateien im .git/modules-Dateien)

Vor kurzem las ich, dass git mv der Lage sein sollte, dies zu tun, das heißt, laufen

git mv c 2015/ 

Dies funktioniert für Repositories, in denen kein verschachteltes Submodul vorhanden ist (in meinem Fall d). Allerdings, wenn ich diesen Befehl auf meinem Verzeichnis laufen, bin ich Fehler wie

fatal: Not a git repository: d/../../.git/modules/c/modules/d 
fatal: 'git status --porcelain' failed in submodule 2015/c 

bekommen (beachten Sie, dieser Fehler auf einem git Status tritt auf, nachdem die oben erwähnte Bewegung ausführt)

Ist jemand bewusst ein clean-Methode, um diese Verschiebung durchzuführen (dh eine Methode, bei der Pfade in .git/modules-Dateien nicht manuell geändert werden müssen)?

Edit: (6/10/2015)

Meine aktuelle beste Lösung, die keine Änderungen an einem der git Konfigurationsdateien beinhalten nicht ist (zunächst sicherstellen, dass alle Änderungen an d begangen wurden und geschoben irgendwo)

rm c/d -rf 
git mv c 2015 
cd 2015/c 
git submodule update 

Edit: (8/10/2015)

Eine noch weniger aufdringlich Abhilfe

git mv c 2015 
rm 2015/c/d/.git 
cd 2015/c 
git submodule update 

Antwort

4

Wie von @VonC in https://stackoverflow.com/a/32924692/2274140 bestätigt, ist dies ein Fehler in Git mv.

Es gibt mehrere mögliche Problemumgehungen. Der einfachste erfordert keine komplexen Modifikationen von .git-Dateien (ich benutze diese seit dem Stellen der Frage). Es funktioniert wie folgt:

git mv c 2015 
rm 2015/c/d/.git 
cd 2015/c 
git submodule update 

es vorübergehend die .git Datei im d subsubmodule entfernt. Das Update des Git-Submoduls repariert diese .git-Datei erneut.

Für andere Abhilfen, die das temporäre Entfernen des gitdir vermeiden, finden Sie diese Antwort: https://stackoverflow.com/a/32924692/2274140

5

-Update 2017:

Die neueste Git 2.14.x/2,15 (Q4 2017) dokumentiert den Bug

Siehe commit c514167 (15. September 2017) von Heiko Voigt (hvoigt).
(Zusammengeführt durch Junio C Hamano -- gitster -- in commit 450b908 25 Sep 2017)

Wenn git-mv mit einem Submodul verwendet es, dass ein und aktualisiert Pfade für ihre Konfigurationen erkennen wird (.gitmodules, worktree und gitfile).
Dies funktioniert nicht für rekursive Submodule, in denen ein Benutzer das Stammmodul umbenennt.


Original-Antwort 2015

Getestet habe ich es nur mit git 2.6.0 (unter Windows), und Bewegen Submodule mit verschachtelten Submodule ihrer eigenen scheint problematisch zu sein:

C:\Users\vonc\prog\git\tests\submove>git clone --recursive a a1 
Cloning into 'a1'... 
done. 
Submodule '2015/b' (C:/Users/vonc/prog/git/tests/submove/b) registered for path '2015/b' 
Submodule 'c' (C:/Users/vonc/prog/git/tests/submove/c) registered for path 'c' 
Cloning into '2015/b'... 
done. 
Submodule path '2015/b': checked out 'dc18955ec7b9ad0c04245968e2474646e4d593b2' 
Cloning into 'c'... 
done. 
Submodule path 'c': checked out 'fb4722eaca17ac171b7a2c8c5a1ac1e697f0ee85' 
Submodule 'd' (C:/Users/vonc/prog/git/tests/submove/d) registered for path 'd' 
Cloning into 'd'... 
done. 
Submodule path 'c/d': checked out '73cd7b8ff82519720b2fcca18df5ed00dd618b71' 

ich habe:

a1 
    c 
    d 
    2015 
    b 

Wenn ich versuche und Submodul c in 2015 Unterordner verschieben:

C:\Users\vonc\prog\git\tests\submove\a1>git mv c 2015/c 

C:\Users\vonc\prog\git\tests\submove\a1>git status 
fatal: Not a git repository: d/../../.git/modules/c/modules/d 
fatal: 'git status --porcelain' failed in submodule 2015/c 

fand ich, dass ich 2 Dinge im verschachtelten Modul ändern müssen d:

1/manuell ändern .git/modules/c/modules/d/config den richtigen Weg zu injizieren:

git config -f .git/modules/c/modules/d/config core.worktree ../../../../../2015/c/d 
                      ^^^^ 

2/ändern d worktree:

git config -f .git/modules/c/modules/d/config core.worktree ../../../../../2015/c/d 

Von dort ein git status funktioniert, aber Ich mag (sicher sein) hinzufügen, um eine git submodule sync --recursive:

C:\Users\vonc\prog\git\tests\submove\a1>git submodule sync --recursive 
Synchronizing submodule url for '2015/b' 
Synchronizing submodule url for '2015/c' 
Synchronizing submodule url for '2015/c/d' 

Die git status tut das erwartete Ergebnis zeigen:

C:\Users\vonc\prog\git\tests\submove\a1>git status 
On branch master 
Your branch is up-to-date with 'origin/master'. 
Changes to be committed: 
    (use "git reset HEAD <file>..." to unstage) 

     modified: .gitmodules 
     renamed: c -> 2015/c 

ich hinzufügen und diese Änderung zu übernehmen:

C:\Users\vonc\prog\git\tests\submove\a1>git add . 

C:\Users\vonc\prog\git\tests\submove\a1>git commit -m "move sub c in 2015/c" 
[master 8289632] move sub c in 2015/c 
2 files changed, 1 insertion(+), 1 deletion(-) 
rename c => 2015/c (100%) 

C:\Users\vonc\prog\git\tests\submove\a1>gl 
* 8289632 - (HEAD -> master) move sub c in 2015/c (3 seconds ago) <VonC> 
* 7ebb8e0 - (origin/master, origin/HEAD) a with sub c (38 minutes ago) <VonC> 

ich jetzt, dass Repo klonen den Umzug war in der Tat richtig registriert zu überprüfen:

C:\Users\vonc\prog\git\tests\submove>git clone --recursive a1 a2 
Cloning into 'a2'... 
done. 
Submodule '2015/b' (C:/Users/vonc/prog/git/tests/submove/b) registered for path '2015/b' 
Submodule 'c' (C:/Users/vonc/prog/git/tests/submove/c) registered for path '2015/c' 
Cloning into '2015/b'... 
done. 
Submodule path '2015/b': checked out 'dc18955ec7b9ad0c04245968e2474646e4d593b2' 
Cloning into '2015/c'... 
done. 
Submodule path '2015/c': checked out 'fb4722eaca17ac171b7a2c8c5a1ac1e697f0ee85' 
Submodule 'd' (C:/Users/vonc/prog/git/tests/submove/d) registered for path 'd' 
Cloning into 'd'... 
done. 
Submodule path '2015/c/d': checked out '73cd7b8ff82519720b2fcca18df5ed00dd618b71' 

Wie Sie können sehen, c und c/d sind in der erwarteten 2015/ Unterordner:

C:\Users\vonc\prog\git\tests\submove>cd a2 

C:\Users\vonc\prog\git\tests\submove\a2>dir 2015\c 

Directory of C:\Users\vonc\prog\git\tests\submove\a2\2015\c 

03/10/2015 18:10 <DIR>   . 
03/10/2015 18:10 <DIR>   .. 
03/10/2015 18:10    29 .git 
03/10/2015 18:10    40 .gitmodules 
03/10/2015 18:10 <DIR>   d 
       2 File(s)    69 bytes 
       3 Dir(s) 23 656 910 848 bytes free 

C:\Users\vonc\prog\git\tests\submove\a2>dir 2015\c\d 

Directory of C:\Users\vonc\prog\git\tests\submove\a2\2015\c\d 

03/10/2015 18:10 <DIR>   . 
03/10/2015 18:10 <DIR>   .. 
03/10/2015 18:10    42 .git 
03/10/2015 18:10     3 d.txt 
       2 File(s)    45 bytes 
       2 Dir(s) 23 656 910 848 bytes free 
+0

, dass eine ganze Menge, wie meine aktuelle Problemumgehung klingt. Danke trotzdem. – BartBog

+0

@BartBog, das als optimierte und präzisere Problemumgehung klingt. Wenn das ein Fehler ist, glaube ich nicht, dass Sie eine bessere Antwort bekommen. – VonC

+0

Es ist in der Tat ein bisschen weniger schmutzig, da es keine manuelle Bearbeitung der Konfigurationsdateien beinhaltet, sondern bearbeitet die Arbeitsbäume mit Git-Befehlen. Trotzdem ist es ziemlich schwierig zu benutzen. Ich habe jetzt meine Frage aktualisiert, um auch meinen neuesten Workflow zu enthalten, der darin besteht, das Submodul d vor dem Umzug zu löschen (funktioniert ziemlich gut und erfordert keine komplexen Modifikationen) – BartBog