Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does git-svn dcommit leave duplicate commits in my git repo? Can I stop it doing that?

Tags:

git-svn

My typical git-svn workflow is:

git checkout -b story-xyz
git commit -a -m "work"
git commit -a -m "more work"
git checkout master
git svn fetch
git merge remotes/trunk
git checkout story-xyz
git rebase master (sometimes with -i)
git checkout master
git merge story-xyz

At this point I have my master and story-xyz branches pointing to the same commit, one or more commits ahead of remotes/trunk. Everything since remotes/trunk is in one linear history.

last svn commit [remotes/trunk] <--- work <--- more work [master, story-xyz]

I then run

git svn dcommit

I expected to see the commits between remotes/trunk and master become Subversion revisions, and end up with a single linear history with remotes/trunk, master and story-xyz all pointing to the latest revision, like so:

last svn commit <--- work <--- more work [master, story-xyz, remotes/trunk]

My Subversion revisions go in fine, but I end up with a two-branched structure. The common root of the branch is the Subversion HEAD before I committed. Both branches contain the same series of commits, in the sense that they contain the same diffs. The branch story-xyz is at the head of one branch, remotes/trunk and master at the other:

last svn commit <--- work <--- more work [master, remotes/trunk]
                  |
                  \- work <--- more work [story-xyz]

The git commits that I had before running git svn dcommit are on the lower branch (story-xyz), with my git commit messages, git user name and email, and git commit timestamps. The commits on the upper branch are new git commits. They use my Subversion username, the timestamp when I ran the dcommit, and the commit messages have the git-svn-id field appended to them.

This is all OK, and I can carry on working. The problem is that I look in gitk and see what looks like an unmerged branch story-xyz. It's pretty hard to tell the difference between a story branch that I have merged back into master, and one that I haven't. The most obvious way to spot it is the duplicate commit messages. I could delete the story-xyz branch, but that feels like I'm not using git properly and I've lost some of my history.

Am I missing something that would stop git-svn from doing this? Or is this just one of the ways that interacting with Subversion dilutes the power and freedom of git?

like image 489
Alex Scordellis Avatar asked Jun 01 '09 16:06

Alex Scordellis


1 Answers

I don't think you're really missing anything. You might be doing some unnecessary work, though. In this case, you have two pointers to the "more work" commit, and you are asking git-svn to move one of them. The other one still stays where it is.

You don't really need the master branch. Git-svn doesn't care about what branch you are dcommiting. IIRC, it uses the first svn-remote it can find among the ancestors of the current commit.

I'll offer another version of the workflow:

git checkout -b story-xyz remotes/trunk
git commit -a -m "work"
git commit -a -m "more work"
git svn fetch
git rebase remotes/trunk (with -i, perhaps)
git svn dcommit

This should give you a tree without the extra branch. You need to be careful with fast-forward merges, though.

like image 90
Antti Rasinen Avatar answered Nov 07 '22 17:11

Antti Rasinen