views:

774

answers:

4

Currently, when I run git svn dcommit git creates a separate commit in SVN for every local commit I've made since last syncing with SVN. Is there any way for dcommit to instead combine all my recent local commits into one commit for SVN?

+7  A: 
git rebase remotes/trunk --interactive 

should bring you to the menu where you can pick commits or squash them all into 1 commit in order to avoid polluting your svn repository. This is a really good (but short) resource on working with git-svn.

Jason Punyon
This seems like a very good solution. I don't understand what the effect of remotes/trunk is in the command, the end result is that all my commits are squashed inside of master. I was hoping they would only be squashed in sending to SVN. It is necessary to commit to SVN after the squashing is done.
MacRae Linton
@MacRae Linton: All your commits have to be squashed in master. If they weren't git would have no way of keeping the git and svn repositories in sync. When you rebase to pull the latest changes svn would have one commit but in git you'd have n commits.
Jason Punyon
@Jason Punyon: The issue I am running into is that after squashing commits in master, it becomes difficult to merge master with my developing branch again. Pretty much all my changes become merge conflicts, which is a huge pain to deal with. Is this an unavoidable consequence of keeping my developing branch separate from the squashed master?
MacRae Linton
@MacRae Linton: Yeah that's a problem. It's not recommended to use rebase for commits that have already been replicated elsewhere. Rewriting history that way causes the problem you describe with the merge conflicts...
Jason Punyon
@Jason: So, in the end, there is no way to maintain separate histories for git and svn. If I want an abridged history for svn, I need to have that history be the history in git as well?
MacRae Linton
+5  A: 

No, but you can squish all the commits together pretty easily. For the following example, I'm going to assume you're on the master branch corresponding to the remote trunk branch and that you want to squish all local commits together:

git tag local # create a temporary tag
git reset --hard trunk
git merge --squash local
git commit # write your single commit message here
git svn dcommit
git tag -d local # delete the temporary tag named local

Instead of using a temporary tag you could also just use the reflog (i.e. use master@{1} in place of local)

Kevin Ballard
this is totally cool, this completely changes my workflow, many thanks
Fire Crow