我阅读了Git手册、常见问题解答、Git-SVN速成课程等,他们都解释了这一点和那一点,但你找不到像这样的简单说明:

SVN存储库位于:svn://myserver/path/to/svn/repos

Git存储库位于:git://myserver/path/to/git/repos

git-do-the-magic-svn-import-with-history \
svn://myserver/path/to/svn/repos \
git://myserver/path/to/git/repos

我不希望它这么简单,也不希望它是一个命令。但我确实希望它不要试图解释任何事情——只是说在这个例子中应该采取什么步骤。


当前回答

收回,收回

对于复杂的案件,埃里克·S·雷蒙德(Eric S.Raymond)的收回是首选工具。除了SVN,它还通过快速导出格式和CVS支持许多其他版本控制系统。作者报告了Emacs和FreeBSD等古代存储库的成功转换。

该工具显然旨在实现近乎完美的转换(例如将SVN的SVN:ignore财产转换为.gitignore文件),即使是对于历史悠久的复杂存储库布局也是如此。在许多情况下,其他工具可能更容易使用。

在深入研究repourgeon命令行的文档之前,请务必阅读出色的DVCS迁移指南,该指南将逐步介绍转换过程。

其他回答

GitHub有一个导入程序。创建存储库后,可以通过其URL从现有存储库导入。如果适用,它将要求您提供证书,然后从那里开始。

当它运行时,它会找到作者,您可以简单地将他们映射到GitHub上的用户。

我已经在一些存储库中使用了它,而且它非常准确,速度也快得多!一个大约4000次提交的存储库花了10分钟,之后我的朋友花了4天!

我们可以使用git-svnclone命令,如下所示。

svn log-q<svn_URL>|awk-F'|''/^r/{sub(“^”,“”,$2);sub(”$“,”,$2);print$2“=”$2“<”$2”>“}'|sort-u>authors.txt

上述命令将从SVN提交创建authors文件。

svn日志—复制时停止<svn_URL>

创建SVN项目时,上面的命令将为您提供第一个修订号。

git svn clone-r<svn_REV_NO>:HEAD--无最小化url--stdlayout--无元数据--作者文件authors.txt<svn_url>

以上命令将在本地创建Git存储库。

问题是它不会将分支和标签转换为推送。您必须手动执行这些操作。以下分支机构示例:

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
* master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$$ git checkout -b MyDevBranch origin/MyDevBranch
Branch MyDevBranch set up to track remote branch MyDevBranch from origin.
Switched to a new branch 'MyDevBranch'
$ git branch -a
* MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$

对于标记:

$git checkout origin/tags/MyDevBranch-1.0
Note: checking out 'origin/tags/MyDevBranch-1.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 3041d81... Creating a tag
$ git branch -a
* (detached from origin/tags/MyDevBranch-1.0)
  MyDevBranch
  master
  remotes/origin/MyDevBranch
  remotes/origin/tags/MyDevBranch-1.0
  remotes/origin/trunk
$ git tag -a MyDevBranch-1.0 -m "creating tag"
$git tag
MyDevBranch-1.0
$

现在将master、branches和标记推送到远程git存储库。

$ git push origin master MyDevBranch MyDevBranch-1.0
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To https://github.com/pankaj0323/JDProjects.git
 * [new branch]      master -> master
 * [new branch]      MyDevBranch -> MyDevBranch
 * [new tag]         MyDevBranch-1.0 -> MyDevBranch-1.0
$

svn2git实用程序

svn2git实用程序删除了带有分支和标记的手动工作。

使用命令sudogeminstallsvn2git安装它。之后运行以下命令。

$svn2git<SVN_URL>--authors.txt--修订版<SVN_REV_NO>

现在,您可以列出分支、标记并轻松推送它们。

$ git remote add origin https://github.com/pankaj0323/JDProjects.git
$ git branch -a
  MyDevBranch
* master
  remotes/svn/MyDevBranch
  remotes/svn/trunk
$ git tag
  MyDevBranch-1.0
