2013-08-02 11 views
7

Ich habe eine lokale Git Repo, die ich aus einer SVN-Repo erstellt:Wie ein Git Repo mit allen Zweigen und Tags von Refs/Fernbedienungen zu klonen?

$ git svn clone -s svn:... 

Ich habe dann eine Backup-Remote und schob alles, um es:

$ git remote add backup [email protected]:mybackup.git 
$ git push --mirror backup 

Nun, wenn ich versuche, von zu klonen Mein Backup, es fehlen alle SVN Tags und Zweige.

$ git clone [email protected]:mybackup.git 
$ cd mybackup 
$ git branch -a 
* master 
    origin 
    remotes/origin/HEAD -> origin/master 
    remotes/origin/master 

Wie klone ich das Repo mit allen Tags und Verzweigungen?

Der einzige Weg, die ich gefunden habe ist die repo spiegeln:

$ git clone --mirror [email protected]:mybackup.git 

Dies schafft ein lokales mybackup.git-Verzeichnis, das über all tags/branches weiß (I Tabulatorvervollständigung kann die gesamte Liste zu bekommen), aber es ist kein gültiges verwendbares Repo:

$ git checkout mytag 
fatal: This operation must be run in a work tree 

Es muss Befehlszeilenoption geben, um den Repo wirklich mit allen Zweigen/Tags zu klonen ???

Ich habe mehrere verwandte Fragen hier gefunden, aber keine der Antworten funktioniert für diese Situation. Ich nehme an, der Unterschied ist, dass mein Klon mit --mirror erstellt wurde?

+0

Weitere Informationen: Ich kann sehen, dass die Zweige, die mein neuer Klon kennt, im 'refs/heads'-Verzeichnis meines Backups sind, während diejenigen, die ich nicht finde, in' refs/remotes' sind (seltsam, 'backup' ist auch in 'refs/remotes' - Nebeneffekt des' Spiegels' nehme ich an. –

Antwort

7

Es gibt zwei Möglichkeiten, um Ihren Befehl git clone --mirror [email protected]:mybackup.git Der, den ich dieses eine gefunden zu verbessern, zu wissen, dass Ihr Befehl ein mybackup.git Verzeichnis erstellt:

mkdir mybackup 
mv mybackup.git mybackup/.git 
cd mybackup 
git init 

Dort haben Sie ein vollständiges Arbeitsverzeichnis.https://git.wiki.kernel.org/index.php/Git_FAQ#How_do_I_clone_a_repository_with_all_remotely_tracked_branches.3F

git clone --mirror [email protected]:mybackup.git mybackup/.git 
cd mybackup 
git config --bool core.bare false 

Ich denke, beide sind gleichwertig bis zur letzten Zeile, und wahrscheinlich der Befehl git config --bool core.bare false ist sauberer als ein git init tun:

Alternativ, wie Sie auf dieser Seite lesen können.

Alles zusammenfassend auf die Tatsache, dass --mirror ein bloßes Repository und kein funktionierendes Repository erstellt, also müssen Sie es in ein funktionierendes Repository transformieren.

+0

Danke. Ich ziehe meine Lösung zurück, denn diese scheint zu funktionieren und einfacher zu sein. Sie müssen dann nur SVN in den neuen Repo einhängen und fertig. –

2

Nach viel suchen, fand ich endlich eine Antwort ...

git clone [email protected]:mybackup.git newdirectory 
cd newdirectory 
git fetch origin refs/remotes/*:refs/remotes/* 
git init 

Jetzt ein git branch -a alle meine entfernten Niederlassungen zeigt.

Ich bin mir nicht sicher, ob die git init hier benötigt wird oder ob nur in der git init --bare Variante (siehe die auskommentierten Zeilen im Shell-Skript unten) benötigt wird, aber ich bin sicher, dass es nichts schadet, es zu verlassen wenn es nicht benötigt wird.

Mein Hauptgrund dafür ist, meine SVN Tags/Zweige zu kopieren, anstatt nur master auf SVN trunk zeigen und ohne die gesamte SVN Geschichte analysieren zu müssen (sehr langsam für Projekte mit viel Geschichte, Tags und Zweige). So kopieren über meine SVN Info:

git svn init -s "svn://mysvnhost/mysvnrepo/myproject" 
git svn fetch 
git checkout master 

Um diesen Prozess zu beschleunigen, habe ich ein Shell-Skript:

#!/bin/sh 
# 
# git-clone-svn-based-repo.sh: 
# 
# clones a git-svn based repo including all SVN commits without pounding 
# the SVN server for hours (just a quick refresh taking seconds) 
# 

usage_exit() 
{ 
    echo "Usage: $0 <git-repo> <dest-directory> <svn-project>" 
    exit 1 
} 


if ! git ls-remote "$1" > /dev/null 2>&1 
then 
    echo "No git repo found at: $1" 
    usage_exit 
fi 

if [ -r "$2" ] 
then 
    echo "File or directory already exists: $2" 
    usage_exit 
fi 

if ! svn ls "$3" 2> /dev/null | grep -q trunk 
then 
    echo "No SVN project found at: $3" 
    usage_exit 
fi 

# create new bare git repo 
mkdir "$2" 
cd "$2" 
git init --bare .git 

# fetch everything from backup 
git remote add backup "$1" 
git fetch backup refs/remotes/*:refs/remotes/* 
git fetch backup refs/heads/*:refs/heads/* 
git fetch backup refs/tags/*:refs/tags/* 

# disable future fetching from backup 
# setup to push all remote refs to backup by default 
git config remote.backup.fetch do_not_fetch_from_backup 
git config remote.backup.push '+refs/remotes/*:refs/remotes/*' 

# initialize git repo to usable (non-bare) state 
git init 

# update SVN references 
git svn init -s "svn://svn.crc-corp.com/carsrepository/$3" 
git config svn.authorsfile $HOME/projects/authors.txt 
git svn fetch 

# update master to current SVN trunk 
git checkout master 
git svn rebase 
# update ignore properties from SVN 
git svn show-ignore >> .git/info/exclude 

Um eine solche Sicherung aus einem bestehenden git SVN-Repo zu erstellen:

# create a bare backup repo at [email protected]:mybackup.git 
git remote add backup [email protected]:mybackup.git 
git config remote.backup.fetch do_not_fetch_from_backup 
git config remote.backup.push '+refs/remotes/*:refs/remotes/*' 
git push backup