cbowns
cbowns

Reputation: 6365

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

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 fetched). 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, dcommited 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?

Upvotes: 3

Views: 1458

Answers (1)

Lily Ballard
Lily Ballard

Reputation: 185681

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.

Upvotes: 6

Related Questions