【问题标题】:GIT show all commits from branch missing in master using git cherry and formatGIT 使用 git cherry 和格式显示 master 中缺少的分支的所有提交
【发布时间】:2016-08-18 14:23:54
【问题描述】:

我想使用git cherry 显示所有提交到特定分支但在主分支中丢失的提交,并使用漂亮的格式记录。

我试过了:

git cherry master branch_name | grep "^+" | sed 's/^+ //' | xargs -I {} git --no-pager log --pretty=format:'%h,%an,%d,%ae,%ad,%s' --date=short -1 {}

这样做是为了:

  1. git cherry master branch_name - 在终端中逐行列出所有在 branch_name 中而不在 master 中具有代码的提交的哈希值,反之则在哈希值前加上 + 或 - 号。

  2. grep "^+" - 仅获取以 + 开头的那些(实际上是 master 中从 branch_name 中缺少的那些)

  3. sed 's/^+ //' - 从行中删除+,这样我们就可以只获取哈希值了。

  4. xargs -I {} git --no-pager log --pretty=format:'%h,%an,%d,%ae,%ad,%s' --date=short -1 {} - 将每个哈希作为参数传递给 git log 以显示每个哈希的格式化日志。这里--no-pager 表示退出 git 日志窗口,-1 表示仅显示 1 次提交。

这样做的问题是,它开始将 git cherry 返回的每个散列的每个结果连接到同一行。它不会逐行执行,因此我可以复制粘贴它们,也可以使用... > tmp.csv 将它们保存到 csv 文件中。

不知道除了xargs 是否还有其他我可以使用的东西,或者这实际上是 git log 的问题并且这不起作用。

我错过了什么?我做错了什么?

谢谢大家,很抱歉成为菜鸟。

【问题讨论】:

  • 您可以在 xargs 之前将| tr ' ' '\n' 添加到您的管道中以用换行符替换空格吗? (或者用空值替换,并使用xargs -0。)
  • 在格式字符串的末尾添加%n作为换行符。
  • @Mort tr 在这里如何提供帮助,没有空格,sed 会处理这个问题。
  • @ElpieKay 没错,这是解决此问题的一种方法,但我实际上正在寻找解释为什么会发生这种情况以及什么是更好的方法。无论如何,感谢您快速修复我当前的设置。
  • @RaduM 似乎是由--no-pager 引起的。

标签: git command-line-interface branching-and-merging xargs git-cherry


【解决方案1】:

您使用了--pretty=format:...。请注意there is a --pretty=tformat:... as well,并且这是默认设置

提交格式

--pretty[=<format>], --format=<format>

       以给定格式漂亮地打印提交日志的内容...当 [不是预定义格式,如短、中、单行等]并且其中包含 %placeholder 时,它的行为就像@给了987654325@。

...

       tformat: 格式的工作方式与 format: 完全相同,只是它提供了“终结者”语义而不是“分隔符”语义。换句话说,每个提交都附加了消息终止符(通常是换行符),而不是在条目之间放置分隔符。这意味着单行格式的最终​​条目将正确地以新行终止...

--pretty=tformat:... 形式因此可以缩写为--format=...

简化:--no-walksed 技巧

除此之外,还有一种更好(更有效)的方法可以达到预期的效果。您仍然可以像这样使用git cherry,并像以前一样使用sed 去除标记。您可以省略grep,因为sed 也可以这样做:使用sed -ns/pattern/replacement/p。而且,既然您已经选择了正确的提交,那么您可以将它们全部作为参数提供给一个 git log 命令,并使用 --no-walk 使 git log 查看提供的哈希值,而不是他们的任何祖先。

也就是说,而不是:

git cherry master branch_name | grep "^+" | sed 's/^+ //' | xargs -I {} \
    git --no-pager log --format='%h,%an,%d,%ae,%ad,%s' --date=short -1 {}

你可以这样做:

git log --no-walk --format='%h,%an,%d,%ae,%ad,%s' --date=short \
    $(git cherry master branch_name | sed -n 's/^+ //p')

(您现在也可以像我一样省略--no-pager,因为它足够安全,可以让寻呼机运行)。

但其实都是内置的

如果git loggit rev-list 本质上不是相同的命令,这将是可行的方法——但事实上,git loggit rev-list 采用所有相同的提交选择参数。此外,git cherry 主要只是 git rev-list 的前端,1 所以有一种更有效的方法来做到这一点:

git log --right-only --cherry-pick --format="$format" master...branch

$format 是您想要的格式。 (我认为-仅获取左/右,正确的cherry-pick/cherry-mark参数有点棘手;这是基于对手册页的快速浏览和对您的问题的草率阅读.)


1当使用git cherry<limit> 参数时,我不确定你是否可以从git rev-list 得到相同的结果,尽管^<limit> 可能会起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 2018-04-16
    • 1970-01-01
    • 2014-02-22
    • 2019-08-14
    • 1970-01-01
    • 2016-10-03
    相关资源
    最近更新 更多