$ git push origin master MyDevBranch MyDevBranch-1.0

假设您有20个分支和标记,显然svn2git将为您节省大量时间,这就是为什么我比原生命令更喜欢它的原因。这是一个很好的原生git-svnclone命令包装器。

有关完整的示例,请参阅我的博客条目。

为此,我使用了svn2git库,过程如下:

sudo apt-get安装git-core git-svn-rubysudo gem安装svn2gitsvn log--quiet|grep-E“r[0-9]+\|.+\|”|cut-d'|'-f2|sed's///g'|sort|uniq>authors.txt(此命令用于映射作者)

以上步骤应该在要从svn转换为git的文件夹中执行。

在authors.txt中每行添加一个映射,如下所示

anand = Anand Tripathi <email_id>
trip = Tripathi Anand <email_id>

为新的git存储库创建一个文件夹,并执行以下命令,路径为authors.txt

svn2git <svn_repo_path> --nobranches --notags --notrunk --no-minimize-url --username <user_name> --verbose  --authors <author.txt_path>

If no trunk and no tag and branch is present then have to execute the above command else if root is trunk then mention rootistrunk or trunk is present then --trunk <trunk_name>

git远程添加原点git push—所有原点git push—标记原点

用于SVN到GIT迁移的一体式shell脚本。用占位符提及GIT和SVN详细信息

#!/bin/bash

######## Project name 
PROJECT_NAME="Helloworld"
EMAIL="example mail"

#Credientials Repo
GIT_USER='<git username>'
GIT_PWD='<git password>'
SVN_USER='<svn username>'
SVN_PWD='<svn password>'

######## SVN repository to be migrated # Dont use https - error will be thrown
BASE_SVN="<SVN URL>/Helloworld"

#Organization inside BASE_SVN
BRANCHES="branches"
TAGS="tags"
TRUNK="trunk"

#Credientials
git config --global user.name '<git username>'
git config --global user.password '<git password>'
git config --global credential.helper 'cache --timeout=3600'

######## GIT repository to migrate - Ensure already project created in Git
GIT_URL=https://$GIT_USER:$GIT_PWD@<GIT URL>/Helloworld.git

###########################
#### Don't need to change from here
###########################

#Geral Configuration
ABSOLUTE_PATH=$(pwd)
TMP=$ABSOLUTE_PATH/$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
echo
echo '[DIR] cd' $TMP
cd $TMP

echo
echo '[LOG] Getting authors'
svn --username $SVN_USER --password $SVN_PWD 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

#Not working so no need to mention it
#--stdlayout $PROJECT_NAME
echo
echo '[RUN] svn ls '$SVN_BRANCHES
svn ls $SVN_BRANCHES

echo 
echo 'git branch -a'
git branch -a

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

#Branches and Tags  
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 'git tag'
git tag

echo
echo 'git show-ref --tags'
git show-ref --tags

echo
echo '[RUN] git remote add origin '$GIT_URL
git remote add origin $GIT_URL

echo
echo '[RUN] git push'
git push origin --all --force
git push origin --tags

#echo git branch -d -r trunk
#git branch -d -r trunk

git config --global credential.helper cache
echo 'Successful.'

当您运行上述脚本时,它将从SVN中获取分支和标记详细信息,并将其放在.git文件夹下。交叉检查SVN中是否存在所有分支,这些分支应在此.git/refs/heads文件夹下可用。如果SVN中缺少一些分支,请手动将分支文件从.git/refs/remotes/origin/<branches>复制到.git/refs/heads只复制分支(包括主分支),如果有标记或主干,则忽略。现在再次运行脚本。您可以在git存储库中看到所有分支和标记。

这里的几个答案涉及https://github.com/nirvdrum/svn2git,但对于大型存储库,这可能会很慢。我试过使用https://github.com/svn-all-fast-export/svn2git相反,它是一个同名的工具,但用于将KDE从SVN迁移到Git。

设置它的工作稍微多了一些,但当为我完成转换时,其他脚本花费了数小时的时间。