views:

161

answers:

1

The company that I'm working is working with SVN but I would like to start working with git to take advantage of the light branching and stashing features (disclaimer, I'm pretty new to git). I've started with git-svn and I'm trying to figure out the ideal git-svn workflow for what I'm trying to do (and suggestions if what I'm trying to do needs tweaking).

I've read through http://stackoverflow.com/questions/1129688/git-svn-workflow-feature-branches-and-merge and a few other posts but its still not clear how I should approach it.

How I plan to work: I plan on having my master branch be clean from development and only used for merging/rebase/dcommit.

I would like break apart each new feature/bug into separate git branches so they can be worked on independently. Meaning, I can work on one feature for a few hours, then put it aside and work on the next issue. When I was in SVN it was a problem when I had two different features/bugs in one file because when it came time to commit, I would remember that it had both changes and temporarily take out what I didn't want to commit now - a pain. And the are some features which are while I might want to work on now, will not be added to the main repo for some time.

After a feature is ready to be shared/tested in the main repo, I'll merge/rebase into my master branch and then dcommit to the svn-repo. I only want to have one SVN commit message for each dcommit - I want to be committing in more often with comments more specific to me and then dcommit to svn with a message for the rest of the team. I assume for this I'll either be using a git merge --squash or a git rebase --interactive for this.

The basic git flow I've envisioned is like this:

  1. // it begins...
    git svn clone <repo>

  2. //
    git checkout -b feature 1
    // work commit, work commit

  3. //
    git checkout -b bug-123
    // work commit, work commit
    // bug-123 finished - ready to send back

  4. // got back to master for step 5
    git checkout master

  5. // get whatever changes other devs did
    git svn rebase

  6. //
    git checkout bug-123

  7. // rebase branch so I have fewer smaller changes. not sure here..
    git rebase master || git svn rebase
    // Assuming I'm doing a FF rebase so my commits are just addons to the current repo
    // I don't know if I rebase the master or svn repo or it doesn't matter.

  8. // need to get my changes back to master to send off
    git checkout master

  9. // add my changes to master
    git rebase bug-123 (--interactive?) || git merge --squash bug-123
    // do I add a new commit message here?

  10. // push my changes back out to the team
    git dcommit

So there are a few questions:

  1. How should I get the changes into the branch I want to commit - by rebasing the master or the svn branch

  2. how do I get the changes back into the main branch - rebase or merge - remember, I want only one commit for each commit - unless this is going to complicate things - I really would prefer to keep my git commits separate from the SVN commits because I might start something - it's half-working, and want to commit it so I could try something else - but I don't want to commit these broken steps.

  3. would it make sense to dcommit directly from the working branch (eg bug-123)?

  4. how do I get the changes from bug-123 back now into feature-1? I'm assuming I'll do it via the SVN repo - meaning the changes that I added will get merged in when I do the rebase when it's time to add feature-1 to the repo - but maybe not.

+2  A: 

I'm no expert, but these are the experiences I've made (related answer).

  1. I think it doesn't matter. The important thing is that you rebase the latest changes from SVN into the branch you are going to dcommit from.
  2. Let other branches receive the changes through SVN. If you want a single SVN commit from a series of git commits, squash them together first.
  3. I think this doesn't matter either. You're going to rebase the latest changes from SVN, and need to get them linearly in front of your Git commits. If you do git svn rebase in master, and then rebase master into a feature branch, or the other way around is same-same. Afterwards you probably want to delete the branch, as it has done its work (as per SVN restrictions, you're not allowed to merge again).
  4. Always let changes flow into other branches and repos through SVN rebasing.

Just try it out and try to get the most simple/practical workflow for you and your team. Try to keep branches short-lived (SVN won't get any notion of them anyway), and remember that the commits must always be linearized at the top of your log before you dcommit back.

Thomas Ferris Nicolaisen
Thanks for the suggestions - one thing I've realized is merge --squash is great if the branch is finished but if I want to keep it around for future work (eg, qa) then it's a big problem because I always run into conflicts when I rebase into the branch the next time because the merges don't line up. It seems the best solution is the rebase -i my git branches until I have acceptable commit messages and then svn dcommit. Then I can rebase new upstream svn commits. Does that sound right?
Yehosef
If you've pushed a branch into SVN, you can't do it again, because SVN doesn't *get* branches the way git does. That's why you get conflicts. Keeping the branch around is hardly ever interesting. You need to linearize your git-commits before dcommitting. This doesn't mean you have to squash them. You can push a series of git commits to SVN at once, as long as they're in the right order: Before dcommit, in the git-log, your local commits should be on top, over the svn-id commits.
Thomas Ferris Nicolaisen
I didn't try it recently, but I thought if I have a branch and I merge that into my master and dcommit from there, when I rebase the branch again, it'l be started after my master commits (which were the commits from the branch merge) - I thought that from git's perspective, it's the same thing - it's not like I need to dcommit from my master and then svn rebase again to get the "svn version" of my commits, no?Most of my problems so far were because I wanted to keep lots of git commits and just a few svn commits - and I now see that that is not going to work if the branch is to stay around.
Yehosef
When you dcommit, git-svn rewrites the master log, including the commits you merged from the branch. They essentially become commits from SVN. Therefore, the next time you merge from the branch, git will not recognize these commits, as they have been morphed into being SVN commits (atleast, that's the way I picture it).
Thomas Ferris Nicolaisen
hmm, didn't know that - thanks for the info! If that's really how it works then it drastically changes how I was planning on using git-svn
Yehosef