(Or: The very basics of git squash, rebasing, and merging)
Pick a feature to work on.
Create a new branch (and push it upstream):
git checkout -b gm_new_feature
git push -u origin gm_new_feature
Here the GM prefix indicates that the branch belongs to "GM", and is therefore unsafe for others to work on (since GM may rewrite history).
Work as normal. My practice is to push upstream frequently, as backup.
git commit -m "hacking X"
git commit -m "X was a bad idea, doing Y instead"
Finish the feature.
If master has moved along in the meantime, we want to expose any merge conflicts now:
git rebase master
If there are conflicts, fix them, then do
git add and
git rebase --continue.
Now we want to rewrite our commit messages, and squash away some commits. We do this as a separate step so we don't have to think about rewriting commits and merging at the same time.
git rebase -i master
(In the editor, it'll be oldest on top, not newest on top like in most git guis. So 'squash' means to meld this commit into the older one.)
Push the newly-tidied branch back upstream. We need to --force this because we're rewriting history. We can safely do that because the branch is marked with "gm".
git push --force
Now that our branch is tidy, apply it to master:
git checkout master
git merge gm_new_feature