And it turns out it's not that bad! The git book has a good page introducing it with nice pictures:
http://git-scm.com/book/en/Git-Branching-Rebasing
and I'll describe how I applied it to my particular situation.
Scenario
I have been pulling from a repository at origin/develop, but also making local changes and committing them to my local repository. Now I want to push some (but not all) of the changes to origin/develop.Procedure
First, I wanted to see how my local repository (currently on branch develop) differed from origin/develop:git diff --name-status origin/develop..develop
Now if I wanted to make all of those changes, I can just do git push origin, and it would be done. Instead I want to make a subset of those changes, but I can't just arbitrarily pick changes because maybe some of them depend on previous commits.
That's how rebase helps: it lets us re-order the commits. It puts all of the remote changes first (this makes pushing trivial), and then it applies our local changes in whatever order we tell it to. So we do:
git rebase -i origin/develop
and this opens up a text editor with all the local changes that have happened since we first diverged from origin/develop. We can rearrange the commits, collapse multiple commits into one using squash, and do all sorts of other things that are covered in this tutorial. In my case, I simply moved the changes I wanted pushed to the top of the list.
Once we save and close this file, git-rebase will try to apply each of those changes, in sequence, using origin/develop as a starting point. This may not proceed entirely smoothly, especially if you have re-ordered some commits.
Once this is finished, I go find the hash of the last commit I want pushed and push all the commits up to that one:
git push origin 1fc6c95:develop
And that's that!