GIT 使用 git cherry 和格式显示 master 中缺少的分支的所有提交

GIT show all commits from branch missing in master using git cherry and format

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

我试过这个:

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 中的所有提交哈希,反之则使用 + 或 a - 在散列前签名。

  2. grep "^+" - 仅获取以 + 开头的那些(实际上 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 日志 window 和 -1 仅显示 1 次提交。

这个问题是它开始连接同一行上从 git cherry 返回的每个散列的每个结果。它不会逐行执行,所以我可以复制粘贴它们,或者我可以使用 ... > tmp.csv.

将它们保存到 csv 文件中

不确定 xargs 是否还有其他我可以使用的东西,或者这是否真的是 git 日志的问题,这不会起作用。

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

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

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

Commit Formatting

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

       Pretty-print the contents of the commit logs in a given format ... When <format> is [not a predefined format like short, medium, oneline, etc] and has %placeholder in it, it acts as if --pretty=tformat:<format> were given.

...

       The tformat: format works exactly like format:, except that it provides "terminator" semantics instead of "separator" semantics. In other words, each commit has the message terminator character (usually a newline) appended, rather than a separator placed between entries. This means that the final entry of a single-line format will be properly terminated with a new line ...

因此 --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 log 本质上不是与 git rev-list 相同的命令,这将是要走的路——但实际上,git loggit rev-list 采取了所有相同的提交选择参数。此外,git cherry 主要只是 git rev-list1 的前端,因此还有一种更有效的方法:

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

其中 $format 是您想要的格式。 (我 认为 — 仅获得 left/right,cherry-pick/cherry-mark 参数正确有点棘手;这是基于快速浏览手册页和有些草率的阅读你的问题。)


1git cherry<limit> 参数一起使用时,我不确定您是否可以从 git rev-list 获得相同的结果,尽管 ^<limit> 可能有效。