Git-Historie beim Auslagern von Maven-Modulen beibehalten


03.08.2016 von

https://www.iteratec.de/fileadmin/Bilder/News/iteratec_logo.png https://www.iteratec.de/fileadmin/Bilder/News/iteratec_logo.png iteratec GmbH

In unserem Projekt Team arbeiten wir an einer Portallandschaft, die sich aus immer kleiner werdenden Services zusammensetzt. Dabei gibt es einige Funktionalitäten, die für mehrere Services interessant sind. Diese wollen wir in einem separaten Repository als geteilte Libraries verwalten. Die betroffenen Klassen habe ich in dedizierte Maven-Module verschoben. Für diese habe ich via gitlab bereits ein neues Repository angelegt. Ich könnte jetzt den Code einfach in das neue Repository kopieren, committen und dann pushen. Dadurch würde aber die Git-Historie für diese Teile verloren gehen. Hier werde ich zeigen, wie man das git filter-branch command nutzen kann, um gezielt die zu den Modulen gehörenden Commits zu extrahieren. 

Als erstes checken wir das Ziel-Repository in unserem Workspace aus.

cd workspace
git clone git@iteragit.iteratec.de:microservice-framework.git

Dann erstellen wir eine Kopie unseres Quell-Repositorys, in der wir alle nicht zu den Modulen gehörenden Commits herausfiltern werden. Danach welchseln wir in dieses neue Verzeichnis.

git clone login login-copy
cd login-copy

Ich will die Git Tags aus dem Quell-Repository nicht übernehmen. Diese enthalten bei uns Referenzen auf gelieferte Releases, Builds unseres CI Servers sowie Referenzen auf verlassene Feature-Branches. Da wir keine der Informationen im neuen Repository benötigen, lösche ich einfach alle Tags.

git tag | xargs git tag -d

Jetzt wird es spannend. Mit nur einem Befehl wird Git sämtliche nicht zu den angegebenen Modulen gehörenden Commits entfernen.

git filter-branch -f --prune-empty --index-filter \
'git rm --ignore-unmatch --cached -r -q -- . ; git reset -q $GIT_COMMIT -- mf-* microservices-*' -- --all

Was geschieht hier technisch? Git durchläuft die gesamte Historie und wendet auf jeden Commit einen von uns definierten Filter an. Hier werden nur Commits beibehalten, die Module beginnend mit mf- oder microservices- verändern. Diese Commits selbst werden dabei so verändert, dass sie nur noch die Änderungen auf diese Files beinhalten. Ich bekomme also einen Ausschnitt der Historie, so als wären diese Teile von Anfang an separat entwickelt worden. Ziemlich praktisch. 

Tipp: In meinem Fall blieben sehr viele leere Merge-Commits in der neuen Historie zurück. Hier hilft folgendes optionales Kommando:

git rebase --root --committer-date-is-author-date HEAD

Weiter im Text. Ich habe mir das Ergebnis mit Git Log angesehen. Nun will ich diese Historie in mein neues Repository mergen. Dafür füge ich zunächst das veränderte Quell-Repository als Upstream-Repo zu unserem Ziel-Repository hinzu.

cd ../microservice-framework
git remote add source ../login-copy
git remote update

Jetzt kann ich den Branch des anderen Respositorys in meinen aktuellen mergen.

git merge source/develop

Dann pushe ich meine Änderungen zum Server.

git push -u origin master

Zum Schluss entferne ich den Source Upstream und lösche das kopierte Verzeichnis.

git remote rm source
rm -rf ../login-copy

Die Git-Historie ist extrem nützlich. Sie ermöglicht es im Nachhinein nachzuvollziehen, welche Änderungen gemacht wurden und warum. Daher sollte ein Entwickler, wann immer möglich, die Historie bewahren. Ich hoffe, ich konnte weiterhelfen. 

Happy Hacking!

Diesen Artikel bewerten
 
 
 
 
 
 
 
0 Bewertungen (0 %)
Bewerten
 
 
 
 
 
 
1
5
0
 

Artikel im Warenkorb:

0