2

I have just read this question/answer:

what-exactly-does-the-u-do-git-push-u-origin-master-vs-git-push-origin-ma

However I am still a little unclear on a couple of points:

  1. If I forget to do git push -u origin myBranch, and instead I simply do git push origin myBranch, can I correct it by then doing a git push -u origin myBranch?

It seemed to work, because when I do a git branch -vv I can see that both the origin/master and myBranch are tracked.

But is that correct? - should they both be tracked or have I got it wrong by doing this?

  1. Is doing git push -u <remote> HEAD really equivalent to git push -u origin myBranch?

  2. Finally I would like to put down an example of what I did just to make sure there are no issues with the way I am working.

Here is my little scenario...

# Recursive clone to to get the submodules
git clone <URL> -b topLevel --recursive
# Create my branch
git branch myBranch
# Now switch to my branch
git checkout myBranch
# Now add my branch to the remote
git push origin myBranch
# ...make some local changes...
git commit -am "did some changes"
# Oops I forgot to do the tracking... but I want to push my changes up...
git push -u origin myBranch
# Finally go into development loop:

# ... Do some changes...
git commit -am "did some changes"
git push
# repeat
Community
  • 1
  • 1
code_fodder
  • 15,263
  • 17
  • 90
  • 167
  • When you do `git push origin myBranch` Git will by default set your local `myBranch` to use `origin/myBranch` to track the remote. So I am not sure what you are trying to achieve here. – Tim Biegeleisen Feb 13 '17 at 14:09
  • @TimBiegeleisen Just trying to use parameter-less "git push" and "git pull". I am trying to get my head around weather I am doing things right or not. There seem to be lots of answers out there that suggest that your your first action on creating a branch should be `git push -u origin myBranch` to setup the upstream tracking... your comment suggests that you don't need to do this at all? - you can simply use `git push` and `git pull` straight away? – code_fodder Feb 13 '17 at 14:41
  • Also - someone is very harsh to -1 this question. I have done my research and come up short. I have an example. I have a (couple of ) clear question... don't really see the problem.... feed back would be useful – code_fodder Feb 13 '17 at 14:43
  • Yes, you don't need to do this, unless you want to point to a different remote tracking branch. This is an atypical use case in my experience. I have upvoted you to counter. – Tim Biegeleisen Feb 13 '17 at 14:46
  • @TimBiegeleisen ah thanks for that confirmation (and the up-vote counter). If you want to stick that in as an answer I will mark it up : ) – code_fodder Feb 13 '17 at 14:56

2 Answers2

1
  1. There is nothing to correct. You've done nothing wrong. Adding the -u just adds an upstream tracking reference so that in the future you can use an argumentless git pull without needing to specify the remote and branch. If you forget the -u, just use it next time. (You can also set up tracking manually if you'd prefer.)

  2. If your remote and origin are the same thing (which is likely if you cloned your repo from the remote in question), and if HEAD and myBranch are the same thing (which is likely if you're currently working on myBranch), then yes, those are equivalent.

  3. There is no problem in your example scenario.

pattivacek
  • 5,617
  • 5
  • 48
  • 62
  • Thanks very much for the answers. I guess HEAD refers to a particular "commit-hash" (one of those long IDs, probably got the terminology wrong here). Just one question then - Tim comments that you don't need to do any of this to use parameter-less `git pull/push`. I am not trying to cross-check his comment - I am sure its correct because I was just testing it.... but there are lots of answers out there suggesting that I need to do the `git push -u origin myBranch` first... so probably I just don't need to do any of this :o – code_fodder Feb 13 '17 at 15:02
  • Tim is right, you only really need to do this if you are trying to point a local branch to a remote branch with a different name, i.e. `git push -u origin master:other` with push local `master` to remote `other`. – pattivacek Feb 13 '17 at 15:21
  • Thanks for the explanation... that whole tracking branch with a different name sounds confusing! – code_fodder Feb 13 '17 at 15:49
  • 1
    It is, but there are uses for it. I've only ever had to do that once or twice, and I guess I'd assumed you were doing something like that here! Since you aren't, you are definitely overthinking it. – pattivacek Feb 13 '17 at 16:01
1

Just for total clarity (if that's possible with Git :-) ), there are a couple of mostly-independent pieces here.

Every (local) branch can have one upstream. The upstream setting has several older names, but let's stick with "upstream" because it's the best name. :-) This upstream is what determines the parameter-free git push and git merge and git rebase. (I recommend avoiding git pull entirely at this point—all it does is run git fetch and then either git merge or git rebase, and it's better to manually control whether you do a merge or a rebase, until you're really familiar with Git so that you can recognize which one it did when things go wrong, as they always do eventually. Usually rebase is better anyway, and pull defaults to merging. You can reconfigure pull's default, but unless you're as obsessed with keystroke counting as the Git folks seem to be, I say: don't bother.)

There are many ways to set the upstream. (Note, by the way, that there's only one upstream—or, if you un-set it, no upstream. The point here, though, is that there are never two or more upstreams.) Once set, it gives you a bunch of conveniences. Besides the parameter-free commands, git status tells you more stuff, for instance.

The most direct way to set it is git branch --set-upstream-to.1 You can set the current branch's upstream:

git branch --set-upstream-to origin/zorg

or set some other branch's upstream:

git branch --set-upstream-to origin/zorg my-other-branch

(I'm using different local and remote-tracking branch names in this example, which is generally a bit unwise, but then again, why do you want to set your upstream to evilness? :-) ).

The thing is, the argument to --set-upstream-to—the remote-tracking branch name—has to be the name of an actual, existing remote-tracking branch that is there in your own repository right now. (Remember, a remote-tracking branch name is something in your repository. It's just called "remote-tracking" because your Git automatically updates it to what your Git sees on their Git, when you git fetch from the remote.)

When you create a new branch—one that doesn't exist on the remote yet—your own Git doesn't have a remote-tracking branch yet either. How could it? Your remote-tracking branches come from the remote, and they don't have it yet! So this means you can't use git branch --set-upstream-to, at least, not yet.

Once you do git push this new branch, your remote will have the branch, and your Git will add the corresponding remote-tracking branch. Then you'll be able to use git branch --set-upstream-to. But, quelle horreur, that requires typing in two commands! Hence, git push grew a --set-upstream aka -u option, so that you can tell your Git: "do this push, and then do the --set-upstream-to thing too." Because we all know that using two commands, like git fetchentergit rebase, is far too much to type when we could type git pull --rebase instead. Why, that saves three whole keystrokes!

(Slightly more seriously, the -u option to git push also works around complaints that can happen depending on how you have push.default configured. So it not only reduces keystrokes, it sometimes reduces confusion.)

Unless you need to change the upstream setting for some reason, you need only set it once. You can do that any time after the first push with git branch, or during the first push with -u, or any time after the first push with another push with -u. This just re-sets it.


1There is also git branch --set-upstream. One might think, given the Git programmers' obsession with fewer keystrokes, that this would be the command to use. But it has the wrong argument order: it got this shorter name by virtue of being put into git branch first. Then they found that people kept getting the arguments wrong, so they added the longer command-option.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Nice explanation... and entertaining along with it (+1 just for that : ) ... to be honest, I am probably one of those keyboard-illiterate software engineers with a phobia of pressing too many keys, so I am fully up for `git pull--rebase` option :o – code_fodder Feb 13 '17 at 16:41