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 {}
这样做的目的是:
git cherry master branch_name
- 在终端中逐行列出代码在 branch_name 而不是在 master 中的所有提交哈希,反之则使用 + 或 a - 在散列前签名。
grep "^+"
- 仅获取以 + 开头的那些(实际上 branch_name 中缺少的那些)
sed 's/^+ //'
- 从行中删除 +
这样我们就可以只得到散列。
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-walk
和 sed
技巧
除此之外,还有一种更好(更有效)的方法可以达到预期的效果。您仍然可以像这样使用 git cherry
,并像以前一样使用 sed
去除标记。您可以省略 grep
,因为 sed
也可以这样做:使用 sed -n
和 s/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 log
和 git rev-list
采取了所有相同的提交选择参数。此外,git cherry
主要只是 git rev-list
、1 的前端,因此还有一种更有效的方法:
git log --right-only --cherry-pick --format="$format" master...branch
其中 $format
是您想要的格式。 (我 认为 — 仅获得 left/right,cherry-pick/cherry-mark 参数正确有点棘手;这是基于快速浏览手册页和有些草率的阅读你的问题。)
1 将 git cherry
与 <limit>
参数一起使用时,我不确定您是否可以从 git rev-list
获得相同的结果,尽管 ^<limit>
可能有效。
我想使用 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 {}
这样做的目的是:
git cherry master branch_name
- 在终端中逐行列出代码在 branch_name 而不是在 master 中的所有提交哈希,反之则使用 + 或 a - 在散列前签名。grep "^+"
- 仅获取以 + 开头的那些(实际上 branch_name 中缺少的那些)sed 's/^+ //'
- 从行中删除+
这样我们就可以只得到散列。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
.
不确定 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 likeformat:
, 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-walk
和 sed
技巧
除此之外,还有一种更好(更有效)的方法可以达到预期的效果。您仍然可以像这样使用 git cherry
,并像以前一样使用 sed
去除标记。您可以省略 grep
,因为 sed
也可以这样做:使用 sed -n
和 s/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 log
和 git rev-list
采取了所有相同的提交选择参数。此外,git cherry
主要只是 git rev-list
、1 的前端,因此还有一种更有效的方法:
git log --right-only --cherry-pick --format="$format" master...branch
其中 $format
是您想要的格式。 (我 认为 — 仅获得 left/right,cherry-pick/cherry-mark 参数正确有点棘手;这是基于快速浏览手册页和有些草率的阅读你的问题。)
1 将 git cherry
与 <limit>
参数一起使用时,我不确定您是否可以从 git rev-list
获得相同的结果,尽管 ^<limit>
可能有效。