简体   繁体   English

一个 `git log` 如何只标记提交?

[英]How does one `git log` tagged commits only?

I'd like to git log all the tagged commits on the master branch (and none of the untagged commits).我想在 master 分支上git log所有标记的提交(并且没有任何未标记的提交)。 Is this possible?这可能吗?

The secret trick to this is to realize that git log uses the same rules as git rev-list .对此的秘密技巧是意识到git log使用与git rev-list相同的规则。 The latter command has a --tags flag to look at tags.后一个命令有一个--tags标志来查看标签。 So, as with the other answers so far, if you're willing to look at all tagged commits, this single command will do it:因此,与迄今为止的其他答案一样,如果您愿意查看所有标记的提交,则此单个命令将执行此操作:

git log --no-walk --tags

(The --no-walk prevents this from starting with tags and finding all their parent commits, and the parents' parents, and so on.) --no-walk阻止从标签开始并查找所有父提交和父提交等。)

But you asked for "tagged commits on the master branch", which I assume means (in technical terms) "commits that are both pointed to by tags and reachable via the master branch".但是您要求“在 master 分支上标记提交”,我认为这意味着(在技术术语中)“由标记指向可通过master分支访问的提交”。 This is substantially harder ( git rev-list can do set union via --stdin --no-walk , but seems to have no way to do set intersection).这要困难得多( git rev-list可以通过--stdin --no-walk设置并集,但似乎无法设置交集)。 Here are several methods of finding the right commit-IDs, with various drawbacks:以下是几种找到正确提交 ID 的方法,但存在各种缺点:

  1. First make two file lists: "all tagged commits" and "all commits reachable from master":首先制作两个文件列表:“所有标记提交”和“所有提交可从主提交”:

     git rev-list --tags --no-walk > /tmp/all-tags git rev-list master > /tmp/all-master

    Now just print lines that appear only in both files.现在只打印只出现在两个文件中的行。 The comm utility can do this. comm实用程序可以做到这一点。 It's documented to expect the files to be sorted, but in all implementations I have seen, the files merely need to be in the same order, as it were, so this works without pre-sorting:它记录在案,希望对文件进行排序,但在我见过的所有实现中,文件只需要按相同的顺序排列,就像这样,因此无需预先排序即可工作:

     comm -12 /tmp/all-tags /tmp/all-master

    Drawbacks: needs two temporary files (unless you use the special bash syntax that uses /dev/fd );缺点:需要两个临时文件(除非你使用特殊的bash语法/dev/fd ); might not work without sorting;没有排序可能无法工作; requires comm .需要comm

  2. Same idea as before, but use uniq -d to produce the list.与之前的想法相同,但使用uniq -d生成列表。 This really does require sorting, but you can eliminate the temporary files using a pipe:确实需要排序,但可以消除使用管道的临时文件:

     (git rev-list --tags --no-walk; git rev-list master) | sort | uniq -d

    Drawback: requires sorting.缺点:需要排序。 The commits come out in some strange order, not the order you would normally see with git log .提交以某种奇怪的顺序出现,而不是您通常使用git log看到的顺序。

  3. Write your own utility that basically does what the comm method would do, but invokes git rev-list itself (perhaps a script that creates temp files using mktemp to make unique names).编写您自己的实用程序,该实用程序基本上可以执行comm方法的功能,但会调用git rev-list本身(可能是一个使用mktemp创建临时文件以生成唯一名称的脚本)。

    Drawback: requires a lot more work.缺点:需要做更多的工作。 :-) :-)

In all cases, once you have the list of commit-IDs, you just need to pass them to git log --no-walk , eg:在所有情况下,一旦您拥有提交 ID 列表,您只需将它们传递给git log --no-walk ,例如:

git log --no-walk $(comm -12 /tmp/all-tags /tmp/all-master)

There are probably lots of ways of going about this, but here's one that I think will do what you want:可能有很多方法可以解决此问题,但我认为这里有一种方法可以满足您的需求:

git tag | 
xargs -iCID git --no-pager log -1  CID

另一种选择,但遵循相同的思路:

git tag | xargs git show --quiet

A lot has happened in Git since 2014;自 2014 年以来,Git 发生了很多事情; modern users may find this command useful for this purpose:现代用户可能会发现此命令对此很有用:

git log --simplify-by-decoration --tags --pretty='tformat:%C(auto)%h %as%d %s'

And if you want to include other decorations (like branches), just remove --tags :如果您想包含其他装饰(如分支),只需删除--tags

git log --simplify-by-decoration --pretty='tformat:%C(auto)%h %as%d %s'

Alternatively, you may find this useful:或者,您可能会发现这很有用:

git tag -l --format='%(tag) %(taggerdate:short) %(objectname:short) %(subject)'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM