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

 ̄綄美尐妖づ 提交于 2019-12-10 15:15:58

问题


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...

  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.




回答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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!