我有一个必须承诺的中央SVN存储库,但我对git很感兴趣(就像我认识的任何其他开发人员一样)。这个案子众所周知。
然后我读了一下git-svn并尝试了一下。由于我不需要完整的历史,仅仅两个月左右,我就是这样:
git svn clone -r 34000 -s https://svn.ourdomain.com/svn/repos/Project/SubProject
SubProject像往常一样拥有子目录trunk
,tags
和branches
。大。
然后,为了得到最后一次修订,我做了
git svn rebase
稍后有些下载,很棒。最后修订,日志等等,好的,现在我将切换到我的功能分支。
$ git branch
* master
$ git branch -r
trunk
$ git branch -a
* master
remotes/trunk
问题是:我的分支在哪里?我做错了什么吗?我怎么做才能在新的git仓库中获得我的分支机构?
编辑:我刚刚发现git svn fetch
会这样做。但它会得到所有修改,这是我不喜欢的。
答案 0 :(得分:72)
你需要几个步骤。
提供正确的trunk,branches和tags文件夹名称并获取svn repo:
git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo
git svn fetch
由于svn中的标签是真正的分支,因此请从标记分支创建git标记:
git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags | cut -d / -f 3- |
while read ref
do
echo git tag -a $ref -m 'import tag from svn'
done
删除标记分支
git for-each-ref --format="%(refname:short)" refs/remotes/tags | cut -d / -f 2- |
while read ref
do
echo git branch -rd $ref
done
由于上一步中标记的标记指向提交“创建标记”,因此我们需要派生“真实”标记,即“创建标记”提交的父级。
git for-each-ref --format="%(refname:short)" refs/tags |
while read ref
do
tag=`echo $ref | sed 's/_/./g'` # give tags a new name
echo $ref -\> $tag
git tag -a $tag `git rev-list -2 $ref | tail -1` -m "proper svn tag"
done
我们现在要做的就是删除旧标签。
答案 1 :(得分:12)
这与nicolai.rostov上面的回答相同,但我只是更改了refs路径
我将refs/remotes/tags
替换为refs/remotes/origin/tags
我将git版本2.1.1
用于cygwin
终端。
$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/origin/tags \
| while read BRANCH REF
do
TAG_NAME=${BRANCH#*/}
BODY="$(git log -1 --format=format:%B $REF)"
echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2
git tag -a -m "$BODY" $TAG_NAME $REF^ &&\
git branch -r -d $BRANCH
done
答案 2 :(得分:7)
你说你的结账时没有得到你的分支。
这可能是您的svn repo布局的问题。
'标准布局'是:
branches/
tags/
trunk/
如果您的布局如下:
branches/user1/
branches/user2/
然后,当你执行git svn fetch / clone时,你将失去你的分支。
要解决此问题,您应该提供参数
--branches=branches/*/*
来git clone。
答案 3 :(得分:5)
如果你想在从svn导入后进行git分支时看到你的分支,你应该使用ruby脚本svn2git (and git2svn)
它比git svn clone更好,因为如果你在svn中有这个代码:
trunk
...
branches
1.x
2.x
tags
1.0.0
1.0.1
1.0.2
1.1.0
2.0.0
git-svn
将通过提交历史记录来构建新的git仓库 它将所有分支和标签导入为远程SVN分支,而您真正想要的是git-native本地分支和git标记对象。 因此,在导入此项目后,您将获得:
$ git branch
* master
$ git branch -a
* master
1.x
2.x
tags/1.0.0
tags/1.0.1
tags/1.0.2
tags/1.1.0
tags/2.0.0
trunk
$ git tag -l
[ empty ]
完成项目svn2git
后,您将获得此项目:
$ git branch
* master
1.x
2.x
$ git tag -l
1.0.0
1.0.1
1.0.2
1.1.0
2.0.0
答案 4 :(得分:4)
我写了一个脚本来帮助您根据需要进行迁移。该脚本并不完美,但是我希望这可以对您有所帮助:
有关更多信息,您可以访问:https://github.com/MPDFT/svn-to-git
#!/bin/bash
####### Project name
PROJECT_NAME="myproject"
EMAIL="mycompany.com"
###########################
####### SVN
# SVN repository to be migrated
BASE_SVN="http://svn.mycompany.com/svn/repo/sistemas/myproject"
# Organization inside BASE_SVN
BRANCHES="branches"
TAGS="tags"
TRUNK="trunk"
###########################
####### GIT
# Git repository to migrate
GIT_URL="https://git.mycompany.com/git/repo/sistemas/myproject.git"
###########################
#### Don't need to change from here
###########################
# Geral Configuration
ABSOLUTE_PATH=$(pwd)
TMP=$ABSOLUTE_PATH/"migration-"$PROJECT_NAME
# Branchs Configuration
SVN_BRANCHES=$BASE_SVN/$BRANCHES
SVN_TAGS=$BASE_SVN/$TAGS
SVN_TRUNK=$BASE_SVN/$TRUNK
AUTHORS=$PROJECT_NAME"-authors.txt"
echo '[LOG] Starting migration of '$SVN_TRUNK
echo '[LOG] Using: '$(git --version)
echo '[LOG] Using: '$(svn --version | grep svn,)
mkdir $TMP
cd $TMP
echo
echo '[LOG] Getting authors'
svn log -q $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@"$EMAIL">"}' | sort -u >> $AUTHORS
echo
echo '[RUN] git svn clone --authors-file='$AUTHORS' --trunk='$TRUNK' --branches='$BRANCHES' --tags='$TAGS $BASE_SVN $TMP
git svn clone --authors-file=$AUTHORS --trunk=$TRUNK --branches=$BRANCHES --tags=$TAGS $BASE_SVN $TMP
echo
echo '[LOG] Getting first revision'
FIRST_REVISION=$( svn log -r 1:HEAD --limit 1 $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $1); sub(" $", "", $1); print $1}' )
echo
echo '[RUN] git svn fetch -'$FIRST_REVISION':HEAD'
git svn fetch -$FIRST_REVISION:HEAD
echo
echo '[RUN] git remote add origin '$GIT_URL
git remote add origin $GIT_URL
echo
echo '[RUN] svn ls '$SVN_BRANCHES
for BRANCH in $(svn ls $SVN_BRANCHES); do
echo git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
done
git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/origin/tags | grep -v "@" | cut -d / -f 3- |
while read ref
do
echo git tag -a $ref -m 'import tag from svn'
git tag -a $ref -m 'import tag from svn'
done
git for-each-ref --format="%(refname:short)" refs/remotes/origin/tags | cut -d / -f 1- |
while read ref
do
git branch -rd $ref
done
echo
echo '[RUN] git push'
git push origin --all --force
git push origin --tags
echo 'Sucessufull.'
答案 5 :(得分:0)
我遇到了同样的问题 - 当我指定修订时,标签和分支都丢失了:
if(funcs.length()==1){
what? = funcs[0].apply(this.obj);
return what?
}
修复方法是指定一系列修订版$ git svn clone -r 34000 -s https://...
:
-r 34000:HEAD
答案 6 :(得分:0)
要将新的 SVN 分支拉入本地 Git-SVN 存储库,我找到了一种简单的方法,不需要编辑任何配置文件等。
您只需要要添加到本地 git-svn 存储库的分支中最后一次提交的修订号。
如果您有新分支的最新 SVN 签出并安装了 TortoiseSVN,您可以右键单击此文件夹并使用“TortoiseSVN / 显示日志”。
记下最上面的提交(例如 45065)。
现在在 Git Bash 中使用以下命令:
git svn fetch -r45065
注意:您需要将编号 45065
替换为您的提交编号。
git 现在会将新的远程分支拉入您的本地存储库。
然后您可以通过创建本地分支来检查它。我正在使用 Git 扩展来检查新分支,使用“远程分支”和选项“使用名称创建本地分支:...”。
提示:您可以从本地分支名称中删除“origin/”前缀,因为这样可以避免警告“refname 'origin/V8.0' is ambiguous。”。