Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I quickly check which Git branch is the newest?

Tags:

git

git-branch

For example if have 4 branches on git like this:

branch1
branch2* (current branch)
branch3 (newest commits here)
master (oldest)

My questions are:

  • How can I check if my current branch is the newest right from the git command line? If not, which branch is the most up-to-date? I mean which branch contains the latest commits?

  • How can I list all the commits in this git repository (in any branches) which are newer than my branch without switching away from the current branch?

like image 202
TaoPR Avatar asked Feb 10 '23 15:02

TaoPR


1 Answers

Edit: You'll find relevant shell scripts in this GitHub repo of mine.

Which branch is the newest?

[...] which branch is the most up-to-date? I mean which branch contains the latest commits?

I interpret this as

Of all the local branches, find the one whose tip is the most recent (in some sense, e.g. in terms of committer date).

git for-each-ref comes in handy for this; this Swiss-Army-knife command is well worth the time going through its man page.

Command

Let's build the command we need step by step...

  1. This first command prints a list of the (short) names of all the local branches.

    git for-each-ref --format='%(refname:short)' \
                     refs/heads
    
  2. This next command does the same thing, but sorts the results by committer date, in descending order (note the -):

    git for-each-ref --sort='-committerdate'     \
                     --format='%(refname:short)' \
                     refs/heads
    
  3. This next command does the same as the previous one, but restrict the output to just one entry:

    git for-each-ref --count=1                   \
                     --sort='-committerdate'     \
                     --format='%(refname:short)' \
                     refs/heads
    

In summary, we now have a command that prints the (short) name of the most recent (in terms of committer date) branch reference: exactly what we want. Great!

Make it an alias

For convenience, let's define an alias (called newest-branch below) based on it:

git config --global alias.newest-branch "for-each-ref --count=1 --sort='-committerdate' --format='%(refname:short)' refs/heads"

Sanity check

Now, let's run some tests in the Git-project repo:

$ git branch
  maint
* master
  next
  pu
$ git newest-branch
pu

# Now print the list of all branches and the committer date of their tips
$ git for-each-ref --sort='-committerdate' \
                   --format="%(refname:short)%09%(committerdate)"
                   refs/heads
pu      Tue Mar 17 16:26:47 2015 -0700
next    Tue Mar 17 16:14:11 2015 -0700
master  Tue Mar 17 16:05:12 2015 -0700
maint   Fri Mar 13 22:57:25 2015 -0700

pu is indeed the most recent branch. Yay!


Is the current branch the newest?

That's easy, now that we have our newest-branch alias; all we have to do is compare the name of the current branch to that of the newest one. (For more robustness, you may want to use the full refname rather than the short one).

Command

The (short) name of the current branch is given by

$ git symbolic-ref --short HEAD
master

Let's compare that to the newest branch, and then print yes if the current branch is the newest, or no otherwise.

if [ $(git newest-branch) = $(git symbolic-ref --short HEAD) ]; then
    printf "yes\n"
else
    printf "no\n"
fi

Make it an alias

Great! For convenience, let's define an alias (called isnewest below) for this as well:

git config --global alias.isnewest '! if [ $(git newest-branch) = $(git rev-parse --abbrev-ref HEAD) ]; then printf "yes\n"; else printf "no\n"; fi'

Sanity check

(We already know, from the previous sanity check, that pu is the newest branch.)

$ git branch
  maint
* master
  next
  pu
$ git isnewest 
no
$ git checkout pu
Switched to branch 'pu'
Your branch is up-to-date with 'origin/pu'.
$ git isnewest
yes
$ git checkout maint
Switched to branch 'maint'
Your branch is up-to-date with 'origin/maint'.
$ git is-newest-branch 
no

Seems to work (•_•) ( •_•)>⌐■-■ (⌐■_■)


How can I list all the commits in this git repository (in any branches) which are newer than my branch without switching away from the current branch?

If you mean newer in terms of some date, it's a hard problem. In the worst case, you'd have to explore the whole DAG, because Git doesn't forbid parents to have more recent dates than their children. If you means in terms of topological order, then it's much easier:

git log --branches HEAD..

(The --branches flag limits the output to commits that are reachable from at least one of the refs/heads.) Of course, you can tweak the output of that command by adding such cosmetic flags as --oneline, --decorate, etc.

like image 53
jub0bs Avatar answered Feb 13 '23 08:02

jub0bs