I often find that I'm in the middle of one thing when I have to do another. Whether it's hotfixes for a client, or just finding a minor bug that blocks my current work, or needing to add components to a feature before I can add custom functionality.
The best way is to stash your current work, checkout the master branch, commit, then go back. If you're working on a feature branch (and you should be), then rebase that afterwards so you have access to the new work there. So that's:
$ git stash
$ git checkout master
// do commits
$ git checkout feature
$ git rebase master
$ git stash pop
But that's not always feasible. Sometimes I'm sloppy, and I've already made code changes before stashing. And lately, I've got one instance of Party module that's got a feature branch that's made database changes, but I don't want to hold that up ongoing commits (and I'm too lazy to set up a new local site!).
If your fix is just one commit, you can make it on the feature branch, then cherrypick it to the master branch like this:
// make your commit and note its SHA
$ git stash
$ git checkout master
$ git cherry-pick COMMIT
$ git checkout feature
$ git rebase master
The rebase should be smart enough to figure out the same commit exists on both branches, and will silently drop it from the feature branch.
Alternatively, if you want to do a chunk of main branch work, make a temporary branch on the tip of feature, which you can then move to the master branch when you're done:
$ git checkout -b moveme
// make as many commits as you like
// Now we take everything that's between the tips of feature and moveme, and move it to the tip of master
$ git rebase --onto master feature moveme
// Now merge moveme into master: this'll just fast-foward master.
$ git checkout master
$ git merge moveme
// moveme can be deleted now
$ git branch -d moveme
// Now rebase the feature branch
$ git checkout feature
$ git rebase master
As I've become more familiar with git, I've found that temporary, throw-away branches can be useful in a variety of situations. Another one is making a backup branch prior to potentially messy rebases: just create a branch 'backup' where you are to be sure that no matter what happens with the rebase, your current chain of commits will be preserved. If there are conflicts, you can diff against it to check no code was lost. And when you're happy with the result of the rebase, just delete it. Branches being cheap, and local, opens up a whole new set of uses for them.