ubuntuusers.de

Von SVN zu Git mit Submodules - Wie geht's wirklich?

Status: Ungelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

NicTheQuick

Anmeldungsdatum:
22. Oktober 2007

Beiträge: 144

Hallo Leute,

ich brauche Hilfe mit GIT und seinen Submodules. Folgendes Szenario: Firmen-intern haben wir ein SVN, das für die Entwicklung miteinander verwendet wird. Es werden Products für Plone entwickelt. Das heißt wir haben ganz einfach im trunk unseres SVNs verschiedene Ordner, die jeweils ein Product darstellen:

<SVN-Pfad>/trunk
 |-- ProductA
 |-- ProductB
 |-- ...
 .
 .

Das ganze soll jetzt auf das Firmen-externe und per VPN- und ssh-gesicherte GIT des Kunden gespielt werden. Das funktioniert bisher so, dass einfach der komplette trunk-Ordner vom SVN in das GIT gepusht wird. Soweit, so gut. Ein weiterer Server im Kunden-internen Netz kümmert sich nun darum bestimmte Product-Sources zu kompilieren. Dafür greift er auf das GIT zu. Das Problem ist jetzt, dass er immer nur das komplette GIT auschecken kann und nicht einfach nur das zu kompilierende Product. Deswegen habe ich mir gedacht ich probiere mich mal mit den GIT-Submodules testweise auf meinem lokalen Rechner. Ich habe also den trunk-Ordner aus dem SVN ausgecheckt und dann in jedem Product-Ordner ein 'git init' aufgerufen. Anschließend hab ich in einem weiteren Ordner außerhalb des trunk ein weiteres GIT angelegt, dass als Parent für die einzelnen Product-GITs fungieren soll. Hier die Vorgehensweise:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
/tmp/git/trunk/ProductA$ git init
Initialisierte leeres Git-Projektarchiv in /tmp/git/trunk/ProductA/.git/
/tmp/git/trunk/ProductA$ echo ".svn*" > .gitignore
/tmp/git/trunk/ProductA$ git add .
/tmp/git/trunk/ProductA$ git commit -m "Initial commit of ProcuctA"
[master (Basis-Version) 29bb36f] Initial commit of ProcuctA
 2 files changed, 2 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 README.txt
nicolas@tp-w530:/tmp/git/trunk/ProductA$ git clone --bare . /tmp/git/origin/ProductA.git
Klone in bloßes Projektarchiv '/tmp/git/origin/ProductA.git'...
Fertig.
/tmp/git/trunk/ProductA$ git remote add origin /tmp/git/origin/ProductA.git
/tmp/git/trunk/ProductA$ git config branch.master.remote origin
/tmp/git/trunk/ProductA$ git config branch.master.merge refs/heads/master
/tmp/git/trunk/ProductA$ git config push.default current
/tmp/git/trunk/ProductA$ git push
Everything up-to-date

Das selbe dann noch für ProductB und wir haben schon mal für beide Products ein GIT angelegt und einen bare-clone davon. Dann habe ich das Eltern-GIT angelegt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/tmp/git/super$ echo ".svn*" > .gitignore
/tmp/git/super$ git add .
/tmp/git/super$ git commit -m "Initial commit of empty superproject."
[master (Basis-Version) 55296ba] Initial commit of empty superproject.
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
/tmp/git/super$ git clone --bare . /tmp/git/origin/super.git
Klone in bloßes Projektarchiv '/tmp/git/origin/super.git'...
Fertig.
/tmp/git/super$ git remote add origin /tmp/git/origin/super.git
/tmp/git/super$ git config branch.master.remote origin
/tmp/git/super$ git config branch.master.merge refs/heads/master
/tmp/git/super$ git submodule add /tmp/git/origin/ProductA.git/
Klone nach 'ProductA'...
Fertig.
/tmp/git/super$ git submodule add /tmp/git/origin/ProductB.git/
Klone nach 'ProductB'...
Fertig.
/tmp/git/super$ git submodule foreach 'git config push.default current'
Betrete 'ProductA'
Betrete 'ProductB'
/tmp/git/super$ git commit -m "Commit submodules."
[master b91de18] Commit submodules.
 3 files changed, 8 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 ProductA
 create mode 160000 ProductB
/tmp/git/super$ git config push.default current
/tmp/git/super$ git push
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 426 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To /tmp/git/origin/super.git
   55296ba..b91de18  HEAD -> master
/tmp/git/super$ ll
insgesamt 28
drwxrwxr-x 5 nicolas nicolas 4096 Nov 11 10:40 ./
drwxrwxr-x 5 nicolas nicolas 4096 Nov 11 10:35 ../
drwxrwxr-x 9 nicolas nicolas 4096 Nov 11 10:41 .git/
-rw-rw-r-- 1 nicolas nicolas    6 Nov 11 10:36 .gitignore
-rw-rw-r-- 1 nicolas nicolas  154 Nov 11 10:40 .gitmodules
drwxrwxr-x 2 nicolas nicolas 4096 Nov 11 10:40 ProductA/
drwxrwxr-x 2 nicolas nicolas 4096 Nov 11 10:40 ProductB/

