Here at Mozilla, a bunch of webdevs use git svn instead of plain Subversion to interact with our svn repositories -- mostly because of in-place branching, better merging, and all these things that make a dev's life happier.
As you probably know when reading this article, you push all uncommitted changes to the remote svn repository by typing
git svn dcommit. This will take your last, say, five commits, push them to SVN, and mark them locally as committed. But what if you only want to
dcommit some of your changes?
(If you don't need explanations, jump straight to the summary).
Step 1 (optional): Reorder commits
I am not going to go into a lot of detail on interactive rebasing (
git rebase -i), but to start off, make sure your commits are ordered, so that the ones you do want to commit to SVN are before the ones you do not want to push up-stream for now. Example: If in the following history, you want to commit all changes but
a023fea, you want to rebase your commits so
a023fea is last:
git rebase -i HEAD~4, change...
pick 07c26c5 some de L10n pick a023fea adding free-text messages to localizer dashboards pick 8597f47 adding featured collections as l10n category pick 19f3df3 making existing localizer pages work with amo2009 layout
Make sure to resolve any merging problems that might occur due to the reordering.
pick 07c26c5 some de L10n pick 8597f47 adding featured collections as l10n category pick 19f3df3 making existing localizer pages work with amo2009 layout pick a023fea adding free-text messages to localizer dashboards
Step 2: Step in between commits
To only push the desired commits to svn, execute another
git rebase -i and mark the last desired commit for editing (by changing
pick 07c26c5 some de L10n pick 8597f47 adding featured collections as l10n category edit 19f3df3 making existing localizer pages work with amo2009 layout pick a023fea adding free-text messages to localizer dashboards
When exiting the editor, git will drop you off after the marked commit, but before the one you don't want, as a quick look at
git log can tell you.
Step 3: dcommit desired changes
After making sure this is really what you want, just execute
git svn dcommit as usual and watch git push all desired changes to SVN, while omitting the rest.
Step 4: Fast-forward to HEAD
When the dcommit is done, remember we are still in the middle of a rebase, so just run
git rebase --continue to fast-forward to the HEAD of your branch. Again, a quick look at
git log can reassure you that only the changes you wanted to have been pushed to SVN.
Summary: Quick cheat sheet
Here's a quick cheat sheet for you (and me) to come back to in case you forget:
- Reorder commits (
git rebase -i HEAD~4) so that the undesired ones are after the ones you want to push
- In your commit history, jump right after the last wanted commit by marking it for
git rebase -i
git svn dcommit
git rebase --continue