It's been a while :) but... I've been researching some aspects of how git works, and stumbled upon this issue again. I came up with the following explanation (of how `push.default = matching` works): > In this mode `git push` pushes matching branches, i.e. all local branches that exist in a remote, to their remote counterparts (if there's a local branch `ba` and a remote branch `origin/ba`, it pushes `ba` to `origin/ba`): > > * First it chooses a remote: > > * if the current branch has an upstream, it chooses the remote the upstream points to > > * else if there's only one remote, it chooses this only remote > > * else it chooses `origin` if it exists > > * otherwise it fails > > * Then it pushes matching branches to the remote. > > * If the upstream of the current branch is in the local repo, there can be no matching branches by definition (there can't be 2 branches with the same name in a repository). > > * It never chooses a non-matching branch, even if it's an upstream. If `ba` has an upstream `origin/ba2` and there's `origin/ba`, it will choose `origin/ba`. More in the following gist: https://gist.github.com/x-yuri/0ac53cb7999b3b0352c1ec0ac8f5f4cc The description given in the documentation: > matching - push all branches having the same name on both ends. This makes the repository you are pushing to remember the set of branches that will be pushed out (e.g. if you always push maint and master there and no other branches, the repository you push to will have these two branches, and your local maint and master will be pushed there). One can sort of make an argument that the remote repository kind of remembers the branches you push to it, but... if you delete the local branch that you just pushed, does that make the remote repository forget that you pushed the branch?.. The analogy is flawed. And confusing, because it's not at all clear that the state is stored "by the list of the branches". Also a lot of aspects of how `push.default = matching` works are left out. Regards, Yuri