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?
Edit: You'll find relevant shell scripts in this GitHub repo of mine.
[...] 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.
Let's build the command we need step by step...
This first command prints a list of the (short) names of all the local branches.
git for-each-ref --format='%(refname:short)' \
refs/heads
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
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!
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"
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!
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).
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
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'
(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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With