I recently started adding a new feature to one of my projects. The first thing I typically do in this scenario:
git checkout -b name-of-feature current-version (replacing name-of-feature and current-version appropriately)
Now as I'm working on this I may bump into something that if I were to refactor would make this new feature a lot a lot simpler to implement.
If I were using only subversion and I started on this refactoring I would have a source history that looks something like:
Added migration for table x
Created new models + tests for feature X
Renamed class foo to bar
Refactored some service into separate services
next change for feature x
fixed bug 370 reported by QA
another change for feature X
Which isn't bad persay, but it would be better if things were in their proper order. I also don't like that I would have to commit some incomplete implementation of feature X just to fix a bug. If I had a little better foresight and planning I might have fixed the bug first, then done that refactoring that will make feature X simpler then actually implemented feature X. Fortunately git makes this pretty easy to do.
Here's what my output of git branch might be:
In my graph here a - represents a commit and | a branch point
What this says is that I started adding feature x, did some refactoring, stopped to fix a bug and continued my refactoring after.
Just because things happened in this order is no reason that history must say they did. I guess I like the Back to the Future theory of time travel better than Terminator.
Since I haven't shared these changes yet, I can fix up my history.
git co fix-bug-370
git rebase v1.2
I now have
And a couple more times:
git co refactor-some-service
git rebase fix-bug-370
git co add-feature-x
git rebase refactor-some-service
So that I now have
Which when I eventually do
git co v1.2
git merge add-feature-x
Will produce a nice linear history in the order things should have happened.