问题
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?
回答1:
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...
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!
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.
回答2:
You can use:
git log --decorate --all --oneline --graph
From: man git log
--decorate
: Print out the ref names of any commits that are shown.--all
: Pretend as if all the refs in refs/ are listed on the command line as<commit>
.--oneline
: This is a shorthand for--pretty=oneline --abbrev-commit
used together.--graph
: Draw a text-based graphical representation of the commit history on the left hand side of the output.
If you want to download the latest objects and refs from the remote repository, execute git fetch
previously:
git fetch origin
Also, the command:
gitk
can help you to see all the commits and refs in a simple graphical interface.
来源:https://stackoverflow.com/questions/29169162/how-can-i-quickly-check-which-git-branch-is-the-newest