1
votes

I'm using the Subgit plugin for BitBucket to mirror an svn repository as a git repository. Only the trunk branch (called master in git) has been marked for synchronization, but developers using the git repository have created a feature branch and committed a dozen commits to the git branch (which is not being synchronized).

Now both branches have several commits and we want to merge the git feature branch back to the trunk svn branch. The subgit docs are not entirely clear if the following would work:

git checkout master
git merge feature
git push

One other thing to note is that merging will require a merge commit since there's a conflict that must be resolved.

  • Is this workflow supported in subgit?
  • Will this mess up the SVN repo?
  • Will all the individual commits on the feature branch be preserved?
  • Or should I just rebase the feature branch onto master and then push?
1
Just forget about svn.0andriy
@0andriy I wish I could!!! But the SVN repo is an old existing one that corporate is unwilling to drop at this time. The compromise is using Subgit so some developers can use git.Justin
Then sad to be you... I hope you will find some solution, though more obvious one is consigning SVN to oblivion.0andriy

1 Answers

2
votes

This workflow

git checkout master
git merge feature
git push

is supported by SubGit (in this case it doesn't matter, but I recommend to to use

git merge --no-ff feature

to prevent fast-forward merges); the result depends on your configuration. I'll describe several cases.

Case 1. (Not your case, but useful to know) If both trunk and the branch are configured to be synchronized by SubGit. In this case the effect is equivalent to "svn merge" command: svn:mergeinfo will be updated. Of course, individual commits in the feature branch will also get into SVN because the feature branch is configured to be synchronized.

Case 2. (Your case, I think, check 'shelves=' option to be sure) Only trunk is configured to be translated, the feature branch is not; and also you have 'shelves=' option set in SVN Mirror add-on settings for the repository, usually the option looks like:

shelves = shelves/*:refs/shelves/*

but the exact value doesn't matter. In this case "git push" will push all commits from both master and feature branch (even though you didn't push the feature branch explicitly), because the commits will be reachable by "merge commit parent" link. On the other hand, the feature branch Git reference won't be pushed, so SubGit can't know the name of the feature branch. In this case SubGit will invent some temporary name in the 'shelves' namespace in SVN, e.g. shelves/shelf corresponding to the commits of the feature branch. Then it will translate these individual commits to SVN one-by-one. Finally it will create a merge commit in the SVN trunk, updating svn:mergeinfo; and after all it will delete that shelves/shelf in SVN (but you can refer to it using older revisions, Subversion never forgets).

To understand that better I recommend this post. The second picture corresponds to this case, e.g. Case 2, while the first one to Case 1.

Case 3. (Not your case but some users prefer this behaviour) Only trunk is configured to be translated, the feature branch is not; and also you do not have 'shelves=' option at all. In this case all individual commits in the feature branch will be ignored in SVN, svn:mergeinfo will not be updated. So you will get all your changes in the SVN trunk, but not as individual commits but as a single SVN commit with all changes squashed together as if your were using

git merge --squash feature

instead of

git merge feature

Note that on Git side the individual commits will still be preserved, they just won't be translated as individual revisions.

I would also add that in SVN Mirror add-on not only this workflow is supported, but alternately you or your team members will create a Pull Request using Bitbucket Server UI and then merge it using UI. The behaviour in this case is approximately the same like when using "git merge" + "git push", i.e. it will be one of 3 Cases above.

What about your other questions:

  • Will this mess up the SVN repo?

No it won't though it depends on your definition of mess. Some people prefer "Case 2", calling "Case 3" the mess, other have the opposite opinion. In either case you can configure the add-on to achieve behaviour you want.

  • Will all the individual commits on the feature branch be preserved?

In Cases 1 and 2 --- yes, in Case 3 --- no, they will be squashed to a single SVN revision. In all cases individual Git commits will be preserved as is.

  • Or should I just rebase the feature branch onto master and then push?

You can, but I wouldn't recommend you to do that. In general I recommed to use git pull --rebase instead of just git pull. But when merging a feature branch it's better to merge it than to rebase it. If you rebase it, you'll see individual commits from the feature branch directly in the master (and hence in SVN trunk), this part is ok. But the feature branch reference will be updated and you will have to either

  1. Push the updated feature branch reference with --force option, what's not recommended in general; OR
  2. Leave the feature branch as is, thus having inconsistent feature branch reference locally and its commits repeatet twice: in 'master' and the feature branch.

This doesn't relate to SubGit (SubGit will just translate to SVN trunk what it will find in the 'master'), but will cause inconvenience in pure Git.

I'm one of SubGit developers.