轻松地将旧svn存储库中的错误修复复制到新的git存储库中。

时间:2012-07-04 15:46:24

标签: git svn interop

我们已将大部分代码库从单个svn存储库移动到一组git存储库中。出于各种原因,一些工作(在现场部署的项目的旧版本)必须在旧的svn分支中继续移动到git并从subversion {{1}中删除}。

我刚刚在trunk分支上完成了这样的工作,并通过执行以下操作将svn存储库中的更改重新应用到svn存储库中:

git

但为每个cd <common_svn_commit_root> svn diff -r 12344:12345 > ~/r12345.diff gedit ~/r12345.diff cd <common_git_commit_root> git apply ~/r12345.diff 提交执行此操作相当麻烦,尤其是svn步骤,我必须手动将gedit路径移至svn路径(通常通过为顶级目录名添加前缀)。

尝试到目前为止提供的一些选项的一个问题是旧git repo和新svn repo的结构是不同的。这是我必须编辑补丁文件的原因之一。

旧的目录结构是

git

而新结构是

svn
    configurations
        blah
        mine
        blam
    plugins
        foo
        core
        mine
        bar

我真的想知道是否有更简单的方法来做到这一点,并了解这种情况的最佳做法。

3 个答案:

答案 0 :(得分:2)

你可以使用git svn将你的git repo与来自svn的更改同步。

git svn --authors-file=authors.txt clone https://repo/svn/reponame/trunk reponame-git-svn

# if something aborts:
cd reponame-git-svn
git svn fetch

# create a new branch
git checkout -b dvcs

git remote add dvcs-svn https://repo/git/reponame.git

这会让你在git分支中使用svn源代码。要从svn同步到git:

git checkout master
# get the changes from svn
git svn rebase
git checkout dvcs

# apply the changes from svn
git rebase master

# fetch the changes from git repo to the local repo
git fetch dvcs-svn

# apply the changes from git repo to the branch dvcs
git rebase dvcs-svn/master

# push all changes back to git repo
git push dvcs-svn dvcs:master

我们对rebase的经验比使用merge更好。希望这也能帮到你。

答案 1 :(得分:1)

没有任何内容禁止您在源树中共存gitsvn。这使得提交的提取比在不同源树之间修补和复制更容易。

  1. svn checkout你已经在git中的分支和修订。
  2. git clonegit checkout与步骤1中的源树状态相同(如果存储库非常庞大,可能会在此处涉及裸存储库 - 您只需要.git/存储库数据)。
  3. .git/目录复制到您的svn checkout根目录。
  4. 通过将git添加到.svn文件中,告诉.gitignore忽略颠覆元数据。
  5. 如果可以,您还可以运行svn propset svn:ignore dirname .git告诉svn忽略.git导演。
  6. 现在有很多方法可以导出提交。这里有一种方法,如果你想拿起说提交r12345(假设上面的点,其中svn和git都是最新的):

    1. 创建并结帐临时git分支(git checkout -b throway-branch);
    2. 通过svn co -r12344;
    3. 在所需的svn提交之下得到一个
    4. 通过git后跟git add -A;
    5. 之类的内容将这些更改(被忽略)提交到git commit -m "SVN -r12344 (uninteresting stuff)"存储库中
    6. 通过svn co -r12345
    7. 查看有趣的svn提交
    8. 将其保存到您的git存储库:git add -A && git commit --date <svn commit date> (假设您要保留svn提交日期,请使用此处--date <svn commit date>。)
    9. 现在,您可以git cherry-pick对您计划​​向全世界发布的实际分支进行最后一次有意义的提交。
    10. 当我在本地使用git时不得不处理上游subversion存储库时,这种双存储库设置对我很有用。我最终制作了一些脚本来使这一切变得更容易。例如。为此,脚本可以获取svn提交日期和消息,并为您创建一个具有相同日期和消息的git提交(将svn修订号添加到消息中以与svn提交匹配)。

      或者你可以像你在帖子中提到的那样使用svn diff --gitgit am,这样更方便,因为你不需要在不同的目录之间移动补丁,你可以随时比较你的随时可以使用svn checkout和当前git commit的工作目录。

      我不熟悉git svn以了解这对您是否有用。

答案 2 :(得分:1)

假设您的源的目录结构保持不变,我建议您将遥控器添加到旧的SVN分支:

$ git config --add svn-remote.svn-branch.url http://my.svn.server/project/branches/my-branch
$ git config --add svn-remote.svn-branch.fetch :refs/remotes/old-svn-branch

这样,您就可以跟踪旧SVN分支和本地分支机构中全新Git服务器的更改,并使用git-cherry-pick在Git服务器分支上应用包含修复的提交。 / p>

修改

Git会跟踪文件的移动。

我自己没有尝试过,但是如果你克隆了SVN repo,那么本地移动目录以匹配你的新Git服务器结构,cherry-pick合并可以将它应用于移动的文件。

它已经为我的某些文件工作了,但也许有一些限制。这绝对值得一试。