1

I have a local branch foo which is set up, I thought, to track remote branch PROJ-123-foo.

But when I tried a simple

git push

on that branch, I got a fatal error:

fatal: The upstream branch of your current branch does not match the name of your current branch.
To push to the upstream branch on the remote, use

    git push origin HEAD:PROJ-123-foo

To push to the branch of the same name on the remote, use

    git push origin HEAD

This made no sense to me, because as I said, I thought my local branch was already indelibly associated with branch PROJ-123-foo on the remote. I thought I had already set things up so that the local and remote branch names were different, i.e. so that git wouldn't think I wanted to "push to the branch of the same name on the remote".

I tried to confirm what remote branch name I had configured, but here I ran into further difficulties. I ran git help branch without finding any useful options. I found the question Find out which remote branch a local branch is tracking, which seemed to be exactly what I was asking, but the answers there make no sense to me. In desperation I peeked at .git/config, and found the lines

[branch "foo"]
    remote = origin
    merge = refs/heads/PROJ-123-foo

which seemed to confirm that the association was at least something like what I thought.

Next I noticed the text

To choose either option permanently, see push.default in 'git help config'.

at the bottom of the original error message. I feel really bad saying this, because someone was clearly trying to anticipate my needs there, and I appreciate that, but: the problem is that I don't understand the options available to me under push.default, either.

So my questions are:

  1. Was I wrong to imagine that local branches are always tied pretty firmly to remote branches, such that git push should always know exactly what to do?

  2. Is part of my problem that my local branch isn't tied firmly enough to my remote? I've heard that there are potentially two distinct remote associations; perhaps I'm missing the one for pushing?

  3. Do I maybe want to set push.default to upstream? The documentation says that's for a "central workflow". I'm not sure I know which workflow I think I'm using, but I think I thought it was closer to "flow". Nevertheless I do think that lots of my local branches are bolted 1:1 onto same- or similarly-named branches in our gitlab server. I'm not sure how to convince myself that upstream is the right choice, that it doesn't have unsuspected downsides that might bite me later, that another choice might be better.

  4. If the answer is "just use push.default = upstream", is there a reason that's not the default? (I suspect I'm missing something.)

  5. Is there a better way to confirm (or set) remote branch associations, or should I just peek at the config file?

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • *How* did you set up the local branch `foo` to track the remote branch `PROJ-123-foo`? – Jim Redmond May 03 '23 at 18:21
  • @JimRedmond I don't remember exactly, or I would have said. I did (like I always do) an initial `git push`, and it gave me the error it always does, telling me the command I have to run to do the initial push and set up the initial association, and I ran the command it told me to, but editing it slightly to set the different name on the server. – Steve Summit May 03 '23 at 18:24
  • `git status` should show you what remote branch your currently checked out branch is tracking, if any. – TTT May 03 '23 at 18:57

2 Answers2

2

Yes, push.default = upstream is completely what you (and the majority of Git users) want.

No, there isn't a separate "push target" configuration for branches, besides branch.<name>.merge. There's just

  • push.default = upstream, which will use branch.<name>.merge (the same place you pull from) as the push target,
  • push.default = current, which will use the local branch name as the push target,
  • push.default = matching, which will use the local branch name as the push target and push all branches, not just the current one, and
  • push.default = simple, which will use the local branch name as the push target if it matches, or yell at you and do nothing if it doesn't match.

So why is simple the default when it seems like it can't possibly make anyone happy? I'm not sure, but I suspect it has something to do with the fact that, for many years, the default was matching — which was terrible and inconvenient — and in order not to surprise people who got used to that, they made the new default also terrible and inconvenient (but at least it won't push to an unexpected destination without manual intervention).

People who never use local branch names that are different from the remote one won't notice anyway; people who do will trip over the error, and then they will have to set matching or current (if they really like the old behavior), or upstream (if they use git the way that 99% of people use git).

hobbs
  • 223,387
  • 19
  • 210
  • 288
0

git help config and hunt up push.default. You're expecting it to be set to upstream, git config --global push.default upstream sets it as your‚ uhh, default default.

  1. Was I wrong to imagine that local branches are always tied pretty firmly to remote branches, such that git push should always know exactly what to do?

Yes, that's wrong. All repositories are peers. Any correspondence between what's in different repositories is entirely a matter of collaboration or coincidence.

  1. Is part of my problem that my local branch isn't tied firmly enough to my remote? I've heard that there are potentially two distinct remote associations; perhaps I'm missing the one for pushing?

Yes, you can configure any fetch and push work flow you want, the really common ones (like fetch from upstream and push to qa) are drop-dead easy.

  1. Do I maybe want to set push.default to upstream? The documentation says that's for a "central workflow".

If you want Git to behave the way that makes it behave, then that's what you want to set it to, yes.

  1. If the answer is "just use push.default = upstream", is there a reason that's not the default? (I suspect I'm missing something.)

It's not the default because there are many more workflows than just that, and because getting practice at setting things up to suit exactly how you want to work is so valuable it's worth making everyone do a few trivial configs just to get the flavor of things.

  1. Is there a better way to confirm (or set) remote branch associations, or should I just peek at the config file?

git branch -vv is the usual convenience command to look, git branch -u to set.

jthill
  • 55,082
  • 5
  • 77
  • 137