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 (eg 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
?
Sounds like you want to do your bugfix in v1
and then cherry-pick that in v2
before commiting both. This is not a merge nor a rebase operation in git
terms. It would be if you would do the change in v1
, then merge that into master
, then merge-or-rebase that into v2
.
I admit I'm not too sure where the problem is, after your description, though. It sounds more like a workflow problem then a git-svn problem to me? If your svn branches were good (ie, not a total mess), then git init
should have transfered them in a way that you can just work with them like usual. If they are already much degraded on the svn side, then it cannot "repair" that mess, really.
EDIT: To respond to your second edit: What you describe (distributing a hotfix/patch across all branches) is called "cherry-picking" in git, not merging. git does not (and does not need to) keep track of whether you did cherry-pick something or not; you just do it and are done with it. You most definitely do not want to do any merges or rebases in your scenario.
So, here's what you can do:
Your situation
D--E--F v1 K--L--M v2 / / A--B--C--G--H--I--J--N trunk ^ | introduced a bug
Fix your bug and commit on v1
, if that is your policy.
git checkout v1 # fix bug git add ; git commit # note the commit hash you just created, let's call it a1b2c3d4
Distribute to the other branches
git checkout v2 git cherry-pick a1b2c3d4 git checkout trunk git cherry-pick a1b2c3d4
New situation
D--E--F--a1b2c3d4 v1 K--L--M--abcde123 v2 / / A--B--C--G--H-------------I--J--N--bca123123 trunk ^ | introduced a bug
That's it. git cherry-pick
will automatically take the diff/patch for that single commit, apply it to your current HEAD, and create a new commit. There is (by design) nothing going on "backstage", it is a quite simple procedure. There may be conflicts as usual, which you may need to fix manually, but git
will tell you what to do more or less clearly.
When you continue your regular work later, and merge/rebase those branches, git
does not need to know about the cherry-picking. The stuff is inside your files, it will see (or not see) the textual differences, and with a bit of luck all will be fine.
Ok, I've finally managed to solve this issue myself. I've solved this in two steps: First of all, as our code bases for v1
and v2
are good (building and working, both with the known bugs fixed), I've recorded a merge of the v1
branch into the v2
branch and v2
into trunk
in svn
. Now I am able to merge the branches in git
. Then I've found this passage in the git-svn
docs:
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.
So I've enabled this config value
git config svn.pushmergeinfo true
and now, if a new bug is found, I'm fixing it in the lowest version that has this bug, dcommit
it to svn
, and afterwards merge it into the next version using the --no-ff
option. If I dcommit
now from there, the mergeinfos in svn
get updated and everything is ok.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.