【问题标题】:What does `git show` with two nonoption arguments mean?带有两个非选项参数的 `git show` 是什么意思?
【发布时间】:2019-06-18 12:32:23
【问题描述】:

git show 的手册页说

git show [<options>] [<object>…]

来自https://stackoverflow.com/a/7196615

git show some_commit_sha1 -- some_file.c

命令是什么意思?

some_commit_sha1some_file.c &lt;object&gt; 都是参数吗?

和这个一样

git show -- some_commit_sha1 some_file.c

谢谢。

【问题讨论】:

  • 您省略了| git apply -R 部分,它将显示文件的输出从另一个提交传递到补丁。
  • 此时我在问git show
  • 不错。不过,您是在断章取义地接受这个答案。
  • 我从零开始

标签: git


【解决方案1】:

它们都不是&lt;object&gt; 参数,而且这里的文档也不是很好。但是,git show 是一个面向用户的(“瓷器”)命令,首先使用它来管道到其他 Git 命令通常不是好的做法。

在这种特殊情况下,git show &lt;commit&gt; -- &lt;path&gt; 最终会调用 git log --no-walk --cc &lt;commit&gt; -- &lt;path&gt; 的等效项。也就是说,它首先运行与git log --no-walk 相同的代码来为该特定提交生成日志消息,根据任何格式指令格式化(无,因此默认为--pretty=medium)。然后它会生成一个差异列表,即使提交是一个合并提交——默认情况下,git log 不会为合并提交生成一个差异列表,因此--cc 选项。

各种git diff 命令——包括git diff 本身,以及管道变体git diff-treegit diff-filesgit diff-index——都允许您指定特定的路径名​​或路径规范。通常很清楚某个东西是路径名(例如,README.txt)还是提交说明符(例如,master)。但也有一些模棱两可的情况:如果您有一个名为 master文件 怎么办?

为了在这些模棱两可的情况下将路径名/路径规范参数与提交说明符区分开来,这些命令使用the POSIX specifications for utility commands 定义的-- 约定(具体参见指南10)。那就是:

git diff-tree master -- develop

告诉git diff-tree,你想要的commitmaster,你关心的文件被命名为develop,而:

git diff-tree develop -- master

告诉git diff-tree提交develop文件master,并且:

git diff-tree develop master -- release

告诉git diff-tree两个提交依次是developmaster,而文件release。请注意,git diff-tree 最多需要两个 &lt;tree-ish&gt; 参数:当只给出一个这样的参数时,这意味着一个参数是一个提交说明符,Git 应该区分提交的父级和提交。

结论

  1. 为了可靠性(避免被各种diff 配置项绊倒,例如通过color.diff=always 强制使用颜色序列),您链接的答案中的命令实际上应该是:

    git diff-tree -p <commit> -- <file> | git apply -R
    

    diff-tree-p 选项打开-r 选项。

  2. git show 文档,尤其是大纲行,是不够的。改进,不一定是完整的,应该是:

    git show [<options>] [<object>...] [--] [<path>...]
    

【讨论】:

  • 谢谢。你能解释一下git show some_commit_sha1 -- some_file.c | git apply -R 的作用吗?
  • 由于git show 调用了git log -p --ccgit diff-tree -p 的等效项,因此您可以从父级到子级获得更改。如果有多个父级,这个组合的 diff 作为一个补丁是无用的,整个事情不会产生任何有用的东西,但是如果提交有一个父级,则 diff 的输出可以作为一个补丁使用(参见the old patch utility) , 而git apply 将其视为一个。 -R 标志告诉 git apply 补丁应该被反转,所以它是反向应用的:[继续下一条评论]
  • 如果补丁说,例如“删除第 30 行,它曾经由以下文本组成:...”,Git 将 插入 一行,其中包含文本。如果补丁显示“插入第 45 行,包含以下文本:...”,Git 将删除第 45 行,前提是它包含该文本。如果有足够的上下文,则使用上下文来定位应该删除或插入行的位置(如果它们已移动)。
  • 由于 diff 输出显示了某人在该提交中 一个特定文件做了什么,因此反向应用同一补丁的 git apply -R 尝试 撤消 完全相同的东西,在同一个文件中。这并不总是可能的,因为自相关提交以来可能发生了额外的变化,但如果它可能的,那就是它所实现的。请注意,这与git revert 的目标相同,除了(1)我们只查看一个文件,以及(2)由于git revert 执行三向合并,因此在补丁失败的情况下它可以成功。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
相关资源
最近更新 更多