git-svn: how to copy git commits from one SVN branch to another?

git, git-svn, version-control

Solution

The first commit on branch2 that's not on local-branch1 is presumably the commit that created branch2, yes? This should appear as an empty commit in git (e.g. a message, but no contents). Copy its sha1 identifier. Then in local-branch1, try `git reset --hard branch2 && git rebase --onto local-branch1@{1} SHA1` (where SHA1 is the copied sha1). This should replay all the commits except that empty one back onto branch 1. You will most likely now want to do an interactive rebase and edit each commit so you can strip out the git-svn-id: line that git-svn adds for you (or you could write a git-filter-branch script to do so, if there's enough commits).

Out of curiosity, why do you want to replay each of the commits? If you want to simply merge your changes in, it's much simpler, you can just do `git checkout local-branch1 && git merge --squash branch2 && git commit`. This will do a non-fast-forward merge, but it won't actually produce a merge commit (as those confuse git-svn). Instead it will produce the equivalent working tree as if a merge had happened, but with only a single parent. This mirrors how svn merges work.

Problem

I've got a git-svn checkout of my entire repo (initialized in the standard `git svn init -t tags -b branches -T trunk $repo_url` fashion, then `git svn fetch`ed). I manually `svn copy $repo_url/branches/branch1 $repo_url/branches/branch2`. I then ran `git svn fetch`, `git checkout -b local-branch2 branch2`, made a few commits to `branch2`, `dcommit`ed them back to the SVN repo, and am done with my work on `branch2`. (Why branch a branch? I wanted to hack at this branch locally in git, but still commit back to SVN and get help from a couple of coworkers while I was working on it). What I haven't done is merge the `branch2` work back into `branch1`. If I `git checkout -b local-branch1 branch1`, then `git merge branch2`, it simply fast-forwards my `local-branch1` pointer to where `branch2` is. Instead, I want git to replay all commits made since starting `branch2` onto branch1, so that I can dcommit each of them to the SVN repo. It seems like there's a way to do this, but I can't think of it. Maybe `git rebase`, or a `git cherry-pick` of each commit made on `branch2`? (though the latter is a bit tedious). I'd rather not svn merge the two URLs together, as that's a big bucket of hurt. Ideas? Any parts of this need more explanation?

Original source