一个`git log`标记的提交方式如何?

dav*_*ers 7 git

我想要git log对master分支上的所有标记提交(以及没有任何未标记的提交).这可能吗?

tor*_*rek 7

对此的秘诀是要意识到git log使用相同的规则git rev-list.后一个命令有一个--tags标志来查看标签.因此,与目前为止的其他答案一样,如果您愿意查看所有标记的提交,则此单个命令将执行此操作:

git log --no-walk --tags
Run Code Online (Sandbox Code Playgroud)

(--no-walk防止这开始使用标签并查找所有父提交,以及父母的父母,等等.)

但是你要求"主分支上的标记提交",我假设这意味着(在技术术语中)"提交既由标记指向并且可以通过master分支到达".这实际上更难(git rev-list可以设置联合通过--stdin --no-walk,但似乎没有办法设置交集).以下是找到正确的commit-ID的几种方法,但有各种缺点:

  1. 首先制作两个文件列表:"所有标记的提交"和"所有可从主服务器访问的提交":

    git rev-list --tags --no-walk > /tmp/all-tags
    git rev-list master > /tmp/all-master
    
    Run Code Online (Sandbox Code Playgroud)

    现在只打印仅出现在两个文件中的行.该comm工具可以做到这一点.据记载,期望对文件进行排序,但在我看到的所有实现中,文件只需要按照相同的顺序排列,因此无需预先排序即可实现:

    comm -12 /tmp/all-tags /tmp/all-master
    
    Run Code Online (Sandbox Code Playgroud)

    缺点:需要两个临时文件(除非你使用特殊的bash语法/dev/fd); 没有排序可能无法工作; 需要comm.

  2. 和以前一样,但用于uniq -d生成列表.这确实确实需要排序,但可以消除使用管道的临时文件:

    (git rev-list --tags --no-walk; git rev-list master) | sort | uniq -d
    
    Run Code Online (Sandbox Code Playgroud)

    缺点:需要排序.提交以某种奇怪的顺序出现,而不是您通常会看到的顺序git log.

  3. 编写您自己的实用程序,它基本上执行该comm方法将执行的操作,但调用git rev-list自身(可能是一个使用创建临时文件mktemp来创建唯一名称的脚本).

    缺点:需要更多的工作.:-)

在所有情况下,一旦你有了commit-ID列表,你只需要将它们传递给git log --no-walk,例如:

git log --no-walk $(comm -12 /tmp/all-tags /tmp/all-master)
Run Code Online (Sandbox Code Playgroud)