Git Repository in Subrepository verwandeln

Auf mactricks.de gibt es eine schöne Anleitung um aus einem Teil eines Git Repositories ein Subrepository zu erzeugen. Allerdings gibt es mit der Variante ein Problem. Wenn man das ganze mehr als zwei oder dreimal machen möchte, wird es mit der Zeit nervig all diese Befehle einzugeben.

Aus diesem Grund habe ich für das Extrahieren eines Subprojektes aus einem Git Repository ein Skript geschrieben:

#!/bin/sh
# extractSubproject <orignal repopath> <new repopath> <subfolder> <new remote (optional)>

# clone repository
git clone --no-hardlinks $1 $2

# extract subproject
cd $2
git filter-branch --subdirectory-filter $3 HEAD
git reset --hard
git remote rm origin
rm -r .git/refs/original/
git reflog expire --expire=now --all
git gc --aggressive
git prune

# Add optional remote and push
if [ "$4" != "" ]; then
git remote add origin $4
  git push origin master
fi

Heruntergeladen werden kann sich das Skript auch unter https://github.com/seeseekey/archive/blob/master/Bash/Git/extractSubproject.sh.

Bashskript zur Aktualisierung von Repositories

Bei mir auf der Festplatte liegen einige Quelltext in Form von Subversion und Git Repositories. Da es mühsam wäre jedes einzelne Repository zu aktualisieren, habe ich mir ein kleines Skript geschrieben, welches diese Aufgabe abnimmt:

#bash

#Update repositories script
#Copyright (c) 2012 by seeseekey <>
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.

SCRIPTPATH=$(pwd);

#Git
for directory in `find $SCRIPTPATH -name ".git" -type d`;
do
  echo $directory;
  cd $directory/..;
  git pull;
done

#Subversion
for directory in `find $SCRIPTPATH -name ".svn" -type d`;
do
  echo $directory;
  cd $directory/..;
  svn update;
done

#Pfad zurücksetzen
cd $SCRIPTPATH;

Das Skript selbst steht dabei unter GPLv3 und kann auch direkt auf Github unter https://github.com/seeseekey/archive/blob/master/Bash/Git/updateRepositories.sh gefunden werden.

Dateien von einem in ein anderes Git Repostory überführen

Man nehme die Git Repositories A und B:

A
|_.git
|_file01.txt
|_file02.txt
|_file03.txt

B
|_.git
|_Zeugs
|_image01.txt
|_image02.txt
|_image03.txt

Im Verzeichnisbaum sieht das ganze dabei so aus:

*
|_A
|_B

Nun soll der Inhalt des Repositories B im Repository A landen. Wichtig hierbei ist das die History erhalten bleiben soll. Dazu legen wir in Repository A einen Branch an und laden das Repository B in diesen. Im Repository A öffnen wir eine Konsole und geben dort folgendes ein:

git remote add other ../B
git fetch other
git checkout -b tmpBranch other/master
git checkout master
git merge tmpBranch
git branch -d tmpBranch
git remote rm other
git push                           

Sollte es nach dem „merge tmpBranch“ zu Konflikten kommen, so müssen diese gelöst werden und das ganze dann mittels „git commit“ bzw. „git commit -a“ fixiert werden. Danach sieht das Repository dann so aus:

A
|_.git
|_Zeugs
|_file01.txt
|_file02.txt
|_file03.txt
|_image01.txt
|_image02.txt
|_image03.txt

Für Git Neulinge das ganze nochmal ein wenig genauer. Mittels „git remote add other ../B“ wird dem Repository A ein neuer Remote hinzugefügt. Die Daten aus diesem werden dann mittels „git fetch other“ geladen und anschließend werden diese „git checkout -b tmpBranch other/master“ in einen neuen Branch namens „tmpBranch“ gepackt.

