我有一个我从svn repo创建的本地git仓库:
$ git svn clone -s svn:...
然后我创建了一个备份遥控器并将所有内容推送到它:
$ git remote add backup git@myhost:mybackup.git
$ git push --mirror backup
现在,当我尝试从我的备份克隆时,它缺少所有svn标记和分支。
$ git clone git@myhost:mybackup.git
$ cd mybackup
$ git branch -a
* master
origin
remotes/origin/HEAD -> origin/master
remotes/origin/master
如何使用所有标签和分支克隆存储库?
我找到的唯一方法是镜像回购:
$ git clone --mirror git@myhost:mybackup.git
这会创建一个本地mybackup.git
目录,它知道所有标记/分支(我可以使用制表符完成来获取整个列表)但它不是有效的可用存储库:
$ git checkout mytag
fatal: This operation must be run in a work tree
必须有命令行选项才能真正克隆带有所有分支/标记的仓库???
我在这里找到了几个相关的问题,但没有一个答案适用于这种情况。我假设不同之处在于我的克隆是使用--mirror
创建的?
答案 0 :(得分:9)
有两种方法可以改善您的命令git clone --mirror git@myhost:mybackup.git
我找到的就是这个,知道你的命令创建了一个mybackup.git目录:
mkdir mybackup
mv mybackup.git mybackup/.git
cd mybackup
git init
在那里,你有一个完整的工作目录。
或者您可以在此页面上阅读:https://git.wiki.kernel.org/index.php/Git_FAQ#How_do_I_clone_a_repository_with_all_remotely_tracked_branches.3F
git clone --mirror git@myhost:mybackup.git mybackup/.git
cd mybackup
git config --bool core.bare false
我认为两者都等同于最后一行,并且命令git config --bool core.bare false
可能比执行git init
更清晰。
这一切总结为--mirror创建一个裸存储库而不是工作存储库这一事实,因此您需要将其转换为工作存储库。
答案 1 :(得分:3)
经过大量的搜索,我终于找到了答案......
git clone git@myhost:mybackup.git newdirectory
cd newdirectory
git fetch origin refs/remotes/*:refs/remotes/*
git init
现在git branch -a
显示了我的所有远程分支。
我不确定此处是否需要git init
,或者仅在git init --bare
变体中是否需要它(请参阅下面shell脚本中注释掉的行),但我确信如果不需要,就不会有任何损失。
我这样做的主要原因是让我的SVN标签/分支被复制而不是只有master
指向SVN trunk
并且不必解析整个SVN历史记录(项目非常慢)有很多历史,标签和分支)。所以复制我的SVN信息:
git svn init -s "svn://mysvnhost/mysvnrepo/myproject"
git svn fetch
git checkout master
为了加快这个过程,我创建了一个shell脚本:
#!/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
为了从现有的git SVN repo创建这样的备份:
# create a bare backup repo at git@myhost:mybackup.git
git remote add backup git@myhost:mybackup.git
git config remote.backup.fetch do_not_fetch_from_backup
git config remote.backup.push '+refs/remotes/*:refs/remotes/*'
git push backup