有什么方法可以在概念上直接输出 [一个] 命令 [作为另一个命令的参数]?
Shell(sh 或 bash 或您使用的任何 shell 命令解释器)通常都有执行此操作的方法。
有两种常见的拼写,一种使用反引号,方便非常短的项目,另一种使用$(...),因为它嵌套正确,所以总体上更好。
git branch --contains 的问题在于它的输出格式不正确:如果它打印的包含给定提交的分支名称之一是当前分支,它将打印*。您必须做一些事情来删除星号,或者使用更面向命令的命令。后者通常更好,但要求您的 Git 不能太旧(2.6 或更高版本):将 git branch --contains <rev> 替换为 git for-each-ref --contains=<rev> --format='%(refname)' ref/heads。
现在,您不能将其转换为--branches= 的一组全局模式,用于git log,但您不需要,因为--branches=<glob> 所做的只是告诉@ 987654334@ 从匹配refs/heads/<glob> 的引用开始,git for-each-ref 已经生成此类引用的完整列表。所以您需要做的就是将完整的引用列表传递给git log。
由于 shell 还将 $name 扩展为包含某个名称的变量,因此我将在下面使用它而不是 <...>,否则它会模棱两可(它可能意味着文字小于号等)。这给出了:
git log $log_args $(git for-each-ref --contains=$rev --format='%(refname)')
如果您的git for-each-ref 太旧而无法处理--contains,则必须使用git branch --contains 并去掉前两列,例如:
git log $log_args $(git branch --contains $rev | cut -c3-)
这有一个缺陷,因为git branch 没有在分支名称前加上refs/heads。如果你有一个名为xyzzy 的分支和一个名为xyzzy 的标签也,git branch 知道使用 branch 名称,并且--branches=xyzzy 会知道使用 branch 而不是 tag,但只需在命令行上命名 xyzzy 即可获得标签,因为通常标签具有更高的优先于分支。 (请参阅the gitrevisions documentation,其中列出了解析名称所采取的六个步骤:将其作为标记尝试是第 3 步,将其作为分支尝试是第 4 步。标签具有更高的优先级。)要解决这个问题——避免this xkcd——你需要多花点心思:
git log $log_args $(git branch --contains $rev | cut -c3- | sed s,^,refs/heads,)
例如。 (当然,另见this xkcd。)