0

For many repos of mine, for all of which an upstream has been correctly set and is reported by the git remote --v command, yet, when I commit locally and before I have pushed to the server, only for some repos it tells me helpfully the message:

$ git status
  Your branch is ahead of 'whatever/upstream' by n commits.

Whereas for others, it always says only:

$ git status
  nothing to commit, working tree clean.

When clearly, my local repo is a few commits forward than the remote.

I figure it has something to do with the way I created the local repo, whether by cloning an existing remote repo or by git init and then setting an upstream and pushing? But I can't be sure.

Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336
  • If you have committed commits on the branch and not pushed, that's what git status will show **for that branch**. If you switch to another branch where you haven't done this, it won't show that. Can you give more details about why you expect it to show that for other branches as well? – Lasse V. Karlsen Dec 29 '18 at 12:08
  • @LasseVågsætherKarlsen I am asking for branches of different repos where in both cases, the branch clearly has more "unpushed" commits in the local repo than in the upstream. Probably has something to do with the way the repo is set up? – Water Cooler v2 Dec 29 '18 at 12:10
  • 1
    The current branch does not have an upstream or is in detached HEAD state. – ElpieKay Dec 29 '18 at 12:15
  • @ElpieKay The branch has a remote upstream set, because when I run the `git remote --v` command, it tells me the remote upstream name and url. I forgot what the detached HEAD state means. I recall vaguely it had to do with several use-cases (for e.g. when you've moved the HEAD to an earlier commit, or are in the middle of a rebase, or a cherry-pick, etc.) I will read up on it again. Meanwhile, could you explain that in a few easy to understand sentences? – Water Cooler v2 Dec 29 '18 at 12:19
  • Not exactly a duplicate, but see https://stackoverflow.com/q/43408030/1256452 – torek Dec 29 '18 at 12:24
  • `git remote -v` prints the *remote(s)*, not the upstream(s). `git branch -vv` prints the upstream of each branch. – torek Dec 29 '18 at 12:53
  • @torek Ah, that *must* be it. Thanks. Amma check and come back on dat one. – Water Cooler v2 Dec 30 '18 at 06:58

1 Answers1

1

The git status command does many things—probably the most important is that it runs two git diffs, to figure out how your HEAD commit, your index, and your work-tree relate to each other—but the first few things it does are:

  • Print the name of the current branch, if you're on a branch.
  • Print counts for ahead and/or behind, if you're on a branch and that branch has an upstream set and the counts are nonzero.

You can disable the ahead/behind counts using --no-ahead-behind, or enable them with --ahead-behind. (The default is enabled.)

To compute the counts, Git uses git rev-list --count. For specifics on how this works, see git branch ahead and behind for local branch? Note that the counting is based on the branch's upstream setting, so if you are on branch B and its upstream is origin/B, this is the result of counting commits that are reachable from your branch B but not from your remote-tracking name origin/B, and vice versa. If origin/B is not up to date with B on origin, this count is not as useful as you might want; run git fetch origin to update it as needed.

Each branch has its own separate upstream setting. Any one branch name can have one upstream, or no upstream. The upstream is pretty commonly a remote-tracking name (origin/whatever) but it can be any name, including other ordinary local branch names. The git branch --set-upstream-to command, or git branch --unset-upstream, is the main modern way to manipulate the upstream setting of any existing branch name. (The actual setting is complicated and can be modified through git config or by editing .git/config.)

As for the detached HEAD mentioned in comments, a detached HEAD simply means that you are not on a branch. This mode is normal when you have asked for it, either via git checkout --detach or by using git checkout on something that is not a branch name. It's also normal, as you mention, when you are in the middle of a rebase operation that has yet to complete. In these cases, modern git status produces an informative message telling you that you are in this detached HEAD mode, and (to some extent) why.

Since a detached HEAD has no upstream—only branch names have upstream settings—there is never any ahead/behind count for this mode.

torek
  • 448,244
  • 59
  • 642
  • 775
  • You're right. The branch in one of my repos did not have an upstream set even though a remote was set. I had forgotten about the `--set-upstream-to` until your answer reminded me of it. Thanks much. :-) – Water Cooler v2 Dec 31 '18 at 14:43