【问题标题】:How do I pass a range of commits to git log?如何将一系列提交传递给 git log?
【发布时间】:2016-09-16 11:32:04
【问题描述】:

好吧,我放弃了,我是 Bash 菜鸟。

这个:

$ git log --no-walk --oneline 6980e6ecede8e188f434f6da669c2297f28decfe 458567536c1f20498da033cb0e42da74439ef12e

打印:

4585675 NNN bethDataFiles, allBethFiles belong to game/game/constants.py
6980e6e NNN bethDataFiles, allBethFiles belong to game/game/constants.py

这个:

git log -g --pretty=format:'%ai %H' | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'| cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '

向我打印一系列提交:

ba4ee4b099d23642e6cad56d9f41974f6e767781 1daaede0f4e11cae0e0bb00b9ebb43bba4f5671 ...

现在为什么要将此命令传递给 git log,如下所示:

git log -g --pretty=format:'%ai %H' | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'| cut -d' ' -f 4 | awk '!a[$0]++' | tr '\r\n' ' ' | git log --format='%h %s %ai' --no-walk

只显示第一次提交:

ba4ee4b _load_active_plugins pre BAPI code - superseded by games.py API: 2016-04-14 19:38:41 +0200

?

$ git --version
git version 2.6.1.windows.1

【问题讨论】:

    标签: git bash git-log


    【解决方案1】:

    git log 不会从标准输入读取任何输入。 尝试做echo "abcd123" | git log --no-walk 你会注意到 git log 将忽略标准输入。它将查找指定为参数的提交哈希,但没有。 因此,它将使用默认的 HEAD,并在您当前的分支上打印最新的提交。

    要打印提交范围,例如:

    如果你知道第一个和最后一个提交哈希:

    git log abcd123..4567abc
    

    如果你知道时间间隔:

    git log --since="10 days ago" --until="5 days ago"
    

    或者如果您知道具体日期:

    git log --since="2016-04-13" --until="2016-04-15"
    

    【讨论】:

    • 谢谢,这消除了混乱,但我想打印关于那些不是连续范围的特定提交的信息。
    • 实际上,git rev-list 确实 有一个--stdin 参数,并且由于git loggit rev-list 共享他们的大部分代码,结果git log 有一个(未公开的)--stdin 也是。
    • 编辑评论太晚了:我检查了文档,--stdin 实际上是广告。
    【解决方案2】:

    bash 和 Unix 实用程序有一个通用形式:

    ... | ... | ... | xargs cmd
    

    (在将标准输入作为参数插入后,xargs 会根据需要多次运行 cmd),或者:

    cmd $(... | ... | ...)
    

    它运行管道,然后将其输出作为参数提供给cmd

    但是,对于 git log,您不需要它,因为它接受 --stdin 让它从标准输入读取修订 ID。

    我认为我们可以简化您的管道(顺便说一下,我没有意识到某些版本的 awk 知道如何直接比较日期;旧的 awk 不知道):

    git log -g --pretty=format:'%ai %H' | \
        awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' | \
        cut -d' ' -f 4 | awk '!a[$0]++' | tr '\n' ' '
    

    我们希望每行一个修订,因此不需要tr。我们还可以使用原始的 awk 来检查哈希 ID 的唯一性。所以:

    git log -g --pretty=format:'%ai %H' | \
        awk '$0 >= "2016-04-13" && $0 <= "2016-04-15" && !a[$4]++ { print $4 }' | \
        git log --no-walk --stdin
    

    顺便说一句,只是因为git log -g 进行了 reflog walk(这可能会产生重复的哈希),我们才需要关联数组 a 来丢弃重复的哈希。

    (根据comment 编辑,但仍未经测试)

    【讨论】:

    • “只是因为 git log -g 做了一个 reflog walk(这可能会产生重复的哈希),我们需要关联数组 a 来丢弃重复的哈希”——是的,我意识到了这一点。感谢您清理我的 noobish 管道 - 我添加了 tr,因为我认为输入为 \n 分隔可能会有所不同 - 这是我在黑暗中击中
    • cut -d' ' -f 4 在最后一个示例中应该仍然是必需的,不是吗?
    • @JoshKlodnicki:如果我做得对,就不会。请注意,此测试 a[$4],而不是 a[$0]$4 来自 %ai %H 生产,例如,2021-08-16 12:15:44 -0700 225bc32a989d7a22fa6addafd4ce7dcd04675dbf。与$0 (而不是$1 $2 $3 放在一起)比较似乎有点不确定,除非您使用的awk 明确表示它使用日期和时间(可能是偏移量,也可能不是)然后停止,但我从原帖中得到的,没有仔细测试过。
    • @torek 是的,awk 工作正常,但git log --stdin 需要一个提交哈希列表(不包括日期)。我建议在 awk 之后添加 cut,除非我遗漏了什么。当然,在 awk (print $4) 中选择字段可能会更好。
    • @JoshKlodnicki:哦,我明白了,完全正确!好吧,这就是未经测试的代码所发生的事情。 :-) 我将编辑 awk 以添加 { print $4 }...
    【解决方案3】:
      git log --format='%h %s %ai' --no-walk \
           $(git log -g --pretty=format:'%ai %H' \
                 | awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"'\
                 | cut -d' ' -f 4 | awk '!a[$0]++' | tr '\r\n' ' '
            )
    

    或者稍微好一点

      git log -g --pretty=format:'%ai %H' | \
            awk '$0 >= "2016-04-13" && $0 <= "2016-04-15"' |\
            cut -d' ' -f 4 | awk '!a[$0]++' | \
            xargs git log --format='%h %s %ai' --no-walk
    

    但我想知道你为什么不想使用git log--since--until 选项?

    【讨论】:

    • 感谢这项工作,但您能否详细说明这两个方面的差异以及为什么第二个更好?至于我为什么使用--since 和 co:stackoverflow.com/q/37311494/281545
    猜你喜欢
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2011-12-07
    • 2015-10-05
    • 2022-11-17
    • 2012-11-19
    • 2015-04-02
    • 2011-06-26
    相关资源
    最近更新 更多