views:

984

answers:

2

What would possibly cause a 'git push' to try and commit to two branches? I have my own branch I'm working on, which is on the shared repo... and a master branch. Right now I just wanted to push to my personal branch which went through just fine, but it also tried to push to master and got rejected. Looked something like this:

foo$ git push
Counting objects: 38, done.
Delta compression using 2 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (21/21), 9.73 KiB, done.
Total 21 (delta 14), reused 0 (delta 0)
To ssh://example.com/project.git
   8184634..86b621e  mybranch -> mybranch
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to 'ssh://example.com/project.git'

My config looks like this:

remote.origin.url=ssh://example.com/project.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.mybranch.remote=origin
branch.mybranch.merge=refs/heads/mybranch

Esko notes that it's pushing to both because they're in my config. What if I want to push to both, just not simultaneously? When I have mybranch checked out and I git push, I clearly mean to push mybranch and not master. There's times when I'll checkout master, edit code, and want to commit/push that also. Is there a way for both to co-exist?

+5  A: 

When using git push without any arguments, it will push all local branches that have a corresponding remote branch with the same name. Since your local repository has branches masterand mybranch, and also the remote repository has branches masterand mybranch, then Git will push both of them.

If you want to push only one branch, you can say to Git explicitly that which branch you want to push: git push origin mybranch

If you want to push master, you can fix that error by first pulling from master. Git complains about the merge being non-fast forward, because somebody else has pushed a commit to master since the last time that you pulled from master.

Esko Luontola
What if I do want to push both of them, just not at the same time? There's times I will want to push just mybranch, and there's times when I'll merge mybranch into master and want to push master. What does one do in that case?
Coocoo4Cocoa
You can always explicitly name the branch that you want to push, using the form "git push <repository> <branch>". See http://www.kernel.org/pub/software/scm/git/docs/git-push.html
Esko Luontola
Newer versions of git allow you to specify this behavior.
Dustin
Not true. Git pushes both branches because 'push matching' (push those branches which are present on both local side, and on remote you push to) is the default behavior.
Jakub Narębski
@Jakub: I have now corrected the answer. Thanks for telling.
Esko Luontola
A: 

If you want to push only current branch, you can use "git push origin HEAD", or perhaps even "git push HEAD" (with modern git).

The default behavior if no refspec for push (you have defined refspec for fetch in your config, but not for push) is to push matching refs. From git-push(1):

git push [...] [<repository> <refspec>...]

<refspec>...

The special refspec : (or +: to allow non-fast forward updates) directs git to push "matching" branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side. This is the default operation mode if no explicit refspec is found (that is neither on the command line nor ...

Jakub Narębski
When I run "git push" with a new(er) git (say 1.6.3.1), I get a huge warning, saying that I should set push.default or the repository should configure push refspecs.I can't for the life of me figure out how to do the second thing. Google hasn't been helpful. (I would like to configure the reository, because the potential push'ers to my repositories will be confused/annoyed with the big fat warning, and I don't want them to have to configure anything after "git clone ...")
asjo
You configure (set up) remote.<remotename>.push, where <remotename> would be probably in your case 'origin', and <refspec> to use for mirror sync push to bare repository would be "+refs/heads/*:refs/heads/*" (and the same for tags)
Jakub Narębski