Working on One Thing At A Time With Git-Svn
We've all seen people who have 2 or 3 work in progress items within a single workspace. Even the workspace owner doesn't always know what file belongs where, nor can they really prove that their change will integrate cleanly with the rest of the code. I see this more often with people that have used centralized source code repositories to manage their code. Branching is expensive and checking out a fresh repository sometimes takes more time than actually fixing the bug. It is tempting to cut a corner here and there to be able to do this quick fix and move back to the task at hand. It is a dangerous thing to do though.
I find that I do my best work when I am working on one item at a time, whether we are talking about a feature or a bug. This is one of the reasons why I like git. It's local branching capabilities makes it easy to do just that while still being able to quickly go back to a clean slate when reality intrudes and I have to switch to a different task.
My Workflow
Project Kenai still hosts its repository in a Subversion repository. I quickly started using git-svn to managed my workspace and I base my daily workflow on Lennon's daily git-svn workflow. Here is how I approach a task:
- I make sure that I am at a clean slate and up-to-date. I checkout my master branch (git checkout master) and bring it up to date with the upstream subversion repository (git svn rebase).
- I create a branch against the master branch and switch to it (git checkout -b branch-name). I normally name the branch based on the Jira issue that I'm working against. This makes it easy for me to link the work that I'm doing to the related Jira issue. I do not using any of the git svn commands in this branch. I add files to the index and commit frequently as I work as a safety net. It is easier to revert to a previous state that way.
- I then switch to my svn merge branch once work has completed. I make sure that it is up to date (git svn rebase) and run our automated tests. This lets me know that I am working against a clean branch. I then merge my changes from the work branch (git merge --squash branch-name). This condenses all of the commits I did in the branch into one commit that will be merged into the svn merge branch, resolve any merge issues and run the tests again.
- I commit the merge into the svn merge branch (git commit) and then push my changes to the Subversion repository (git svn dcommit).
- I finally go back to the master branch, update it (git svn rebase) and run the tests to make sure that all is working as expected.
It may seem a little involved, but it gives me many points where I have a chance to run tests and verify that the work will integrate cleanly with the rest of the team's work.
When Reality Intrudes
I don't always have the luxury of a linear workflow. there are times where I have to jump to a different work item (critical bug) and work on a fix. The workflow that I use allows me to do this very easily since I can go back to a clean slate at any point in time by:
- Committing the work in progress
- Going back to the master branch
- Updating the master branch
- Creating a new branch for the new work
- Complete the new work and commit it to the Subversion repository.
- Go back to the work in progress branch and resume work
As a result, my workspace always contains the changes associated with one work item. There isn't confusion on what file needs to be committed nor do I run the risk of having multiple patches applied to a single file and having to sort through them manually when it is time to commit.
The good news is that this very same workflow will work just as well if we switch the Project Kenai's repository to git or Mercurial.