Jetzt fangen die Probleme an. Jetzt sind ProductA und ProductB sozusagen zweimal da. Einmal in /tmp/git/super/Product* und einmal in /tmp/git/trunk/Product*. Welches soll ich nun verwenden? Eigentlich sollte es ja egal sein. Das, was ich zuerst angelegt habe, könnte ich theoretisch sogar löschen. Aber erst mal ein kleiner Test:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/tmp/git/trunk/ProductA$ echo "Zweite Zeile." >> README.txt 
/tmp/git/trunk/ProductA$ git status
# Auf Zweig master
# Änderungen, die nicht zum Eintragen bereitgestellt sind:
#   (benutze "git add <Datei>..." zum Bereitstellen)
#   (benutze "git checkout -- <Datei>..." um die Änderungen im Arbeitsverzeichnis zu verwerfen)
#
#	geändert:   README.txt
#
Keine Veränderungen hinzugefügt, die eingereicht werden könnten  (verwenden Sie »git add« und/oder »git commit -a«)
/tmp/git/trunk/ProductA$ git commit -a -m "Zweite Zeile hinzugefügt."
[master bf065d8] Zweite Zeile hinzugefügt.
 1 file changed, 1 insertion(+)
/tmp/git/trunk/ProductA$ cd ../../super/
/tmp/git/super$ git pull --recurse-submodules
Fetching submodule ProductA
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
Von /tmp/git/origin/ProductA
   29bb36f..bf065d8  master     -> origin/master
Fetching submodule ProductB
Already up-to-date.
/tmp/git/super$ cat ProductA/README.txt 
ProductA
/tmp/git/super/ProductA$ cat ../../trunk/ProductA/README.txt 
ProductA
Zweite Zeile.
/tmp/git/super/ProductA$ git pull origin
Aktualisiere 29bb36f..bf065d8
Fast-forward
 README.txt | 1 +
 1 file changed, 1 insertion(+)
/tmp/git/super/ProductA$ cat README.txt 
ProductA
Zweite Zeile.

Also irgendwie muss man bei jedem Submodule einzeln 'git pull origin' aufrufen. 'git pull' alleine reicht nicht und ein 'git pull --recurse-submodules origin' direkt auf dem Eltern-Project funktioniert genauso wenig. Aber das sind jetzt eher Kleinigkeiten. Später soll ja sowieso jedes Submodule einzeln ausgecheckt werden.

Das eigentliche Problem ist jetzt, wie ich dieses Parent-GIT in '/tmp/git/super' inklusive Submodules in das GIT auf den Kunden-Server kriege? Ich kann dort ja leider keine weiteren einzelnen GITs anlegen, sonst könnte ich das alles ja auch ohne Submodules machen. Ich habe da reinen git-shell-Zugriff. Kein ssh, mit dem ich mir beliebig neue GITs anlegen könnte. Wenn ich jetzt einfach den 'origin' vom Parent-GIT auf den Kundenserver umstelle und dann 'git push' aufrufe, dann werden die Submodules nicht übertragen und auschecken kann ich sie dann erst recht nicht. Was mache ich hier also falsch? Oder geht es nicht anders als für jedes Submodule ein einzelnes GIT anzulegen?

Vielen Dank schonmal und Grüße, NicTheQuick

TheDarkRose

Avatar von TheDarkRose

Anmeldungsdatum:
28. Juli 2010

Beiträge: 3459

Submodules sind sozusagen nur Referenzen wie das origin. Also nein

Beim Kunden für die benötigten Produkte ein Git-Repo geben lassen, fertig. Hier mit einen Git rumzueiern ist der falsche Ansatz. Sowieso schon im SVN kaputt (Ein SVN für alles.... nenene).

NicTheQuick

(Themenstarter)

Anmeldungsdatum:
22. Oktober 2007

Beiträge: 144

Ich dachte eben solche Submodules sind wirkliche Untermodule, die im Haupt-GIT integriert sind. Demnach war ich der Meinung, dass man sie auch im gesamten "pushen" kann, aber eben auch jedes einzelne Submodule für sich "pullen" kann. Bei SVN geht das wesentlich komfortabler. Da kann man jeden Ordner wie ein eigenes SVN auschecken und auch commiten. Man muss nicht immer das große ganze mitschleppen. Da verstehe ich gar nicht, was alle so an GIT haben. Ich finde SVN wesentlich komfortabler. 😉

Aber gut, schade. Dann müssen wir uns eben einzelne GITs anlegen lassen oder wir nehmen einen unserer ssh-fähigen Accounts mit bash, wo wir dann GITs anlegen.

Danke jedenfalls für die Antwort.

Antworten |