Nun machen wir mit „git checkout master“ den Masterbranch wieder zum aktiven Branch und mergen den „tmpBranch“ mittels „git merge tmpBranch“ in den Masterbranch. Danach wird der „tmpBranch“ mittels „git branch -d tmpBranch“ gelöscht und der nicht mehr benötige Remote mittels „git remote rm other“ entfernt.

Nun wird das ganze noch mit „git push“ auf den Remote des Repositories gepusht und fertig ist die Überführung.

Weitere Informationen gibt es unter:
http://de.wikipedia.org/wiki/Git
http://progit.org/book/de/ch3-4.html
http://de.gitready.com/beginner/2009/01/25/branching-and-merging.html
http://stackoverflow.com/questions/1683531/how-to-import-existing-git-repository-into-another

Bestehendes Subversion Repository in Google Code importieren

Möchte man ein bestehendes Subversion Repository ín Google Code importieren so geht muss man im ersten Schritt auf seine Google Code Seite dort dann auf Source -> Browser und unten dann auf „reset this repository“ und dort klickt man dann den Punkt „Did you just start this project and do you want to ’svnsync‘ content from an existing repository into this project?“ an.

Danach ist das Repository auf Revision 0 zurückgesetzt worden. Nun wird in der Konsole mittels

svnsync init –username YOURUSERNAME https://YOURPROJECT.googlecode.com/svn file:///path/to/localrepos

das Projekt initialisiert und mittels

svnsync sync –username YOURUSERNAME https://YOURPROJECT.googlecode.com/svn

die Synchronisation begonnen werden. Das ganze kann dabei durchaus ein paar Stunden dauern. Ausgefüllt sieht das ganze dann z.B. so aus:

svnsync init –username seeseekey https://invertika.googlecode.com/svn https://invertika.svn.sourceforge.net/svnroot/invertika

svnsync sync –username seeseekey https://invertika.googlecode.com/svn

Sollte die Synchronisation zwischendurch unterbrochen werden so ist das kein Problem da sie jederzeit wieder gestartet werden kann und bei der letzten synchronisierten Revision anfängt.

SVN-Begrifflichkeiten

Wenn man von einem anderen Version Control System auf SVN wechselt bzw. zum ersten Mal ein VCS benutzt so wird man über einige neue Begriffe stolpern welche ich hier erklären möchte.

Repository
Das Repository bezeichnet das Archiv der Quelltexte (oder was auch immer man mittels SVN verwaltet). In dem Repository befinden sich sämtliche Revisionen des Projektes.

trunk, branch und tag
In einem SVN Repository gibt es drei Verzeichnisse names trunk, branch und tag. Im Verzeichnis trunk befindet sich die aktuelle Entwicklungszweig. Das branch Verzeichnis enthält Abspaltungen z.B. um größere Änderungen zu testen. Möchte man solche Änderung machen erzeugt man aus dem trunk einen neuen Branch. Im tag Verzeichnis können die Releaseversionen „gelagert“ werden.

Revision
Eine Revision bezeichnet die Version des Repostiories bzw. einer Datei in ebend diesem. Wenn das Repository z.B. die Revision 53 hat und man fügt eine neue bzw. ändert eine bestehende Datei des Repository so steigt deren Revision um 1. Die neue Revision ist dann 54.

Checkout
Im Gegensatz zu VC Systemen wie Visual SourceSafe bezeichnet ein Checkout bei SVN das holen einer Arbeitskopie des Repository vom Server.

Lock
Ein Lock benötigt man dann wenn man eine Datei bearbeiten möchte. Dadurch wird die Datei gesperrt, so das andere Nutzer sie nicht bearbeiten können (je nach Einstellung). Möchte man die bearbeitete Datei nun zurück in Reposity bringen so macht man ein Commit.

Commit
Mit einem Commit werden die veränderten Dateien wieder ins Repository hochgeladen.

Weitere Informationen unter:
http://de.wikipedia.org/wiki/Subversion_(Software)