将具有多个活动分支的 SVN 存储库转换为 GIT

Convert SVN Repository with multiple active branches to GIT

I'm trying to convert my SVN Repository into a GIT repository. The problem with this is, that in the SVN there are several active branches for different software versions maintained in parallel. So the SVN setup looks somthing like this:

SVN ROOT
|- trunk
|- branches
|  |- v1
|  |- v2
|  |- v3
|- tags
|  |- v1
|  |  |- 0
|  |  |- 1
|  |- v2
...

Now I want to create a GIT repository with a branch for each of the branches of the SVN. Creating the repository and porting the tags is not a problem at all. I'm doing a

git svn init -s --tags=tags/v1 --tags=tags/v2 <REPO_URL>
# modified .git/config to use tags/v1/* for the tags of the different versions
git svn fetch

and after this I get the branches as desired and I'm able to check out the different software versions by using

git checkout -b v1 origin/v1

The Problem is that the SVN Repository is verry old and the different branches all branch from the trunk. But my development requires me to fix a bug in v1, merge it to v2 as well and dcommit everything back to SVN.

So my question is what's the best way to get clean (mergable / rebaseable) GIT branches? And how should the workflow with this be? Should I add a new branch for each version in GIT, let's say svn_v1, rebase the v1 into this and then dcommit from there? Or what's the best way to get the commit back to SVN?

EDIT:

I've already tried to rebase the different branches according to the merge upstream (e.g. rebased v2 onto v1 and trunk onto v2) but this messed up my histroy and when trying to dcommit it wanted to commit all the commits that I've rebased on top of the current history. This would make the SVN history messy as these commits already are in the Repo.

EDIT2:

To make the problem more clear. Imageine the following history:

        D--E--F v1  K--L--M v2
       /           /
A--B--C--G--H--I--J--N trunk
   ^
   |
   introduced a bug

As commit B introduced a bug, all branches v1, v2, and trunk are affected. The policy of my company is now (in SVN) to fix this issue in the lowest affected branch (v1 in this case) and then merge the commit through the branches up to trunk. How does the workflow look like to do the same thing in GIT, such that in SVN the commit in v1 is marked as being merged into v2?

听起来您想在 v1 中修复错误,然后在提交两者之前在 v2 中挑选它。这不是 git 术语中的合并或变基操作。如果您要在 v1 中进行更改,然后将其合并到 master,然后将其合并或变基到 v2

我承认,根据您的描述,我不太确定问题出在哪里。对我来说,这听起来更像是工作流程问题,然后是 git-svn 问题?如果你的 svn 分支很好(即不是一团糟),那么 git init 应该以一种你可以像往常一样使用它们的方式转移它们。如果它们在 svn 方面已经严重退化,那么它就不会 "repair" 那样乱七八糟了,真的。

编辑:回应您的第二次编辑:您描述的内容(在所有分支中分发 hotfix/patch)在 git 中称为 "cherry-picking",而不是合并。 git 不会(也不需要)跟踪您是否选择了某些东西;你只要去做就可以了。您绝对不想在您的场景中进行任何合并或变基。

因此,您可以执行以下操作:

  1. 你的情况

            D--E--F v1  K--L--M v2
           /           /
    A--B--C--G--H--I--J--N trunk
       ^
       |
       introduced a bug
    
  2. 修复您的错误并提交 v1,如果这是您的政策。

    git checkout v1
    # fix bug
    git add ; git commit
    # note the commit hash you just created, let's call it a1b2c3d4
    
  3. 分发到其他分行

    git checkout v2
    git cherry-pick a1b2c3d4
    
    git checkout trunk
    git cherry-pick a1b2c3d4
    
  4. 新情况

            D--E--F--a1b2c3d4 v1    K--L--M--abcde123 v2
           /                      /
    A--B--C--G--H-------------I--J--N--bca123123 trunk
       ^
       |
       introduced a bug
    

就是这样。 git cherry-pick 将自动为该单个提交获取 diff/patch,将其应用于您当前的 HEAD,并创建一个新的提交。没有(按设计)发生任何事情 "backstage",这是一个非常简单的过程。像往常一样可能会有冲突,您可能需要手动修复,但是 git 会或多或少地告诉您应该做什么。

当您稍后继续正常工作时,merge/rebase 那些分支,git 不需要知道樱桃采摘。这些东西在你的文件里面,它会看到(或看不到)文本差异,运气好的话一切都会好起来的。

好的,我终于自己解决了这个问题。 我分两步解决了这个问题:首先,由于我们的 v1v2 代码库很好(构建和工作,都修复了已知错误),我记录了一个合并v1 分支进入 v2 分支,v2 进入 svn 中的 trunk。 现在我可以合并 git 中的分支。然后我在 git-svn 文档中找到了这段话:

config key: svn.pushmergeinfo

This option will cause git-svn to attempt to automatically populate the svn:mergeinfo property in the SVN repository when possible. Currently, this can only be done when dcommitting non-fast-forward merges where all parents but the first have already been pushed into SVN.

所以我启用了这个配置值

git config svn.pushmergeinfo true

现在,如果发现新的错误,我会在有这个错误的最低版本中修复它,dcommitsvn,然后将其合并到下一个版本中使用 --no-ff 选项。如果我 dcommit 现在从那里开始,svn 中的合并信息得到更新,一切正常。