Reputation: 4940
I have master
branch and I have the following configurations set.
branch.master.remote=github
branch.master.merge=refs/heads/master
push.default=simple
Now I wanted to test behaviour of push.default
. I did
git branch master1 // This created a new branch on same commit as master
git checkout master1
git push github
Now, since my local branch name is master1
and it is new branch , it does not have any upstream set with it. Why did not git push github
showed me error message to use --set-upstream
flag ?
Also, it successfully created master1
branch on remote repo. Also, I see no remote tracking branch with it upon running git branch -vv
master 42f18f8 [github/master] Some message
master1 42f18f8 Some message
However, if I had just done git push
while being on master1
branch , then it asks for --set-upstream
.
Also, I dont have remote.github.push
or remote.master1.push
set.
Upvotes: 0
Views: 359
Reputation: 488471
Let's take this in two parts.
git push
and upstreamsFirst: git push
, with no additional arguments, will (usually—depending on settings, which I won't go into here), looks at the upstream setting of the current branch.
If there isn't an upstream on the current branch, you get:
fatal: The current branch <branch> has no upstream branch.
(followed by configurable advice to use git push --set-upstream
; if you configure it away, you won't get the advice).
If there is an upstream, you don't get that error. That's all there really is to it. If there is an upstream set, git push
won't tell you to set one. If not, it will give you an error, and (unless you've configured the advice away) suggest that you set one.
Second, git push
with additional arguments behaves differently. Edit: the next bit was wrong. The crucial additional argument here was the github
argument. See jthill's answer for details. I've left the rest in strikeout because it can apply in some situations as well.
But you did not run:
git push github
You actually ran:
git push github master1
(Check your command history.) If you supply a refspec argument, which this four-word git push
command does, the refspec supplies the branch names—both the one used locally, and the one your Git requests that their Git set. There's no need for the current branch, nor for any upstream settings of any branches.
git branch
or git checkout -b
and upstreamsBoth git branch
and git checkout
can create new branch names.
A branch name can have an upstream set, or not set.
Therefore, when git branch
or git checkout
creates a new branch name, they have the option of setting an upstream.
Their actual behavior is configurable, using branch.autoSetupMerge
and branch.autoSetupRebase
. Their default behavior, though, is this:
HEAD
as the starting commit when creating the new branch, and do not set an upstream.Since git branch master1
does not supply a starting commit, the new name is created using the hash ID to which HEAD
resolves, and it has no upstream. Hence your git branch -vv
showed no upstream set.
The exact details of all of the possible interactions between all the different settings (push.default
, remote.<name>.push
, and others) can mess with all of this. I mention this primarily because you mentioned that you have not set any of these. If you do, some or all of the above may be invalidated. The Git documentation covers some, but not all possible, combinations.
Where it says that some combination is supposed to behave in some particular manner, it should behave that way. Otherwise, it may behave in any way the Git coders felt was convenient for them. Be careful when configuring options: some combinations have probably never been tested.
Upvotes: 0
Reputation: 60305
I think you missed the second paragraph of the simple
docs:
When pushing to a remote that is different from the remote you normally pull from, work as current. This is the safest option and is suited for beginners.
and you're pushing to a remote that is not the remote you normally pull from. So it works as "current", "push the current branch to update a branch with the same name on the receiving end".
Git's trying to avoid newbies doing unintentional damage while still being as helpful as possible, exactly what needs to be allowed or prevented by default is always going to be a bit befuddling because rookie mistakes are too.
Upvotes: 2