views:

253

answers:

1

I have forked an SVN project using Git because I needed to add features that they didn't want. But at the same time, I wanted to be able to continue pulling in features or fixes that they added to the upstream version down into my fork (where they don't conflict). So, I have my Git project with the following branches:

  • master - the branch I actually build and deploy from
  • feature_* - feature branches where I work or have worked on new things, which I then merge to master when complete
  • vendor-svn - my local-only git-svn branch that allows me to "git svn rebase" from their svn repo
  • vendor - my local branch that i merge vendor-svn into. then i push this (vendor) branch to the public git repo (github)

So, my flow is something like this:

git checkout vendor-svn
git svn rebase
git checkout vendor
git merge vendor-svn
git push origin vendor

Now, the question comes here: I need to review each commit that they made (preferably individually since at this point I'm about twenty commits behind them) before merging them into master. I know that I could run git checkout master; git merge vendor, but this would pull in all changes and commit them, without me being able to see if they conflict with what I need.

So, what's the best way to do this? Git seems like a great tool for handling forks of projects since you can pull and push from multiple repos - I'm just not experienced with it enough to know the best way of doing this.

Here's the original SVN project I'm talking about: https://appkonference.svn.sourceforge.net/svnroot/appkonference

My fork is at github.com/jthomerson/AsteriskAudioKonf

+2  A: 

It seems like you should just create a branch off of master for your testing:

git checkout -b testing master
git merge vendor-svn
# test...
git checkout master
git merge testing

Or, if you want to test individual commits, you could merge them all individually at once:

git checkout -b testing master
git log --pretty=%H testing..version-svn | while read commit; do git merge $commit || break; done
# now go check out and test each merge that was created

Or one at a time:

git checkout -b testing master
git merge $(git log --pretty=%H testing..version-svn | tail -n 1)
# now test the result, and if you're okay...
# run the merge command again to merge the next commit
git merge $(git log --pretty=%H testing..version-svn | tail -n 1)
# and so on

You'll probably like the latter better, since you can test that commit before bothering to merge the next one. The history will be ugly, so you'd obviously want to go back and redo it all as one merge later.

Either way be sure and set rerere.enabled to true so that git will remember how you've resolved conflicts, and when you go back and redo the merge straight into master, you won't have to resolve them over again!

Jefromi
I like the `git log` for merging commits here. +1
VonC
Couldn't you interactively merge commits with `git rebase -i`?
rjh
@rjh: I'm not sure what you mean by that. How exactly are you going to get `rebase` to create a merge commit? It's true, you could do `rebase -i testing copy-of-version-svn`, choose "edit" for everything, and go along, but that wouldn't actually be a merge, just cherry-picks, so with more complex merges the results wouldn't be as good, I don't think.
Jefromi
thanks! this worked great. fortunately, there were no merge errors and everything tested out fine. i merged one commit at a time into my testing branch and then tested. since they all worked without a problem, i then did "git checkout master; git merge vendor-svn" to merge them all in one shot. however, i'm not sure how I would merge them all as a single shot if there was one commit in the middle that failed or needed to be modified - any help here?
Jeremy Thomerson
@Jefromi: I'm relatively new to git, so just curious. Thanks for the explanation.
rjh
@rjh: Ah, okay. And to be fair, if rebasing were your final goal, that'd actually be a great way to do it testing one-at-a-time!
Jefromi
@Jeremy Thomerson: It depends on what sort of failure it was. If it was merge conflicts, then `rerere` would REuse the REcorded REsolution, and you wouldn't have to worry about anything. If you needed to patch it so it'd play nice with your fork, my suggestion would be to do that in a separate commit, noting which commit it's a correction to. You could just do that between the merges to start with, then after merging vendor-svn into master, cherry-pick the fixes. Alternatively, you could branch off of vendor-svn, cherry-pick onto that branch, and merge it all at once to master.
Jefromi