5

I like to use git status --short in a simple script to check if all repos are unchanged.

I want to know if there are commits which are not pushed yet.

I checked the help of git status and found no way to output this message:

Your branch is ahead of origin/master by 1 commit

if things are not pushed, and nothing if everything is ok.

I could use git status and ignore lines by using grep, but that is no nice solution.


Goal:

  • Output nothing if no changes were made and no push is missing
  • Brief output if changes are there and push is missing
Community
  • 1
  • 1
guettli
  • 26,461
  • 53
  • 224
  • 476

2 Answers2

7

The help of "git status" does actually show the option you can use:

-b
--branch
  Show the branch and tracking info even in short-format.

The format is different in --short mode, but it's there:

$ git status --short --branch
## master...origin/heads/master [ahead 2]
[...]                           ^^^^^^^^^

If you don't care about the output format, git status --short --branch internally runs the equivalent of git rev-list --left-right @...@^{upstream} and interprets its results. You can run git rev-list directly. It will give output if and only if your current branch and your remote branch are different, by giving you the commits that are in your current branch but not in your remote branch (ahead), as well as commits that are in your remote branch but not in your current branch (behind), in a diff-style format.

Ahead:

$ git rev-list --left-right @...@{upstream}
<baa782ec4590a91d9835c36ad33f7681e4a859d5
<8b6255249bc08e2f14d8b6f31bab83b9c48cb698

Behind:

$ git rev-list --left-right @...@{upstream}
>0e0140fbf6f903aa7205063eac5b8cf6e268ab3b

Both:

$ git rev-list --left-right @...@{upstream}
<a7992ac7127b37d24b00fbecf67156688285be15
>0e0140fbf6f903aa7205063eac5b8cf6e268ab3b

You can optionally use git log instead of git rev-list and use its regular format options (such as --oneline) to tailor the output format to your liking.

Or you can change the --left-right @...@{upstream} to just @{upstream}..@ if you don't care about incoming changes, only about unpushed changes.

  • the three dots at the end are misleading; since he asks for "brief" output. I tested this and got only the line you specified. What else could be shown where you show the [...] ? – Chris Maes Feb 11 '16 at 10:00
  • @ChrisMaes The names of files with uncommitted changes will be shown there, even in `--short` mode. –  Feb 11 '16 at 10:01
  • 3
    Yes, this shows `[ahead 2]` but unfortunately, it outputs `## master` even if everything is unchanged. This question has the constraint, that if no changes are there no output should happen. – guettli Feb 11 '16 at 12:36
  • @guettli Then `git status` cannot do it, I think. Answer edited to provide an alternative. (Note: you may want to combine that with `git status --short`, without the `--branch`, to get info about uncommitted changes.) –  Feb 11 '16 at 12:54
  • @hvd ok. I can call git twice, no problem. Thank you. – guettli Feb 11 '16 at 13:00
3

That's because your local branch is not "configured to track" the matching remote branch.

This is a bit counter-intuitive (for novices) but the background is that you might have several remotes (those thingies like your "origin") which you communicate with, and patterns of these communications may be complicated.

You might opt to explicitly mark your local branch as "tracking" the single remote branch, and once you will have done that certain Git commands will start hint you about how these two "linked" branches relate in terms of their histories.

To set a local branch "foo" track a remote branch "origin/foo" use

git checkout foo
git branch --set-upstream-to origin/foo

(you can use -u instead of --set-upstream-to).

There's also an older (and harder to use) --track command-line option:

git branch --track foo origin/foo

(Note that in this case the command requires the name of the local branch to be explicitly spelled out.)

There are other ways to set a branch track a remote branch:

  1. On push:

    git push -u foo origin
    

    would push "foo" to "origin" and set it to track "origin/foo" at the same time.

  2. On initial creation using a shortcut command:

    git checkout origin/foo
    

    would create a local branch "foo" pointing to the same commit "origin/foo" is pointing at, and would set up tracking information right away.

To get better results, please make yourself familiar with the concept of remote branches in Git.

kostix
  • 43,267
  • 10
  • 69
  • 137