Agile Git Workflow
geewax.org
geewax.org
1. Branch off of master to work on the feature
2. Work, work, work, commit, commit, commit
3. Pull down any updates to master
4. Rebase and squash the feature branch to master’s HEAD
5. Merge the feature branch back to master
6. Push up to the shared repository
Their Rational for Step 6:"When you’re ready to share this feature with the rest of your team, they probably won’t care about all your interim commits (for example, you added and then changed feature.py). We can package up all the commits into one big commit (sort of like the one big patch against master you used before) by using git’s rebase command."
Some of the history that was used in developing the feature may be useful for someone else trying to a) figure out how the code works or b) trying to fix a bug in the program. By chunking the development of the feature into on patch you eliminate the nuances which would have helped later on.
Even beyond the development concerns, version control systems have great power to model your actual development process. Not just the one that is on paper, but the one that produces the code which ships. By eliminating history of development you loose the ability to discover this useful information. So don't rebase your feature branch merge into the mainline.
The best approach I have found is to use merge --no-ff to merge the feature branch to the master branch. This lets you both keep the history and group the feature's commits together.
1. Branch off of master to work on the feature.
2. Work, work, work, commit, commit, commit
3. Pull down any updates to master
4. Rebase the feature on master without squashing the commits
5. Merge the feature branch back to master
6. Push up to the shared repositoryLike all things in programming, discretion is key and obviously it can be overdone, but anecdotally, I've found that it makes the history so much more useful to lump related changesets together.
In short, categoricals like "don't do it, you'll lose history" don't really hold much water for me. Of course it can be over done. But done right, it really is a great feature of git and a god-send on larger projects (check out the actual git source log for an example).
A. Rebase on top of master, keeping all commits; or
B. Merge the branch, keeping branch history.
[1] Obviously squashing has good uses, too, within the branch. Maybe you want to squash together all commits for a particular feature's implementation (while still keeping the specs for same in a separate commit, hopefully).
I agree with you that if you have a longer-lived branch that's shared among repositories, you'll want to see that merge in the history and optionally squash some of the commits as needed. For short lived topic branches, I often like to squash down to a single commit.
1d9322f Added model & migration for feature x
3fa93f9 Unit tests for feature x
38ce239 Fixed intermittent failure in test_feature_x_foo
6728eca Added view and css for feature x
8fed23d Added missing background image for feature x
392ea84 Refactored feature x controller to handle foobaz
Instead of littering the master branch with those 6 commits, wouldn't it be nice to have just: 84fac31 Added feature x with tests and support for foobaz
This has the advantage of1) Less noise in history, so easier to page through and see what has happened
2) The feature is in a single commit, so I can more easily cherry-pick it into a release branch if I need it
3) Impressing your co-developers as it looks like you got it right the first time