views:

70

answers:

2

Perhaps I'm missing something about using gi through svn, but how do I keep around a set of locally modified files without pushing those changes to subversion.

Here's my broken workflow.

(on master) git svn rebase
git checkout -b issue
*apply changes I need on all my branches*
*changes*
git commit *changes*
git checkout master
git merge issue
git svn dcommit

The problem lies in the fact that svn rebase, or even committing, I lose my locally modified but not checked in files. I don't want to commit the files, because I don't want them pulled into an svn commit.

How is my workflow supposed to work in a situation like this?

+2  A: 

My git-svn workflow looks something like this:

(on master) git svn rebase
git checkout work
... make commits for all changes, including local-only and those I intend to push up
git checkout master
... cherry-pick changes from work branch
git svn dcommit
git checkout work
git rebase master

The last rebase step removes all the commits from the work branch that have already been committed upstream.

For the cherry-pick step, I actually use a small shell script that automatically gets all the commits except those that have "NOCOMMIT" in their description. You could use another indicator like "LOCAL" or "NOPUSH" or whatever you like. These commits are those which hang around on the "work" branch and aren't pushed up to Subversion.

Here's my pull-work script:

#!/bin/sh

BRANCH=`git branch | grep ^\\* | cut -d' ' -f2`
if [ $BRANCH != "master" ]; then
  echo "$0: Current branch is not master"
  exit 1
fi

git log --pretty=oneline work...master | grep -v -E '(NOCOMMIT|DEBUG):' | cut -d' ' -f1 | tac | xargs -l git cherry-pick

Note the use of subtleties like tac that reverse the order of the listed commits so they get applied to master in the same order.

Greg Hewgill
How does this prevent modified, uncommitted files from being pulled into master. Is that part of the cherry-pick step? How does that work, exactly? Can you specify which versions of the branch to pull into master from a merge?
Stefan Kendall
Mind posting your script somewhere?
Stefan Kendall
I don't leave modified, uncommitted changes hanging around at all. If I have a change I need locally for some reason, I make the change *and* commit it with "NOCOMMIT" in the commit description. After all, if there was a reason for the change then I want to record that.
Greg Hewgill
I understand. Could you host your nocommit script somewhere? That sounds extremely useful.
Stefan Kendall
+2  A: 

It sounds as though what's happening is that your HEAD is being reset. To avoid this, use svn dcommit --no-rebase.

However, I think your workflow is somewhat broken. Having uncommitted files kind of defeats the purpose, doesn't it?

You should probably use git stash. This makes your new workflow:

(on master) git svn rebase
git checkout -b issue
*apply changes I need on all my branches*
*changes*
git commit *changes*
git checkout master
git merge issue
git stash
git svn rebase
git svn dcommit
git stash apply

Name your stashes appropriately, and you should be able to do whatever it is you're trying to do.

David M
I prefer `git stash save "mumble something"` and `git stash pop`. The `pop` avoids accumulating stashes. The labeled save does as you suggest and gives it a useful name.
bstpierre