3

I can run these commands and get expected output

$ git branch --track test
$ git checkout test
$ touch hello.txt
$ git add hello.txt
$ git commit -m hello.txt
$ git status
On branch test
Your branch is ahead of 'master' by 1 commit.

However here is where my issue is

$ git checkout master
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

I want to know if I am ahead of origin/master, but I also want to know if I am behind test. I am looking for a command to give me something like this:

On branch master
Your branch is up-to-date with 'origin/master'.
Your branch is behind 'test' by 1 commit, and can be fast-forwarded.
Zombo
  • 1
  • 62
  • 391
  • 407

1 Answers1

3

There is no such thing built in, and tracking is stored only in the other direction: "X tracks Y", not "Y is tracked by ...", which is more complex as the "..." part can expand to more than one item. (Also, I believe it's much more typical for Y to be a remote-tracking branch in the first place, in which case you can't ever be on Y—though a command that tries to find "what tracks Y" could certainly take arguments, so you could say "tell me about any of my branches that track origin/master).

That said, it's certainly possible to build such a thing. The algorithm looks like this, in Python-esque pseudo-code:

table = {}
for branch in local_branches:
    try:
        remote, tracked = get_what_branch_tracks(branch)
    except ValueError:
        continue # local branch "branch" not tracking anything
    try:
        br2 = analyze(branch, remote, tracked)
    except ValueError:
        warn('upstream for %s is gone' % branch)
        continue
    # at this point br2 is, e.g., origin/master or a local branch that "branch" tracks
    table.setdefault(br2, []).append(branch)

# now table[] is a table of branches that are tracked, with
# each table[key] being the branches that track branch "key"

So now for any interesting branch(es) that are in table, you simply count revisions find-able in the various branch pairs, the same way git status does, which in shell is just:

# to compute "git status" for branch X that tracks Y:
nahead=$(git rev-list --count Y..X) # we're ahead $nahead commits
nbehind=$(git rev-list --count X..Y) # and behind $nbehind

If you're behind but not ahead, you can fast-forward.

The details for get_what_branch_tracks are simply to do some git config --gets, of branch.branch.remote and of branch.branch.merge, while the details for analyze are more complex: if remote is . then whatever is in tracked is simple, but if it's an actual remote, whatever is in tracked must be passed through the corresponding fetch lines to find the appropriate remote-tracking branch.

Zombo
  • 1
  • 62
  • 391
  • 407
torek
  • 448,244
  • 59
  • 642
  • 775