Without any additional command line options git push's behavior is almost never what I actually want it to do, since I rarely wish to push more than one branch at once, and often work with multiple remotes where I have push access.

Even though I am generally in the habit of always supplying both the remote and a list of refs when pushing (git push <remote> <ref1> [..<refN>]) I'd rather not have anything potentially dangerous or unwanted happen if I happen to leave off the ref(s) (or very rarely both the remote and the ref(s)).

By default Git will first pick a remote to use for the push by checking the value of branch.${current-branch}.remote. You can see which remote this will be by running the command shown below. Git will skip this bit if you specify the remote but still leave off the ref(s) to push.

Show the default push remote for current branch

git config branch.$(git rev-parse --abbrev-ref HEAD).remote

Next, Git will compare the list of local branches with the list of remote branches in the remote repository found earlier, and will attempt to update all branches with the same name.

This automatic discovery of not only the remote to use, but also what to push is almost never going to end up being what I want. Thankfully, since 1.6.3 Git has had a configuration option (push.default) to specify what the default behavior should be. This config option is fully documented from git help config.

My preferred setting is nothing (do not push anything), since leaving off the ref is almost always an error given how I work with Git. I used to use the current (push the current branch to a branch of the same name) setting, but found that the few times I did leave off the ref portion of the push command, it was almost always in error.

By setting git config --global push.default nothing, it forces me to be explicit about where I wish to push, and what I wish pushed there every time I run git push. While this may seem like a bit of a pain, it is a small hurdle that I quickly got used to. It also significantly lessens the likelihood that I am going to affect the remote repository in unexpected ways, which is a huge win when I'm working with shared repositories (whether they're internal "corporate" repositories, or public open source projects).