Git 中文参考(三)

2024-06-26 14:12:18 浏览数 (3)

原文:Git Reference 协议:CC BY-NC-SA 4.0

git-mergetool

原文: git-scm.com/docs/git-mergetool

名称

git-mergetool - 运行合并冲突解决工具来解决合并冲突

概要

代码语言:javascript复制
git mergetool [--tool=<tool>] [-y | --[no-]prompt] [<file>…​]

描述

使用git mergetool运行多个合并实用程序之一来解决合并冲突。它通常在 git merge 之后运行。

如果一个或多个< file>给出参数,将运行合并工具程序以解决每个文件的差异(跳过那些没有冲突的文件)。指定目录将包括该路径中的所有未解析文件。如果没有< file>如果指定了名称, git mergetool 将在每个具有合并冲突的文件上运行合并工具程序。

OPTIONS

代码语言:javascript复制
 -t <tool> 
代码语言:javascript复制
 --tool=<tool> 

使用< tool>指定的合并解析程序。有效值包括 emerge,gvimdiff,kdiff3,meld,vimdiff 和 tortoisemerge。运行git mergetool --tool-help以获取有效< tool>的列表设置。

如果未指定合并解析程序, git mergetool 将使用配置变量merge.tool。如果未设置配置变量merge.toolgit mergetool 将选择合适的默认值。

您可以通过设置配置变量mergetool.&lt;tool&gt;.path显式提供工具的完整路径。例如,您可以通过设置mergetool.kdiff3.path配置 kdiff3 的绝对路径。否则, git mergetool 假定该工具在 PATH 中可用。

可以通过指定要在配置变量mergetool.&lt;tool&gt;.cmd中调用的命令行来自定义 git mergetool 来运行备用程序,而不是运行其中一个已知的合并工具程序。

当使用此工具调用 git mergetool 时(通过-t或--tool选项或merge.tool配置变量),将在BASE设置为名称的情况下调用配置的命令行包含合并公共基础的临时文件(如果有); LOCAL设置为包含当前分支上文件内容的临时文件的名称; REMOTE设置为包含要合并的文件内容的临时文件的名称,MERGED设置为合并工具应写入合并解析结果的文件的名称。

如果自定义合并工具正确指示合并解析及其退出代码成功,则配置变量mergetool.&lt;tool&gt;.trustExitCode可以设置为true。否则, git mergetool 将提示用户在自定义工具退出后指示分辨率是否成功。

代码语言:javascript复制
 --tool-help 

打印可能与--tool一起使用的合并工具列表。

代码语言:javascript复制
 -y 
代码语言:javascript复制
 --no-prompt 

在每次调用合并解析程序之前不要提示。如果使用--tool选项或merge.tool配置变量显式指定了合并解析程序,则这是默认值。

代码语言:javascript复制
 --prompt 

在每次调用合并解析程序之前提示,以便为用户提供跳过路径的机会。

代码语言:javascript复制
 -g 
代码语言:javascript复制
 --gui 

当使用-g--gui选项调用 git-mergetool 时,将从配置的merge.guitool变量而不是merge.tool中读取默认合并工具。

代码语言:javascript复制
 --no-gui 

这将覆盖先前的-g--gui设置,并且将从配置的merge.tool变量中读取默认合并工具。

代码语言:javascript复制
 -O<orderfile> 

按照< orderfile>中指定的顺序处理文件,每行有一个 shell glob 模式。这会覆盖diff.orderFile配置变量(参见 git-config [1] )。要取消diff.orderFile,请使用-O/dev/null

临时文件

git mergetool在解析合并时创建*.orig备份文件。一旦文件合并并且其git mergetool会话已完成,可以安全地删除它们。

mergetool.keepBackup配置变量设置为false会导致git mergetool在文件成功合并时自动删除备份。

GIT

部分 git [1] 套件

git-log

原文: git-scm.com/docs/git-log

名称

git-log - 显示提交日志

概要

代码语言:javascript复制
git log [<options>] [<revision range>] [[--] <path>…​]

描述

显示提交日志。

该命令采用适用于git rev-list命令的选项来控制显示的内容和方式,以及适用于git diff-*命令的选项,以控制每个提交引入的更改的显示方式。

OPTIONS

代码语言:javascript复制
 --follow 

继续列出重命名以外的文件历史记录(仅适用于单个文件)。

代码语言:javascript复制
 --no-decorate 
代码语言:javascript复制
 --decorate[=short|full|auto|no] 

打印出所有提交的引用名称。如果指定 _ 短 _,则引用名称前缀 refs / heads /refs / tags /refs / remotes / 将不会打印。如果指定了 full ,将打印完整的引用名称(包括前缀)。如果指定了 auto ,那么如果输出到达终端,则 ref 名称显示为 short ,否则不显示 ref 名称。默认选项为 _ 短 _。

代码语言:javascript复制
 --decorate-refs=<pattern> 
代码语言:javascript复制
 --decorate-refs-exclude=<pattern> 

如果没有给出--decorate-refs,假装好像所有参考都被包括在内。对于每个候选人,如果它与--decorate-refs-exclude给出的任何模式匹配或者与--decorate-refs给出的任何模式都不匹配,请不要将其用于装饰。

代码语言:javascript复制
 --source 

打印出在每个提交到达的命令行上给出的引用名称。

代码语言:javascript复制
 --use-mailmap 

使用 mailmap 文件将作者和提交者名称以及电子邮件地址映射到规范的真实姓名和电子邮件地址。见 git-shortlog [1] 。

代码语言:javascript复制
 --full-diff 

如果没有此标志,git log -p &lt;path&gt;...将显示触摸指定路径的提交,并显示相同指定路径的差异。这样,就会显示完全差异,以便接触指定的路径。这意味着“< path> …”仅限制提交,并不限制这些提交的差异。

请注意,这会影响所有基于差异的输出类型,例如:那些由--stat等产生的

代码语言:javascript复制
 --log-size 

在每次提交的输出中包含“日志大小< number>”行,其中< number>是以字节为单位的提交消息的长度。旨在通过允许它们提前分配空间来加速从git log输出读取日志消息的工具。

代码语言:javascript复制
 -L <start>,<end>:<file> 
代码语言:javascript复制
 -L :<funcname>:<file> 

跟踪“< start>,< end>”给出的行范围的演变(或< file>)中的(或函数名称 regex< funcname>)。你可能不会给任何 pathpec 限制器。目前这仅限于从单个修订开始的步行,即,您可能只提供零个或一个正修订参数。您可以多次指定此选项。

<开始>和< end>可以采取以下形式之一:

  • 数 如果< start>或者< end>是一个数字,它指定一个绝对行号(行数从 1 开始)。
  • /正则表达式/ 此表单将使用与给定 POSIX 正则表达式匹配的第一行。如果< start>是一个正则表达式,它将从前一个-L范围的末尾搜索,如果有的话,否则从文件的开头搜索。如果< start>是“^ / regex /”,它将从文件的开头搜索。如果< end>是一个正则表达式,它将从< start>给出的行开始搜索。
    • offset 或-offset

    这仅适用于< end>并将在< start>给出的行之前或之后指定行数。

如果给出“:< funcname>”代替< start>和< end>,它是一个正则表达式,表示从匹配< funcname>的第一个 funcname 行到下一个 funcname 行的范围。 “:< funcname>”从上一个-L范围的末尾搜索(如果有的话),否则从文件的开头搜索。 “^:< funcname>”从文件的开头搜索。

代码语言:javascript复制
 <revision range> 

仅显示指定修订范围内的提交。当没有<修订范围>如果指定,则默认为HEAD(即导致当前提交的整个历史记录)。 origin..HEAD指定从当前提交可以访问的所有提交(即HEAD),但不是origin。有关拼写< revision range>的完整列表,请参阅 gitrevisions [7] 的 _ 指定范围 _ 部分。

代码语言:javascript复制
 [--] <path>…​ 

仅显示足以解释与指定路径匹配的文件的提交。有关详细信息和其他简化模式,请参见下面的 _ 历史简化 _。

当出现混淆时,路径可能需要以--作为前缀,以将它们与选项或修订范围分开。

提交限制

除了使用说明书中解释的特殊符号指定应列出的提交范围之外,还可以应用其他提交限制。

除非另有说明,否则使用更多选项通常会进一步限制输出(例如,--since=&lt;date1&gt;限制提交比&lt;date1&gt;更新,并将其与--grep=&lt;pattern&gt;一起使用进一步限制其日志消息具有与&lt;pattern&gt;匹配的行的提交)。

请注意,这些是在提交排序和格式化选项之前应用的,例如--reverse

代码语言:javascript复制
 -<number> 
代码语言:javascript复制
 -n <number> 
代码语言:javascript复制
 --max-count=<number> 

限制要输出的提交数量。

代码语言:javascript复制
 --skip=<number> 

在开始显示提交输出之前,跳过 _ 编号 _ 提交。

代码语言:javascript复制
 --since=<date> 
代码语言:javascript复制
 --after=<date> 

显示比特定日期更新的提交。

代码语言:javascript复制
 --until=<date> 
代码语言:javascript复制
 --before=<date> 

显示超过特定日期的提交。

代码语言:javascript复制
 --author=<pattern> 
代码语言:javascript复制
 --committer=<pattern> 

将提交输出限制为具有与指定模式(正则表达式)匹配的作者/提交者标题行的输出。对于多个--author=&lt;pattern&gt;,选择作者与任何给定模式匹配的提交(类似于多个--committer=&lt;pattern&gt;)。

代码语言:javascript复制
 --grep-reflog=<pattern> 

将提交输出限制为具有与指定模式(正则表达式)匹配的 reflog 条目的输出。如果有多个--grep-reflog,则选择其 reflog 消息与任何给定模式匹配的提交。除非正在使用--walk-reflogs,否则使用此选项是错误的。

代码语言:javascript复制
 --grep=<pattern> 

将提交输出限制为具有与指定模式(正则表达式)匹配的日志消息的输出。如果有多个--grep=&lt;pattern&gt;,则会选择其消息与任何给定模式匹配的提交(但请参见--all-match)。

--show-notes生效时,来自注释的消息将被匹配,就像它是日志消息的一部分一样。

代码语言:javascript复制
 --all-match 

将提交输出限制为匹配所有给定--grep的输出,而不是匹配至少一个的输出。

代码语言:javascript复制
 --invert-grep 

将提交输出限制为具有与--grep=&lt;pattern&gt;指定的模式不匹配的日志消息的输出。

代码语言:javascript复制
 -i 
代码语言:javascript复制
 --regexp-ignore-case 

匹配正则表达式限制模式而不考虑字母大小写。

代码语言:javascript复制
 --basic-regexp 

将限制模式视为基本正则表达式;这是默认值。

代码语言:javascript复制
 -E 
代码语言:javascript复制
 --extended-regexp 

考虑限制模式是扩展正则表达式而不是默认的基本正则表达式。

代码语言:javascript复制
 -F 
代码语言:javascript复制
 --fixed-strings 

将限制模式视为固定字符串(不要将模式解释为正则表达式)。

代码语言:javascript复制
 -P 
代码语言:javascript复制
 --perl-regexp 

将限制模式视为与 Perl 兼容的正则表达式。

对这些类型的正则表达式的支持是可选的编译时依赖性。如果 Git 没有编译并支持它们,那么提供此选项将导致它死亡。

代码语言:javascript复制
 --remove-empty 

当给定路径从树中消失时停止。

代码语言:javascript复制
 --merges 

仅打印合并提交。这与--min-parents=2完全相同。

代码语言:javascript复制
 --no-merges 

不要打印具有多个父级的提交。这与--max-parents=1完全相同。

代码语言:javascript复制
 --min-parents=<number> 
代码语言:javascript复制
 --max-parents=<number> 
代码语言:javascript复制
 --no-min-parents 
代码语言:javascript复制
 --no-max-parents 

仅显示至少(或最多)许多父提交的提交。特别是,--max-parents=1--no-merges相同,--min-parents=2--merges相同。 --max-parents=0给出所有 root 提交和--min-parents=3所有章鱼合并。

--no-min-parents--no-max-parents再次重置这些限制(无限制)。等效形式是--min-parents=0(任何提交具有 0 或更多父母)和--max-parents=-1(负数表示无上限)。

代码语言:javascript复制
 --first-parent 

在看到合并提交时,仅遵循第一个父提交。在查看特定主题分支的演变时,此选项可以提供更好的概述,因为合并到主题分支往往只是关于不时调整到更新的上游,并且此选项允许您忽略引入的单个提交通过这样的合并你的历史。不能与–bisect 结合使用。

代码语言:javascript复制
 --not 

反转所有后续修订说明符的 ^ 前缀(或缺少)的含义,直到下一个--not

代码语言:javascript复制
 --all 

假设refs/中的所有引用与HEAD一起在命令行中列为 < commit>

代码语言:javascript复制
 --branches[=<pattern>] 

假设refs/heads中的所有引用都在命令行中列为 < commit> 。如果 < pattern> 给出,将分支限制为匹配给定 shell glob 的分支。如果模式缺乏 _?最后暗示 _, *[/ *

代码语言:javascript复制
 --tags[=<pattern>] 

假设refs/tags中的所有引用都在命令行中列为 < commit> 。如果 _< pattern>给出了 _,将标签限制为与给定 shell glob 匹配的标签。如果模式缺乏 _?最后暗示 _, *[/ *

代码语言:javascript复制
 --remotes[=<pattern>] 

假设refs/remotes中的所有引用都在命令行中列为 < commit> 。如果 _< pattern>给出了 _,将远程跟踪分支限制为与给定 shell glob 匹配的分支。如果模式缺乏 _?最后暗示 _, *[/ *

代码语言:javascript复制
 --glob=<glob-pattern> 

假设所有的 refs 匹配 shell glob < glob-pattern> 在命令行中列为 < commit> 。领先的 refs / 会在缺失时自动添加。如果模式缺乏 _?最后暗示 _, *[/ *

代码语言:javascript复制
 --exclude=<glob-pattern> 

不包括引用匹配 < glob-pattern> 否则会考虑下一个--all--branches--tags--remotes--glob。重复此选项会累积排除模式,直至下一个--all--branches--tags--remotes--glob选项(其他选项或参数不会清除累积模式)。

当应用于--branches--tags--remotes时,给出的模式不应以refs/headsrefs/tagsrefs/remotes开始,并且当应用于--glob时,它们必须以refs/开头]或--all。如果打算使用尾随 / * ,则必须明确给出。

代码语言:javascript复制
 --reflog 

假设 reflog 所提到的所有对象都在命令行中列为&lt;commit&gt;

代码语言:javascript复制
 --single-worktree 

默认情况下,当有多个工作树时,将通过以下选项检查所有工作树(参见 git-worktree [1] ):--all--reflog--indexed-objects。此选项强制它们仅检查当前工作树。

代码语言:javascript复制
 --ignore-missing 

在输入中看到无效的对象名称时,假装没有给出错误的输入。

代码语言:javascript复制
 --bisect 

假设好像已经列出了错误的二分法refs/bisect/bad并且好像它后面跟着--not并且良好的二分法在命令行上引用了refs/bisect/good-*。不能与–first-parent 结合使用。

代码语言:javascript复制
 --stdin 

除了 _< commit>在命令行中列出 _,从标准输入中读取它们。如果看到--分隔符,请停止读取提交并开始读取路径以限制结果。

代码语言:javascript复制
 --cherry-mark 

--cherry-pick(见下文)相同,但标记等效提交与=而不是省略它们,而与 不等价。

代码语言:javascript复制
 --cherry-pick 

当提交集受限于对称差异时,省略任何引用与“另一方”上的另一个提交相同的更改的提交。

例如,如果您有两个分支,AB,通常只在一侧列出所有提交的方法是使用--left-right(请参阅下面--left-right选项说明中的示例) 。但是,它显示了从另一个分支中挑选出来的提交(例如,“b 上的第 3 个”可以从分支 A 中挑选出来)。使用此选项,将从输出中排除此类提交对。

代码语言:javascript复制
 --left-only 
代码语言:javascript复制
 --right-only 

列表仅在对称差异的相应侧提交,即仅在那些将被标记为&lt;的那些。 &gt; --left-right

例如,--cherry-pick --right-only A...B省略了来自B的提交,这些提交位于A中,或者补丁等效于A中的提交。换句话说,这列出了git cherry A B 提交。更确切地说,--cherry-pick --right-only --no-merges给出了确切的列表。

代码语言:javascript复制
 --cherry 

--right-only --cherry-mark --no-merges的同义词;有用的是将输出限制在我们这一侧的提交中,并用git log --cherry upstream...mybranch标记已应用于分叉历史记录另一侧的输出,类似于git cherry upstream mybranch

代码语言:javascript复制
 -g 
代码语言:javascript复制
 --walk-reflogs 

而不是走提交祖先链,将 reflog 条目从最新的条目转到较旧的条目。使用此选项时,您无法指定要排除的提交(即 ^ commitcommit1…commit2commit1 … commit2 表示法不能用过的)。

使用oneline以外的--pretty格式(出于显而易见的原因),这会导致输出从 reflog 中获取两行额外的信息。输出中的 reflog 指示符可能显示为ref@{Nth}(其中Nth是 reflog 中的反向时间顺序索引)或ref@{timestamp}(带有该条目的时间戳),具体取决于以下几条规则:

  1. 如果起始点指定为ref@{Nth},则显示索引格式。
  2. 如果起始点指定为ref@{now},则显示时间戳格式。
  3. 如果两者均未使用,但在命令行中给出了--date,则以--date请求的格式显示时间戳。
  4. 否则,显示索引格式。

--pretty=oneline下,提交消息在同一行上以此信息为前缀。此选项不能与--reverse组合使用。另见 git-reflog [1] 。

代码语言:javascript复制
 --merge 

合并失败后,show refs 触摸有冲突的文件,并且在所有头上都不存在要合并的文件。

代码语言:javascript复制
 --boundary 

输出排除边界提交。边界提交以-为前缀。

历史简化

有时您只对历史记录的某些部分感兴趣,例如修改特定< path>的提交。但 _ 历史简化 _ 有两个部分,一部分是选择提交,另一部分是如何做,因为有各种策略来简化历史。

以下选项选择要显示的提交:

代码语言:javascript复制
 <paths> 

提交修改给定的<路径>被选中。

代码语言:javascript复制
 --simplify-by-decoration 

选择某些分支或标记引用的提交。

请注意,可以显示额外的提交以提供有意义的历史记录。

以下选项会影响简化的执行方式:

代码语言:javascript复制
 Default mode 

将历史简化为最简单的历史,解释树的最终状态。最简单的,因为如果最终结果相同(即合并具有相同内容的分支),它会修剪一些侧分支

代码语言:javascript复制
 --full-history 

与默认模式相同,但不修剪某些历史记录。

代码语言:javascript复制
 --dense 

仅显示选定的提交,并显示一些具有有意义的历史记录。

代码语言:javascript复制
 --sparse 

显示简化历史记录中的所有提交。

代码语言:javascript复制
 --simplify-merges 

--full-history的附加选项,用于从生成的历史记录中删除一些不必要的合并,因为没有选定的提交有助于此合并。

代码语言:javascript复制
 --ancestry-path 

当给出一系列要显示的提交时(例如 commit1…commit2commit2 ^ commit1 ),只显示直接存在于 commit1 之间的祖先链上的提交]和 commit2 ,即提交既是 commit1 的后代,又是 commit2 的祖先。

下面是更详细的解释。

假设您将foo指定为< paths>。我们将调用修改foo!TREESAME 的提交,以及其余的 TREESAME。 (在foo的差异滤波中,它们分别看起来不同且相等。)

在下文中,我们将始终参考相同的示例历史记录来说明简化设置之间的差异。我们假设您正在过滤此提交图中的文件foo

代码语言:javascript复制
	  .-A---M---N---O---P---Q
	 /     /   /   /   /   /
	I     B   C   D   E   Y
	    /   /   /   /   /
	  `-------------'   X

历史 A — Q 的水平线被视为每次合并的第一个父级。提交是:

  • I是初始提交,其中foo存在内容“asdf”,文件quux存在,内容为“quux”。初始提交与空树进行比较,因此I是!TREESAME。
  • A中,foo仅包含“foo”。
  • B包含与A相同的更改。它的合并M是微不足道的,因此对所有父母都是 TREESAME。
  • C不会更改foo,但是它的合并N会将其更改为“foobar”,因此它不是任何父级的 TREESAME。
  • Dfoo设置为“baz”。它的合并OND的字符串组合成“foobarbaz”;即,它不是任何父母的 TREESAME。
  • Equux更改为“xyzzy”,其合并P将字符串组合为“quux xyzzy”。 P是 TREESAME 到O,但不是E
  • X是一个独立的根提交,它添加了一个新文件sideY修改了它。 Y是 TREESAME 到X。它的合并Qside添加到PQ将 TREESAME 添加到P,但不添加到Y

rev-list根据是否使用--full-history和/或父改写(通过--parents--children)来回溯历史记录,包括或排除提交。可以使用以下设置。

代码语言:javascript复制
 Default mode 

如果对任何父母不是 TREESAME,则包含提交(尽管可以更改,请参阅下面的--sparse)。如果提交是合并,并且它是一个父级的 TREESAME,则只关注该父级。 (即使有几个 TREESAME 父母,也只能跟随他们中的一个。)否则,请跟随所有父母。

这导致:

代码语言:javascript复制
	  .-A---N---O
	 /     /   /
	I---------D

请注意,仅遵循 TREESAME 父级的规则(如果有的话)将完全从考虑中删除BC被认为是通过N,但是是 TREESAME。 Root 提交与空树进行比较,因此I是!TREESAME。

父/子关系仅在--parents中可见,但这不会影响在默认模式下选择的提交,因此我们显示了父行。

代码语言:javascript复制
 --full-history without parent rewriting 

此模式与默认值在一点上不同:始终跟随合并的所有父项,即使它是其中一个的 TREESAME。即使合并的多个方面包含了包含的提交,这并不意味着合并本身就是!在这个例子中,我们得到了

代码语言:javascript复制
	I  A  B  N  D  O  P  Q

M被排除在外,因为对父母双方都是 TREESAME。 ECB都走了,但只有B是!TREESAME,所以没有出现。

请注意,如果没有父改写,就不可能谈论提交之间的父/子关系,因此我们将它们显示为断开连接。

代码语言:javascript复制
 --full-history with parent rewriting 

只有普通提交才包括在内!TREESAME(虽然可以更改,但请参见下面的--sparse)。

合并始终包括在内。但是,它们的父列表会被重写:沿着每个父项删除不包含在其中的提交。这导致了

代码语言:javascript复制
	  .-A---M---N---O---P---Q
	 /     /   /   /   /
	I     B   /   D   /
	    /   /   /   /
	  `-------------'

--full-history比较而不重写上述内容。请注意,E被删除,因为它是 TREESAME,但是 P 的父列表被重写为包含E的父ICNXYQ也发生了同样的情况。

除上述设置外,您还可以更改 TREESAME 是否影响包含:

代码语言:javascript复制
 --dense 

如果他们不是任何父母的 TREESAME,则包括走路的提交。

代码语言:javascript复制
 --sparse 

包括所有步行的提交。

请注意,如果没有--full-history,这仍然可以简化合并:如果其中一个父项是 TREESAME,我们只遵循那个,所以合并的其他方面永远不会走。

代码语言:javascript复制
 --simplify-merges 

首先,以与父改写的--full-history相同的方式构建历史图(参见上文)。

然后根据以下规则将每个提交C简化为最终历史记录中的替换C'

  • C'设置为C
  • C'的每个父P替换为其简化P'。在这个过程中,删除作为其他父母或祖先的祖先的父母将 TREESAME 提交到空树,并删除重复项,但要注意永远不要删除我们所有父母的 TREESAME。
  • 如果在此父级重写之后,C'是根或合并提交(具有零或> 1 父级),边界提交或!TREESAME,它仍然存在。否则,它将替换为其唯一的父级。

通过与--full-history与父重写进行比较,可以最好地显示出这种效果。这个例子变成了:

代码语言:javascript复制
	  .-A---M---N---O
	 /     /       /
	I     B       D
	    /       /
	  `---------'

注意NPQ--full-history的主要差异:

  • N的父列表删除了I,因为它是另一个父M的祖先。仍然,N仍然是因为它是!TREESAME。
  • P的父列表同样删除了IP然后被完全删除,因为它有一个父母并且是 TREESAME。
  • Q的父列表将Y简化为X。然后删除X,因为它是 TREESAME 根。 Q然后被完全删除,因为它有一个父母并且是 TREESAME。

最后,还有第五种简化模式:

代码语言:javascript复制
 --ancestry-path 

将显示的提交限制为直接在给定提交范围中的“from”和“to”提交之间的祖先链上的提交。即只显示“to”提交的祖先和“from”提交的后代的提交。

作为示例用例,请考虑以下提交历史记录:

代码语言:javascript复制
	    D---E-------F
	   /            
	  B---C---G---H---I---J
	 /                     
	A-------K---------------L--M

常规 D…M 计算作为M的祖先的提交集,但不包括作为D的祖先的提交。这对于从D以来导致M的历史发生了什么是有用的,因为“D中没有M具有什么M”。这个例子中的结果将是所有提交,除了AB(当然还有D本身)。

当我们想知道M中的提交被D引入的 bug 污染并需要修复时,我们可能只想查看实际上 D…M 的子集D的后代,即排除CK。这正是--ancestry-path选项的作用。应用于 D…M 范围,它会导致:

代码语言:javascript复制
		E-------F
		        
		  G---H---I---J
			       
				L--M

--simplify-by-decoration选项允许您通过省略未由标记引用的提交来仅查看历史拓扑的大图。如果(1)它们被标记引用,或(2)它们改变命令行上给出的路径的内容,则提交被标记为!TREESAME(换句话说,保持在上述历史简化规则之后)。所有其他提交都标记为 TREESAME(可以简化)。

提交订购

默认情况下,提交以反向时间顺序显示。

代码语言:javascript复制
 --date-order 

在显示所有子项之前不显示父项,但在提交时间戳顺序中显示提交。

代码语言:javascript复制
 --author-date-order 

在显示所有子项之前不显示父项,但在作者时间戳顺序中显示提交。

代码语言:javascript复制
 --topo-order 

在显示所有子项之前不显示父项,并避免在多行历史记录中显示混合的提交。

例如,在这样的提交历史中:

代码语言:javascript复制
    ---1----2----4----7
		       
	 3----5----6----8---

其中数字表示提交时间戳的顺序,git rev-list--date-order的朋友按时间戳顺序显示提交:8 7 6 5 4 3 2 1。

使用--topo-order,他们将显示 8 6 5 3 7 4 2 1(或 8 7 4 2 6 5 3 1);为了避免将两个并行开发轨道的提交混合在一起,显示一些较旧的提交在较新的提交之前。

代码语言:javascript复制
 --reverse 

输出要以相反顺序显示的提交(请参阅上面的“提交限制”部分)。不能与--walk-reflogs结合使用。

对象遍历

这些选项主要用于打包 Git 存储库。

代码语言:javascript复制
 --no-walk[=(sorted|unsorted)] 

只显示给定的提交,但不要遍历他们的祖先。如果指定了范围,则无效。如果给出了参数unsorted,则提交将按命令行中给出的顺序显示。否则(如果sorted或没有给出参数),提交按提交时间以反向时间顺序显示。不能与--graph结合使用。

代码语言:javascript复制
 --do-walk 

覆盖之前的--no-walk

提交格式
代码语言:javascript复制
 --pretty[=<format>] 
代码语言:javascript复制
 --format=<format> 

以给定格式打印提交日志的内容,其中 < format> 可以是 oneline ,_ 短 培养基 更丰富 之一电子邮件 原始 格式:< string>_ 和 tformat:< string> 。当 < format> 不属于上述情况,并且其中包含 _%占位符 _,其行为就像 –pretty = tformat:< format> 给出了。

有关每种格式的一些其他详细信息,请参阅“PRETTY FORMATS”部分。当 =< format> 部分省略,默认为 medium

注意:您可以在存储库配置中指定默认的漂亮格式(请参阅 git-config [1] )。

代码语言:javascript复制
 --abbrev-commit 

而不是显示完整的 40 字节十六进制提交对象名称,而只显示部分前缀。可以使用“–abbrev =< n>”指定非默认位数(如果显示,也会修改 diff 输出)。

对于使用 80 列终端的人来说,这应该使“–pretty = oneline”更具可读性。

代码语言:javascript复制
 --no-abbrev-commit 

显示完整的 40 字节十六进制提交对象名称。这否定了--abbrev-commit以及暗示它的选项,例如“–oneline”。它还会覆盖log.abbrevCommit变量。

代码语言:javascript复制
 --oneline 

这是一起使用的“–pretty = oneline --abbrev-commit”的简写。

代码语言:javascript复制
 --encoding=<encoding> 

提交对象在其编码头中记录用于日志消息的编码;此选项可用于告诉命令以用户首选的编码重新编码提交日志消息。对于非管道命令,默认为 UTF-8。请注意,如果一个对象声称在X中编码并且我们在X中输出,我们将逐字输出该对象;这意味着原始提交中的无效序列可能会复制到输出中。

代码语言:javascript复制
 --expand-tabs=<n> 
代码语言:javascript复制
 --expand-tabs 
代码语言:javascript复制
 --no-expand-tabs 

执行选项卡扩展(将每个选项卡替换为足够的空格以填充到日志消息中的 < n> 的倍数的下一个显示列),然后在输出中显示它。 --expand-tabs--expand-tabs=8的简写,--no-expand-tabs--expand-tabs=0的简写,它会禁用制表符扩展。

默认情况下,选项卡以相当格式展开,将日志消息缩进 4 个空格(即 medium ,默认情况下, fullfulller )。

代码语言:javascript复制
 --notes[=<treeish>] 

在显示提交日志消息时,显示注释提交的注释(请参阅 git-notes [1] )。当命令行中没有给出--pretty--format--oneline选项时,这是git loggit showgit whatchanged命令的默认值。

默认情况下,显示的注释来自core.notesRefnotes.displayRef变量(或相应的环境覆盖)中列出的注释 refs。有关详细信息,请参阅 git-config [1] 。

使用可选的 < treeish> 参数,使用树形查找要显示的注释。树形可以在以refs/notes/开头时指定完整的引用名称;当它以notes/开始时,refs/和其他refs/notes/作为前缀以形成 ref 的全名。

可以组合多个–notes 选项来控制显示哪些音符。示例:“ - notes = foo”将仅显示“refs / notes / foo”中的注释; “–notes = foo --notes”将显示“refs / notes / foo”和默认音符 ref(s)中的两个音符。

代码语言:javascript复制
 --no-notes 

不要显示笔记。这取消了上面的--notes选项,通过重置显示注释的注释列表。选项按命令行中给出的顺序进行解析,例如, “–notes --notes = foo --no-notes --notes = bar”只会显示“refs / notes / bar”中的注释。

代码语言:javascript复制
 --show-notes[=<treeish>] 
代码语言:javascript复制
 --[no-]standard-notes 

不推荐使用这些选项。请使用上面的–notes / - no-notes 选项。

代码语言:javascript复制
 --show-signature 

通过将签名传递给gpg --verify并显示输出来检查已签名的提交对象的有效性。

代码语言:javascript复制
 --relative-date 

--date=relative的同义词。

代码语言:javascript复制
 --date=<format> 

仅对以人类可读格式显示的日期生效,例如使用--pretty时。 log.date config 变量为日志命令的--date选项设置默认值。默认情况下,日期显示在原始时区(提交者或作者)中。如果-local附加到格式(例如,iso-local),则使用用户的本地时区。

--date=relative显示相对于当前时间的日期,例如“2 小时前”。 -local选项对--date=relative无效。

--date=local--date=default-local的别名。

--date=iso(或--date=iso8601)以类似 ISO 8601 的格式显示时间戳。与严格的 ISO 8601 格式的区别在于:

  • 空格而不是T日期/时间分隔符
  • 时区和时区之间的空间
  • 时区的小时和分钟之间没有冒号

--date=iso-strict(或--date=iso8601-strict)以严格的 ISO 8601 格式显示时间戳。

  • --date=rfc(或--date=rfc2822)以 RFC 2822 格式显示时间戳,通常在电子邮件中找到。
  • --date=short仅以YYYY-MM-DD格式显示日期,但不显示时间。
  • --date=raw显示自纪元以来的秒数(1970-01-01 00:00:00 UTC),后跟一个空格,然后将时区显示为与 UTC 的偏移量( -与四位数;前两位是小时,后两位是分钟)。即,好像时间戳是用strftime("%s %z")格式化的。请注意,-local选项不会影响秒 - 自 - 纪元值(始终以 UTC 为单位),但会切换附带的时区值。
  • --date=human如果时区与当前时区不匹配则显示时区,如果匹配则不显示整个日期(即跳过“今年”日期的打印年份,但也跳过整个日期如果它是在过去几天,我们可以说它是什么工作日)。对于较旧的日期,小时和分钟也被省略。
  • --date=unix将日期显示为 Unix 纪元时间戳(自 1970 年以来的秒数)。与--raw一样,它始终为 UTC,因此-local无效。
  • --date=format:...将格式...输入系统strftime,%z 和%Z 除外,它们在内部处理。使用--date=format:%c以系统区域设置的首选格式显示日期。有关格式占位符的完整列表,请参阅strftime手册。使用-local时,正确的语法是--date=format-local:...
  • --date=default是默认格式,类似于--date=rfc2822,但有一些例外:
  • 星期几之后没有逗号
  • 使用本地时区时,省略时区
代码语言:javascript复制
 --parents 

同时打印提交的父级(以“提交父级”的形式)。也可以启用父重写,请参阅上面的 _ 历史简化 _。

代码语言:javascript复制
 --children 

同时打印提交的子项(以“提交子项…”的形式)。也可以启用父重写,请参阅上面的 _ 历史简化 _。

代码语言:javascript复制
 --left-right 

标记可以从中获取提交的对称差异的哪一侧。左侧的提示以&lt;为前缀,右侧的提示以&gt;为前缀。如果与--boundary结合使用,则这些提交以-为前缀。

例如,如果您有此拓扑:

代码语言:javascript复制
	     y---b---b  branch B
	    /  /
	   /   .
	  /   / 
	 o---x---a---a  branch A

你会得到这样的输出:

代码语言:javascript复制
	$ git rev-list --left-right --boundary --pretty=oneline A...B

	>bbbbbbb... 3rd on b
	>bbbbbbb... 2nd on b
	<aaaaaaa... 3rd on a
	<aaaaaaa... 2nd on a
	-yyyyyyy... 1st on b
	-xxxxxxx... 1st on a
代码语言:javascript复制
 --graph 

在输出的左侧绘制提交历史的基于文本的图形表示。这可能会导致在提交之间打印额外的行,以便正确绘制图形历史记录。不能与--no-walk结合使用。

这使父进行重写,参见上面的 _ 历史简化 _。

默认情况下,这意味着--topo-order选项,但也可以指定--date-order选项。

代码语言:javascript复制
 --show-linear-break[=<barrier>] 

当不使用–graph 时,所有历史分支都被展平,这使得很难看出两个连续的提交不属于线性分支。在这种情况下,此选项会在它们之间设置障碍。如果指定了&lt;barrier&gt;,则显示的是字符串而不是默认字符串。

差异格式化

下面列出了控制 diff 输出格式的选项。其中一些特定于 git-rev-list [1] ,但是可以给出其他差异选项。有关更多选项,请参阅 git-diff-files [1] 。

代码语言:javascript复制
 -c 

使用此选项,合并提交的 diff 输出同时显示每个父项与合并结果的差异,而不是一次显示父项和结果之间的成对差异。此外,它仅列出从所有父母修改的文件。

代码语言:javascript复制
 --cc 

这个标志意味着-c选项并通过省略不感兴趣的帅哥进一步压缩补丁输出,其中父母的内容只有两个变体,合并结果选择其中一个而不做修改。

代码语言:javascript复制
 -m 

此标志使合并提交像常规提交一样显示完整差异;对于每个合并父项,将生成单独的日志条目和差异。一个例外是,当给出--first-parent选项时,只显示对第一个父项的差异;在这种情况下,输出表示合并带来的变化 _ 进入当前分支的 _。

代码语言:javascript复制
 -r 

显示递归差异。

代码语言:javascript复制
 -t 

在 diff 输出中显示树对象。这意味着-r

漂亮的格式

如果提交是合并,并且如果漂亮格式不是 oneline ,_ 电子邮件 _ 或 raw ,则在 _ 作者之前插入另一行:_ 行。该行以“Merge:”开头,并且打印祖先提交的 sha1,用空格分隔。请注意,如果您限制了对历史记录的查看,则列出的提交可能不一定是直接父提交的列表:例如,如果您只对与某个目录或文件相关的更改感兴趣。

有几种内置格式,您可以通过设置漂亮的格式来定义其他格式。< name>将选项配置为另一种格式名称或 _ 格式:_ 字符串,如下所述(参见 git-config [1] )。以下是内置格式的详细信息:

oneline

代码语言:javascript复制
&lt;sha1&gt; &lt;title line&gt;

这是为了尽可能紧凑。

_ 短 _

代码语言:javascript复制
commit &lt;sha1&gt;
Author: &lt;author&gt;
代码语言:javascript复制
&lt;title line&gt;

_ 中 _

代码语言:javascript复制
commit &lt;sha1&gt;
Author: &lt;author&gt;
Date:   &lt;author date&gt;
代码语言:javascript复制
&lt;title line&gt;
代码语言:javascript复制
&lt;full commit message&gt;

_ 全 _

代码语言:javascript复制
commit &lt;sha1&gt;
Author: &lt;author&gt;
Commit: &lt;committer&gt;
代码语言:javascript复制
&lt;title line&gt;
代码语言:javascript复制
&lt;full commit message&gt;

_ 更丰富 _

代码语言:javascript复制
commit &lt;sha1&gt;
Author:     &lt;author&gt;
AuthorDate: &lt;author date&gt;
Commit:     &lt;committer&gt;
CommitDate: &lt;committer date&gt;
代码语言:javascript复制
&lt;title line&gt;
代码语言:javascript复制
&lt;full commit message&gt;

_ 电子邮件 _

代码语言:javascript复制
From &lt;sha1&gt; &lt;date&gt;
From: &lt;author&gt;
Date: &lt;author date&gt;
Subject: [PATCH] &lt;title line&gt;
代码语言:javascript复制
&lt;full commit message&gt;

_ 原始 _

raw 格式显示完整提交,与存储在提交对象中完全相同。值得注意的是,无论是否使用–abbrev 或–no-abbrev,SHA-1 都会完整显示,并且 _ 父 _ 信息显示真正的父提交,而不考虑移植或历史简化。请注意,此格式会影响提交的显示方式,但不会影响显示差异的方式,例如用git log --raw。要以原始 diff 格式获取完整对象名称,请使用--no-abbrev

_ 格式:< string>_

_ 格式:< string>_ 格式允许您指定要显示的信息。它的工作方式有点像 printf 格式,但有一个值得注意的例外,即你用 %n 而不是 n 获得换行符。

例如,_ 格式:“%h 的作者是%an,%ar%n 标题是>>%s<<%n”_ 将显示如下内容:

代码语言:javascript复制
The author of fe6e0ee was Junio C Hamano, 23 hours ago
The title was &gt;&gt;t4119: test autocomputing -p&lt;n&gt; for traditional diff input.&lt;&lt;

占位符是:

  • %H :提交哈希
  • %h :缩写提交哈希
  • %T :树形哈希
  • %t :缩写树哈希
  • %P :父哈希
  • %p :缩写为父哈希值
  • _%和 _:作者姓名
  • %aN :作者姓名(尊重.mailmap,见 git-shortlog [1] 或 git-blame [1] )
  • %ae :作者电邮
  • %aE :作者电子邮件(尊重.mailmap,见 git-shortlog [1] 或 git-blame [1] )
  • %ad :作者日期(格式尊重 - 日期=选项)
  • %aD :作者日期,RFC2822 风格
  • %ar :作者日期,相对
  • 的 _%:作者日期,UNIX 时间戳 _
  • %ai :作者日期,ISO 8601 样格式
  • %aI :作者日期,严格的 ISO 8601 格式
  • %cn :提交者名称
  • %cN :提交者名称(尊重.mailmap,见 git-shortlog [1] 或 git-blame [1] )
  • %ce :提交者电子邮件
  • %cE :提交者电子邮件(尊重.mailmap,参见 git-shortlog [1] 或 git-blame [1] )
  • %cd :提交者日期(格式尊重 - 日期=选项)
  • %cD :提交者日期,RFC2822 样式
  • %cr :提交者日期,相对
  • %ct :提交者日期,UNIX 时间戳
  • %ci :提交者日期,类似 ISO 8601 的格式
  • %cI :提交者日期,严格的 ISO 8601 格式
  • %d :引用名称,如 git-log [1] 的–decorate 选项
  • %D :没有“(”,“)”包装的引用名称。
  • %S :在达到提交的命令行上给出的引用名称(如git log --source),仅适用于git log
  • %e :编码
  • %s :受试者
  • %f :已清理的主题行,适用于文件名
  • %b :身体
  • %B :生体(未包裹的主体和身体)
  • %N :提交备注
  • %GG :来自 GPG 的签名提交的原始验证消息
  • %G? :显示好的(有效)签名“G”,坏签名显示“B”,有效期未知的好签名显示“U”,已过期的好签名显示“X”,“Y”代表由过期密钥签名的好签名,“R”表示由撤销密钥签名的好签名,“E”表示签名无法检查(例如缺少密钥),“N”表示没有签名
  • %GS :显示签名提交的签名者姓名
  • %GK :显示用于签署签名提交的密钥
  • %GF ​​:显示用于签署签名提交的密钥的指纹
  • %GP :显示主键的指纹,其子键用于签名提交的签名
  • %gD :reflog 选择器,例如refs/stash@{1}refs/stash@{2 minutes ago};格式遵循-g选项描述的规则。 @之前的部分是命令行中给出的 refname(因此git log -g refs/heads/master将产生refs/heads/master@{0})。
  • %gd :缩短了 reflog 选择器;与%gD相同,但 refname 部分缩短了人类的可读性(因此refs/heads/master变为master)。
  • %gn :reflog 身份名称
  • %gN :reflog 身份名称(尊重.mailmap,见 git-shortlog [1] 或 git-blame [1] )
  • %ge :reflog 身份电子邮件
  • %gE :reflog 身份邮件(尊重.mailmap,见 git-shortlog [1] 或 git-blame [1] )
  • %gs :reflog 主题
  • %Cred :将颜色切换为红色
  • %Cgreen :将颜色切换为绿色
  • %Cblue :将颜色切换为蓝色
  • %Creset :重置颜色
  • %C(…):颜色规格,如 git-config [1] 的“CONFIGURATION FILE”部分中的值所述。默认情况下,仅在启用日志输出时显示颜色(通过color.diffcolor.ui--color,并且如果我们要去终端,则尊重前者的auto设置)。 %C(auto,...)被接受为默认的历史同义词(例如,%C(auto,red))。即使没有启用颜色,指定%C(always,...)也会显示颜色(尽管只考虑使用--color=always为整个输出启用颜色,包括这种格式和其他任何 git 可能颜色的颜色)。单独auto(即%C(auto))将打开下一个占位符的自动着色,直到再次切换颜色。
  • %m :左(&lt;),右(&gt;)或边界(-)标记
  • %n :换行符
  • %% :原始
  • %x00 :从十六进制代码打印一个字节
  • %w([< w> [,< i1> [,< i2>]]]):切换行换行,类似 git-shortlog [1]的-w 选项。
  • %<(< N> [,trunc | ltrunc | mtrunc]):使下一个占位符至少取 N 列,如果需要,在右边填充空格。如果输出长于 N 列,则可以选择在开头(ltrunc),中间(mtrunc)或结尾(trunc)截断。请注意,截断仅适用于 N> = 2。
  • %< |(< N>):使下一个占位符至少占用第 N 列,如果需要,在右边填充空格
  • %>(< N>)%> |(< N>):与 %相似,%< |(< N>)_,但左边的填充空格 _
  • %>(< N>)%> |(< N>):类似于 %>(< N>分别是 ,%> |(< N>),除非下一个占位符占用的空间多于给定的空间并且左侧有空格,请使用这些空格
  • %><(< N>)%>< |(< N>):类似于 %<(< N> )%< |(< N>),但填充两侧(即文本居中)
  • %(预告片[:options]):显示 git-interpret-trailers [1] 解释的正文预告片。 trailers字符串后面可以跟冒号和零个或多个逗号分隔选项。如果给出了only选项,则省略拖车块中的非拖车线。如果给出unfold选项,则表现得就像给出了 interpre-trailer 的--unfold选项一样。例如,%(trailers:only,unfold)两者都做。

| 注意 | 一些占位符可能依赖于修订遍历引擎的其他选项。例如,%g* reflog 选项将插入一个空字符串,除非我们遍历 reflog 条目(例如,通过git log -g)。如果命令行中尚未提供--decorate%d%D占位符将使用“短”装饰格式。 |

如果在占位符的 之后添加 (加号),则在扩展之前插入换行符当且仅当占位符扩展为非空字符串时。

如果在占位符的 之后添加-(减号),则当且仅当占位符扩展为空字符串时,才会删除紧接在扩展之前的所有连续换行符。

如果在占位符的 之后添加一个“空格”,则在扩展之前插入一个空格,当且仅当占位符扩展为非空字符串时。

tformat:

_ 格式:_ 格式与 _ 格式完全相同:_,除了它提供“终结符”语义而不是“分隔符”语义。换句话说,每个提交都附加了消息终止符(通常是换行符),而不是在条目之间放置的分隔符。这意味着单行格式的最终​​输入将使用新行正确终止,就像“oneline”格式一样。例如:

代码语言:javascript复制
$ git log -2 --pretty=format:%h 4da45bef 
  | perl -pe '$_ .= " -- NO NEWLINEn" unless /n/'
4da45be
7134973 -- NO NEWLINE

$ git log -2 --pretty=tformat:%h 4da45bef 
  | perl -pe '$_ .= " -- NO NEWLINEn" unless /n/'
4da45be
7134973

此外,其中包含%的任何无法识别的字符串都被解释为它前面有tformat:。例如,这两个是等价的:

代码语言:javascript复制
$ git log -2 --pretty=tformat:%h 4da45bef
$ git log -2 --pretty=%h 4da45bef

常见的 DIFF 选项

代码语言:javascript复制
 -p 
代码语言:javascript复制
 -u 
代码语言:javascript复制
 --patch 

生成补丁(请参阅生成补丁的部分)。

代码语言:javascript复制
 -s 
代码语言:javascript复制
 --no-patch 

抑制差异输出。对于git show等默认显示补丁的命令,或取消--patch的效果很有用。

代码语言:javascript复制
 -U<n> 
代码语言:javascript复制
 --unified=<n> 

用< n>生成差异。上下文而不是通常的三行。意味着-p

代码语言:javascript复制
 --raw 

对于每个提交,使用原始 diff 格式显示更改摘要。请参阅 git-diff [1] 的“RAW OUTPUT FORMAT”部分。这与以原始格式显示日志本身不同,您可以使用--format=raw来实现。

代码语言:javascript复制
 --patch-with-raw 

-p --raw的同义词。

代码语言:javascript复制
 --indent-heuristic 

启用改变差异块边界的启发式以使补丁更易于阅读。这是默认值。

代码语言:javascript复制
 --no-indent-heuristic 

禁用缩进启发式。

代码语言:javascript复制
 --minimal 

花些额外的时间来确保产生尽可能小的差异。

代码语言:javascript复制
 --patience 

使用“耐心差异”算法生成差异。

代码语言:javascript复制
 --histogram 

使用“histogram diff”算法生成 diff。

代码语言:javascript复制
 --anchored=<text> 

使用“锚定差异”算法生成差异。

可以多次指定此选项。

如果源和目标中都存在一行,只存在一次,并以此文本开头,则此算法会尝试阻止它在输出中显示为删除或添加。它在内部使用“耐心差异”算法。

代码语言:javascript复制
 --diff-algorithm={patience|minimal|histogram|myers} 

选择差异算法。变体如下:

代码语言:javascript复制
 default, myers 

基本的贪心差异算法。目前,这是默认值。

代码语言:javascript复制
 minimal 

花些额外的时间来确保产生尽可能小的差异。

代码语言:javascript复制
 patience 

生成补丁时使用“耐心差异”算法。

代码语言:javascript复制
 histogram 

该算法将耐心算法扩展为“支持低发生的共同元素”。

例如,如果将diff.algorithm变量配置为非默认值并想要使用默认值,则必须使用--diff-algorithm=default选项。

代码语言:javascript复制
 --stat[=<width>[,<name-width>[,<count>]]] 

生成 diffstat。默认情况下,文件名部分将使用必要的空间,图形部分的其余部分将使用。最大宽度默认为终端宽度,如果未连接到终端,则为 80 列,并且可以被&lt;width&gt;覆盖。可以通过在逗号后面给出另一个宽度&lt;name-width&gt;来限制文件名部分的宽度。可以使用--stat-graph-width=&lt;width&gt;(影响生成统计图的所有命令)或设置diff.statGraphWidth=&lt;width&gt;(不影响git format-patch)来限制图形部分的宽度。通过给出第三个参数&lt;count&gt;,可以将输出限制为第一个&lt;count&gt;行,如果有更多,则可以将...限制为...

也可以使用--stat-width=&lt;width&gt;--stat-name-width=&lt;name-width&gt;--stat-count=&lt;count&gt;单独设置这些参数。

代码语言:javascript复制
 --compact-summary 

输出扩展标题信息的精简摘要,例如文件创建或删除(“新”或“消失”,如果是符号链接,则可选“ l”)和模式更改(“ x”或“-x”用于添加或删除 diffstat 中的可执行位)。信息放在文件名部分和图形部分之间。意味着--stat

代码语言:javascript复制
 --numstat 

--stat类似,但显示十进制表示法中添加和删除的行数以及没有缩写的路径名,以使其更加机器友好。对于二进制文件,输出两个-而不是0 0

代码语言:javascript复制
 --shortstat 

仅输出--stat格式的最后一行,其中包含已修改文件的总数,以及已添加和已删除行的数量。

代码语言:javascript复制
 --dirstat[=<param1,param2,…​>] 

输出每个子目录的相对更改量的分布。 --dirstat的行为可以通过以逗号分隔的参数列表传递来定制。默认值由diff.dirstat配置变量控制(参见 git-config [1] )。可以使用以下参数:

代码语言:javascript复制
 changes 

通过计算已从源中删除或添加到目标的行来计算 dirstat 数。这忽略了文件中纯代码移动的数量。换句话说,重新排列文件中的行不会像其他更改那样计算。这是没有给出参数时的默认行为。

代码语言:javascript复制
 lines 

通过执行常规的基于行的差异分析来计算 dirstat 数字,并对移除/添加的行数进行求和。 (对于二进制文件,计算 64 字节块,因为二进制文件没有自然的线条概念)。这是比changes行为更昂贵的--dirstat行为,但它确实计算文件中重新排列的行与其他更改一样多。结果输出与您从其他--*stat选项获得的输出一致。

代码语言:javascript复制
 files 

通过计算更改的文件数来计算 dirstat 数。在 dirstat 分析中,每个更改的文件都相同。这是计算上最便宜的--dirstat行为,因为它根本不需要查看文件内容。

代码语言:javascript复制
 cumulative 

计算父目录的子目录中的更改。请注意,使用cumulative时,报告的百分比总和可能超过 100%。可以使用noncumulative参数指定默认(非累积)行为。

代码语言:javascript复制
 <limit> 

整数参数指定截止百分比(默认为 3%)。贡献低于此百分比变化的目录不会显示在输出中。

示例:以下将计算已更改的文件,同时忽略少于已更改文件总量的 10%的目录,并在父目录中累计子目录计数:--dirstat=files,10,cumulative

代码语言:javascript复制
 --summary 

输出扩展标题信息的精简摘要,例如创建,重命名和模式更改。

代码语言:javascript复制
 --patch-with-stat 

-p --stat的同义词。

代码语言:javascript复制
 -z 

将提交与 NUL 分开,而不是使用新换行符。

此外,当给出--raw--numstat时,不要使用路径名并使用 NUL 作为输出字段终止符。

如果没有此选项,则会引用具有“异常”字符的路径名,如配置变量core.quotePath所述(参见 git-config [1] )。

代码语言:javascript复制
 --name-only 

仅显示已更改文件的名称。

代码语言:javascript复制
 --name-status 

仅显示已更改文件的名称和状态。有关状态字母的含义,请参阅--diff-filter选项的说明。

代码语言:javascript复制
 --submodule[=<format>] 

指定子模块的差异如何显示。指定--submodule=short时,使用 _ 短 _ 格式。此格式仅显示范围开头和结尾的提交名称。指定--submodule--submodule=log时,使用 log 格式。此格式列出 git-submodule [1] summary等范围内的提交。指定--submodule=diff时,使用 diff 格式。此格式显示提交范围之间子模块内容更改的内联差异。如果未设置配置选项,则默认为diff.submodule或 _ 短 _ 格式。

代码语言:javascript复制
 --color[=<when>] 

显示彩色差异。 --color(即没有 =<当> )与--color=always相同时。 < when> 可以是alwaysneverauto之一。

代码语言:javascript复制
 --no-color 

关掉彩色差异。它与--color=never相同。

代码语言:javascript复制
 --color-moved[=<mode>] 

移动的代码行的颜色不同。 <模式>如果没有给出选项,默认为 no ,如果给出没有模式的选项,则默认为 zebra 。模式必须是以下之一:

代码语言:javascript复制
 no 

移动的线条不会突出显示。

代码语言:javascript复制
 default 

zebra的同义词。这可能会在未来转变为更明智的模式。

代码语言:javascript复制
 plain 

在一个位置添加并在另一个位置删除的任何行都将使用 color.diff.newMoved 进行着色。类似地, color.diff.oldMoved 将用于在 diff 中的其他位置添加的已删除行。此模式选择任何已移动的行,但在检查中确定是否在没有置换的情况下移动了代码块时,它不是很有用。

代码语言:javascript复制
 blocks 

贪婪地检测至少 20 个字母数字字符的移动文本块。使用 color.diff。{old,new} Moved 颜色绘制检测到的块。相邻的街区不能分开。

代码语言:javascript复制
 zebra 

在 _ 块 _ 模式中检测移动文本块。使用 color.diff。{old,new} Moved 颜色或 color.diff。{old,new} MovedAlternative 绘制块。两种颜色之间的变化表示检测到新的块。

代码语言:javascript复制
 dimmed-zebra 

zebra 类似,但执行了移动代码的无趣部分的额外调暗。两个相邻街区的边界线被认为是有趣的,其余的是无趣的。 dimmed_zebra是不推荐使用的同义词。

代码语言:javascript复制
 --no-color-moved 

关闭移动检测。这可用于覆盖配置设置。它与--color-moved=no相同。

代码语言:javascript复制
 --color-moved-ws=<modes> 

这将配置在执行--color-moved的移动检测时如何忽略空白。这些模式可以以逗号分隔的列表给出:

代码语言:javascript复制
 no 

执行移动检测时不要忽略空格。

代码语言:javascript复制
 ignore-space-at-eol 

忽略 EOL 中的空白更改。

代码语言:javascript复制
 ignore-space-change 

忽略空格量的变化。这会忽略行尾的空格,并将一个或多个空白字符的所有其他序列视为等效。

代码语言:javascript复制
 ignore-all-space 

比较线条时忽略空格。即使一行有空格而另一行没有空格,这也会忽略差异。

代码语言:javascript复制
 allow-indentation-change 

最初忽略移动检测中的任何空格,然后如果每行的空白变化相同,则仅将移动的代码块分组到块中。这与其他模式不兼容。

代码语言:javascript复制
 --no-color-moved-ws 

执行移动检测时不要忽略空格。这可用于覆盖配置设置。它与--color-moved-ws=no相同。

代码语言:javascript复制
 --word-diff[=<mode>] 

使用< mode>显示单词 diff。划定改变的单词。默认情况下,单词由空格分隔;见下面的--word-diff-regex。 <模式>默认为 plain ,必须是以下之一:

代码语言:javascript复制
 color 

仅使用颜色突出显示更改的单词。意味着--color

代码语言:javascript复制
 plain 

将单词显示为[-removed-]{ added }。如果它们出现在输入中,则不会尝试转义分隔符,因此输出可能不明确。

代码语言:javascript复制
 porcelain 

使用特殊的基于行的格式用于脚本使用。添加/删除/未更改的运行以通常的统一 diff 格式打印,从行开头的 / - /``字符开始并延伸到行尾。输入中的换行符由其自身行上的波浪号~表示。

代码语言:javascript复制
 none 

再次禁用字差异。

请注意,尽管第一个模式的名称,但如果启用了颜色,则使用颜色突出显示所有模式中已更改的部分。

代码语言:javascript复制
 --word-diff-regex=<regex> 

使用< regex>决定一个单词是什么,而不是将非空格的运行视为一个单词。除非已经启用,否则还暗示--word-diff

< regex>的每个非重叠匹配被认为是一个词。这些匹配之间的任何内容都被视为空格并被忽略(!)以查找差异。您可能希望将|[^[:space:]]附加到正则表达式,以确保它匹配所有非空白字符。包含换行符的匹配项会在换行符处以静默方式截断(!)。

例如,--word-diff-regex=.会将每个字符视为一个单词,并相应地逐个字符地显示差异。

正则表达式也可以通过 diff 驱动程序或配置选项设置,参见 gitattributes [5] 或 git-config [1] 。明确地覆盖任何差异驱动程序或配置设置。 Diff 驱动程序覆盖配置设置。

代码语言:javascript复制
 --color-words[=<regex>] 

相当于--word-diff=color加(如果指定了正则表达式)--word-diff-regex=&lt;regex&gt;

代码语言:javascript复制
 --no-renames 

关闭重命名检测,即使配置文件提供默认值也是如此。

代码语言:javascript复制
 --check 

如果更改引入冲突标记或空白错误,则发出警告。什么被认为是空白错误由core.whitespace配置控制。默认情况下,尾随空格(包括仅由空格组成的行)和在行的初始缩进内紧跟着制表符的空格字符被视为空格错误。如果发现问题,则退出非零状态。与–exit-code 不兼容。

代码语言:javascript复制
 --ws-error-highlight=<kind> 

突出显示差异的contextoldnew行中的空白错误。多个值用逗号分隔,none重置先前的值,default将列表重置为newallold,new,context的简写。如果未指定此选项,并且未设置配置变量diff.wsErrorHighlight,则仅突出显示new行中的空白错误。空白错误用color.diff.whitespace着色。

代码语言:javascript复制
 --full-index 

在生成补丁格式输出时,在“索引”行上显示完整的前映像和后映像 blob 对象名称,而不是第一个字符。

代码语言:javascript复制
 --binary 

--full-index外,还可输出可用git-apply应用的二进制差异。

代码语言:javascript复制
 --abbrev[=<n>] 

而不是在 diff-raw 格式输出和 diff-tree 标题行中显示完整的 40 字节十六进制对象名称,而是仅显示部分前缀。这与上面的--full-index选项无关,后者控制 diff-patch 输出格式。可以使用--abbrev=&lt;n&gt;指定非默认位数。

代码语言:javascript复制
 -B[<n>][/<m>] 
代码语言:javascript复制
 --break-rewrites[=[<n>][/<m>]] 

将完整的重写更改分为删除和创建对。这有两个目的:

它影响了一个更改的方式,相当于一个文件的完全重写,而不是一系列的删除和插入混合在一起,只有几行恰好与文本作为上下文匹配,而是作为单个删除所有旧的后跟一个单个插入所有新内容,数字m控制-B 选项的这一方面(默认为 60%)。 -B/70%指定少于 30%的原始文本应保留在结果中,以便 Git 将其视为完全重写(即,否则生成的修补程序将是一系列删除和插入与上下文行混合在一起)。

当与-M 一起使用时,完全重写的文件也被视为重命名的源(通常-M 只考虑作为重命名源消失的文件),并且数字n控制 - 的这方面 - B 选项(默认为 50%)。 -B20%指定添加和删除的更改与文件大小的 20%或更多相比,有资格被选为可能的重命名源到另一个文件。

代码语言:javascript复制
 -M[<n>] 
代码语言:javascript复制
 --find-renames[=<n>] 

如果生成差异,则检测并报告每次提交的重命名。对于遍历历史记录时重命名后续文件,请参阅--follow。如果指定了n,则它是相似性指数的阈值(即与文件大小相比的添加/删除量)。例如,-M90%表示如果超过 90%的文件未更改,Git 应将删除/添加对视为重命名。如果没有%符号,则该数字将作为分数读取,并在其前面加上小数点。即,-M5变为 0.5,因此与-M50%相同。同样,-M05-M5%相同。要将检测限制为精确重命名,请使用-M100%。默认相似性指数为 50%。

代码语言:javascript复制
 -C[<n>] 
代码语言:javascript复制
 --find-copies[=<n>] 

检测副本以及重命名。另见--find-copies-harder。如果指定了n,则其含义与-M&lt;n&gt;的含义相同。

代码语言:javascript复制
 --find-copies-harder 

出于性能原因,默认情况下,仅当在同一变更集中修改了副本的原始文件时,-C选项才会查找副本。此标志使命令检查未修改的文件作为副本源的候选者。对于大型项目来说,这是一项非常昂贵的操作,因此请谨慎使用。提供多个-C选项具有相同的效果。

代码语言:javascript复制
 -D 
代码语言:javascript复制
 --irreversible-delete 

省略删除的原像,即只打印标题而不打印原像和/dev/null之间的差异。得到的贴片不适用于patchgit apply;这仅适用于那些希望在更改后专注于审阅文本的人。此外,输出显然缺乏足够的信息来反向应用这样的补丁,甚至手动,因此选项的名称。

-B一起使用时,也省略删除/创建对的删除部分中的原像。

代码语言:javascript复制
 -l<num> 

-M-C选项需要 O(n ^ 2)处理时间,其中 n 是潜在的重命名/复制目标的数量。如果重命名/复制目标的数量超过指定的数量,此选项可防止重命名/复制检测运行。

代码语言:javascript复制
 --diff-filter=[(A|C|D|M|R|T|U|X|B)…​[*]] 

仅选择已添加(A),复制(C),已删除(D),已修改(M),已重命名(R)的文件,其类型(即常规文件,符号链接,子模块,…)更改(T),未合并(U),未知(X),或已配对破碎(B)。可以使用过滤器字符的任何组合(包括无)。当*(全部或全部)添加到组合中时,如果有任何文件与比较中的其他条件匹配,则选择所有路径;如果没有与其他条件匹配的文件,则不会选择任何内容。

此外,这些大写字母可以降级为排除。例如。 --diff-filter=ad排除添加和删除的路径。

请注意,并非所有差异都可以包含所有类型。例如,从索引到工作树的差异永远不会有添加条目(因为差异中包含的路径集受限于索引中的内容)。同样,如果禁用了对这些类型的检测,则无法显示复制和重命名的条目。

代码语言:javascript复制
 -S<string> 

查找改变文件中指定字符串出现次数(即添加/删除)的差异。用于脚本编写者的使用。

当你正在寻找一个确切的代码块(比如一个结构体)时,它很有用,并且想要知道该块首次出现以来的历史:迭代地使用该特征将原始图像中的有趣块反馈回-S,继续前进,直到你获得该块的第一个版本。

也搜索二进制文件。

代码语言:javascript复制
 -G<regex> 

查找补丁文本包含与< regex>匹配的添加/删除行的差异。

为了说明-S&lt;regex&gt; --pickaxe-regex-G&lt;regex&gt;之间的区别,请考虑在同一文件中使用以下 diff 进行提交:

代码语言:javascript复制
     return !regexec(regexp, two->ptr, 1, &regmatch, 0);
...
-    hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);

虽然git log -G"regexec(regexp"将显示此提交,但git log -S"regexec(regexp" --pickaxe-regex不会(因为该字符串的出现次数没有改变)。

除非提供--text,否则将忽略没有 textconv 过滤器的二进制文件的补丁。

有关详细信息,请参阅 gitdiffcore [7] 中的 pickaxe 条目。

代码语言:javascript复制
 --find-object=<object-id> 

查找更改指定对象出现次数的差异。与-S类似,只是参数的不同之处在于它不搜索特定的字符串,而是搜索特定的对象 id。

该对象可以是 blob 或子模块提交。它意味着git-log中的-t选项也可以找到树。

代码语言:javascript复制
 --pickaxe-all 

-S-G找到更改时,显示该更改集中的所有更改,而不仅仅是包含< string>中更改的文件。

代码语言:javascript复制
 --pickaxe-regex 

对待< string>赋予-S作为扩展的 POSIX 正则表达式以匹配。

代码语言:javascript复制
 -O<orderfile> 

控制文件在输出中的显示顺序。这会覆盖diff.orderFile配置变量(参见 git-config [1] )。要取消diff.orderFile,请使用-O/dev/null

输出顺序由< orderfile>中的 glob 模式的顺序决定。首先输出所有与第一个模式匹配的路径名的文件,然后输出所有与第二个模式(但不是第一个模式)匹配的路径名的文件,依此类推。路径名与任何模式都不匹配的所有文件都是最后输出的,就好像文件末尾有一个隐式匹配所有模式一样。如果多个路径名具有相同的等级(它们匹配相同的模式但没有早期模式),则它们相对于彼此的输出顺序是正常顺序。

< orderfile>解析如下:

  • 空行被忽略,因此可以将它们用作分隔符以提高可读性。
  • 以哈希(“#”)开头的行将被忽略,因此它们可用于注释。如果以散列开头,则将反斜杠(“”)添加到模式的开头。
  • 每个其他行包含一个模式。

模式与没有 FNM_PATHNAME 标志的 fnmatch(3)使用的模式具有相同的语法和语义,但如果删除任意数量的最终路径名组件与模式匹配,则路径名也匹配模式。例如,模式“foo*bar”匹配“fooasdfbar”和“foo/bar/baz/asdf”而不匹配“foobarx”。

代码语言:javascript复制
 -R 

交换两个输入;也就是说,显示从索引或磁盘文件到树内容的差异。

代码语言:javascript复制
 --relative[=<path>] 

从项目的子目录运行时,可以告诉它排除目录外的更改并使用此选项显示相对于它的路径名。当您不在子目录中时(例如,在裸存储库中),您可以通过给出< path>来命名哪个子目录以使输出相对。作为一个论点。

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --text 

将所有文件视为文本。

代码语言:javascript复制
 --ignore-cr-at-eol 

进行比较时,忽略行尾的回车。

代码语言:javascript复制
 --ignore-space-at-eol 

忽略 EOL 中的空白更改。

代码语言:javascript复制
 -b 
代码语言:javascript复制
 --ignore-space-change 

忽略空格量的变化。这会忽略行尾的空格,并将一个或多个空白字符的所有其他序列视为等效。

代码语言:javascript复制
 -w 
代码语言:javascript复制
 --ignore-all-space 

比较线条时忽略空格。即使一行有空格而另一行没有空格,这也会忽略差异。

代码语言:javascript复制
 --ignore-blank-lines 

忽略其行全部为空的更改。

代码语言:javascript复制
 --inter-hunk-context=<lines> 

显示差异之间的上下文,直到指定的行数,从而融合彼此接近的帅哥。如果未设置配置选项,则默认为diff.interHunkContext或 0。

代码语言:javascript复制
 -W 
代码语言:javascript复制
 --function-context 

显示整个周围的变化功能。

代码语言:javascript复制
 --ext-diff 

允许执行外部 diff 助手。如果使用 gitattributes [5] 设置外部差异驱动程序,则需要将此选项与 git-log [1] 和朋友一起使用。

代码语言:javascript复制
 --no-ext-diff 

禁止外部差异驱动程序。

代码语言:javascript复制
 --textconv 
代码语言:javascript复制
 --no-textconv 

在比较二进制文件时允许(或禁止)外部文本转换过滤器运行。有关详细信息,请参阅 gitattributes [5] 。由于 textconv 过滤器通常是单向转换,因此生成的差异适合人类使用,但无法应用。因此,默认情况下,textconv 过滤器仅针对 git-diff [1] 和 git-log [1] 启用,但不适用于 git-format-patch [ 1] 或差异管道命令。

代码语言:javascript复制
 --ignore-submodules[=<when>] 

忽略差异生成中子模块的更改。 <当>可以是“none”,“untracked”,“dirty”或“all”,这是默认值。使用“none”时,如果子模块包含未跟踪或修改的文件,或者其 HEAD 与超级项目中记录的提交不同,则可以使用“无”来修改子模块,并可用于覆盖中 ignore 选项的任何设置 git-config [1] 或 gitmodules [5] 。当使用“未跟踪”时,如果子模块仅包含未跟踪的内容(但仍会扫描修改的内容),则子模块不会被视为脏。使用“脏”忽略对子模块工作树的所有更改,仅显示存储在超级项目中的提交的更改(这是 1.7.0 之前的行为)。使用“all”隐藏子模块的所有更改。

代码语言:javascript复制
 --src-prefix=<prefix> 

显示给定的源前缀而不是“a /”。

代码语言:javascript复制
 --dst-prefix=<prefix> 

显示给定的目标前缀而不是“b /”。

代码语言:javascript复制
 --no-prefix 

不显示任何源或目标前缀。

代码语言:javascript复制
 --line-prefix=<prefix> 

为每行输出预先附加前缀。

代码语言:javascript复制
 --ita-invisible-in-index 

默认情况下,“git add -N”添加的条目在“git diff”中显示为现有空文件,在“git diff --cached”中显示为新文件。此选项使条目在“git diff”中显示为新文件,在“git diff --cached”中不存在。可以使用--ita-visible-in-index恢复此选项。这两个选项都是实验性的,将来可以删除。

有关这些常用选项的更详细说明,另请参阅 gitdiffcore [7] 。

使用-p 生成补丁

当“git-diff-index”,“git-diff-tree”或“git-diff-files”使用-p选项运行时,“git diff”不带--raw选项或“git log”使用“-p”选项,它们不会产生上述输出;相反,他们生成一个补丁文件。您可以通过GIT_EXTERNAL_DIFFGIT_DIFF_OPTS环境变量自定义此类修补程序的创建。

-p 选项产生的内容与传统的 diff 格式略有不同:

它前面有一个“git diff”标题,如下所示:

代码语言:javascript复制
diff --git a/file1 b/file2

除非涉及重命名/复制,否则a/b/文件名是相同的。特别是,即使是创建或删除,/dev/null也是 _ 而不是 _ 来代替a/b/文件名。

当涉及重命名/复制时,file1file2分别显示重命名/复制的源文件的名称和重命名/复制的文件的名称。

它后跟一个或多个扩展标题行:

代码语言:javascript复制
old mode &lt;mode&gt;
new mode &lt;mode&gt;
deleted file mode &lt;mode&gt;
new file mode &lt;mode&gt;
copy from &lt;path&gt;
copy to &lt;path&gt;
rename from &lt;path&gt;
rename to &lt;path&gt;
similarity index &lt;number&gt;
dissimilarity index &lt;number&gt;
index &lt;hash&gt;..&lt;hash&gt; &lt;mode&gt;

文件模式打印为 6 位八进制数,包括文件类型和文件权限位。

扩展标头中的路径名不包括a/b/前缀。

相似性指数是未更改行的百分比,相异性指数是更改行的百分比。它是一个向下舍入的整数,后跟一个百分号。因此,100%的相似性索引值保留用于两个相等的文件,而 100%的相异性意味着旧文件中的任何行都不会成为新文件。

索引行包括更改前后的 SHA-1 校验和。 <模式>如果文件模式没有改变,则包括在内;否则,单独的行表示旧模式和新模式。

具有“异常”字符的路径名被引用,如配置变量core.quotePath所述(参见 git-config [1] )。

输出中的所有file1文件在提交之前引用文件,并且所有file2文件在提交之后引用文件。将每个更改顺序应用于每个文件是不正确的。例如,此补丁将交换 a 和 b:

代码语言:javascript复制
diff --git a/a b/b
rename from a
rename to b
diff --git a/b b/a
rename from b
rename to a

组合差异格式

在显示合并时,任何差异生成命令都可以使用-c--cc选项生成 _ 组合差异 _。当显示与 git-diff [1] 或 git-show [1] 的合并时,这是默认格式。另请注意,您可以为这些命令中的任何一个提供-m选项,以强制使用合并的各个父项生成差异。

_ 组合 diff_ 格式如下所示:

代码语言:javascript复制
diff --combined describe.c
index fabadb8,cc95eb0..4866510
--- a/describe.c
    b/describe.c
@@@ -98,20 -98,12  98,20 @@@
	return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
  }

- static void describe(char *arg)
 -static void describe(struct commit *cmit, int last_one)
  static void describe(char *arg, int last_one)
  {
  	unsigned char sha1[20];
  	struct commit *cmit;
	struct commit_list *list;
	static int initialized = 0;
	struct commit_name *n;

  	if (get_sha1(arg, sha1) < 0)
  		usage(describe_usage);
  	cmit = lookup_commit_reference(sha1);
  	if (!cmit)
  		usage(describe_usage);
  
	if (!initialized) {
		initialized = 1;
		for_each_ref(get_name);

它前面有一个“git diff”标题,看起来像这样(当使用-c选项时):

代码语言:javascript复制
diff --combined file

或者像这样(当使用--cc选项时):

代码语言:javascript复制
diff --cc file

它后跟一个或多个扩展标题行(此示例显示了与两个父项的合并):

代码语言:javascript复制
index &lt;hash&gt;,&lt;hash&gt;..&lt;hash&gt;
mode &lt;mode&gt;,&lt;mode&gt;..&lt;mode&gt;
new file mode &lt;mode&gt;
deleted file mode &lt;mode&gt;,&lt;mode&gt;

只有当< mode>中的至少一个出现时,mode &lt;mode&gt;,&lt;mode&gt;..&lt;mode&gt;行才会出现。与其他人不同。具有关于检测到的内容移动(重命名和复制检测)的信息的扩展标题被设计为与两个< tree-ish>的差异一起工作。并且不会被组合 diff 格式使用。

接下来是两行的文件/文件头

代码语言:javascript复制
--- a/file
    b/file

与传统 _ 统一 _ diff 格式的双行标题类似,/dev/null用于表示创建或删除的文件。

修改了块头格式以防止人们意外地将其馈送到patch -p1。创建组合差异格式用于审查合并提交更改,并不适用于应用。此更改类似于扩展 _ 索引 _ 标头中的更改:

代码语言:javascript复制
@@@ &lt;from-file-range&gt; &lt;from-file-range&gt; &lt;to-file-range&gt; @@@

组合 diff 格式的块头中有(父项数 1)@个字符。

与传统的 _ 统一 _ 差异格式不同,后者显示两个文件 A 和 B,其中一列具有-(减去 - 出现在 A 中但在 B 中删除), (加 - 缺少 A 但是添加到 B)或" "(空格 - 未更改)前缀,此格式将两个或多个文件 file1,file2,…与一个文件 X 进行比较,并显示 X 与每个文件 N 的不同之处。每个 fileN 的一列被添加到输出行之前,以指示 X 的行与它的不同之处。

N 列中的-字符表示该行出现在 fileN 中,但它不会出现在结果中。列 N 中的 字符表示该行出现在结果中,而 fileN 没有该行(换句话说,从该父项的角度添加了该行)。

在上面的示例输出中,函数签名已从两个文件中更改(因此,file1 和 file2 中的两个-删除加上 表示添加的一行未出现在 file1 或 file2 中)。另外八行与 file1 相同,但不出现在 file2 中(因此以 为前缀)。

当由git diff-tree -c显示时,它将合并提交的父项与合并结果进行比较(即 file1…fileN 是父项)。当由git diff-files -c显示时,它将两个未解析的合并父项与工作树文件进行比较(即 file1 是阶段 2 又名“我们的版本”,file2 是阶段 3 又名“他们的版本”)。

例子

代码语言:javascript复制
 git log --no-merges 

显示整个提交历史记录,但跳过任何合并

代码语言:javascript复制
 git log v2.6.12.. include/scsi drivers/scsi 

显示自版本 v2.6.12 以来更改include/scsidrivers/scsi子目录中的任何文件的所有提交

代码语言:javascript复制
 git log --since="2 weeks ago" -- gitk 

在过去两周内将更改显示到文件 gitk--是必要的,以避免与名为 gitk分支混淆

代码语言:javascript复制
 git log --name-status release..test 

显示“test”分支中但尚未在“release”分支中的提交,以及每个提交修改的路径列表。

代码语言:javascript复制
 git log --follow builtin/rev-list.c 

显示更改builtin/rev-list.c的提交,包括在文件被赋予其当前名称之前发生的提交。

代码语言:javascript复制
 git log --branches --not --remotes=origin 

显示任何本地分支中的所有提交,但不显示 _ 原点 _ 的任何远程跟踪分支中的所有提交(您的原点没有)。

代码语言:javascript复制
 git log master --not --remotes=*/master 

显示本地主服务器中但不在任何远程存储库主分支中的所有提交。

代码语言:javascript复制
 git log -p -m --first-parent 

显示包含更改差异的历史记录,但仅显示“主分支”透视图,跳过来自合并分支的提交,并显示合并引入的完整更改差异。只有遵循严格的策略,在停留在单个集成分支上时合并所有主题分支才有意义。

代码语言:javascript复制
 git log -L '/int main/',/^}/:main.c 

显示文件main.c中的函数main()如何随时间演变。

代码语言:javascript复制
 git log -3 

将要显示的提交数限制为 3。

讨论

Git 在某种程度上是字符编码不可知的。

  • blob 对象的内容是未解释的字节序列。核心级别没有编码转换。
  • 路径名以 UTF-8 规范化形式 C 编码。这适用于树对象,索引文件,ref 名称,以及命令行参数,环境变量和配置文件中的路径名(.git/config(参见 git) -config [1] ), gitignore [5] , gitattributes [5] 和 gitmodules [5] )。 请注意,核心级别的 Git 仅将路径名称视为非 NUL 字节序列,没有路径名称编码转换(Mac 和 Windows 除外)。因此,即使在使用传统扩展 ASCII 编码的平台和文件系统上,使用非 ASCII 路径名也会起作用。但是,在此类系统上创建的存储库将无法在基于 UTF-8 的系统(例如 Linux,Mac,Windows)上正常工作,反之亦然。此外,许多基于 Git 的工具只是假设路径名为 UTF-8,并且无法正确显示其他编码。
  • 提交日志消息通常以 UTF-8 编码,但也支持其他扩展 ASCII 编码。这包括 ISO-8859-x,CP125x 和许多其他,但 _ 不是 _ UTF-16/32,EBCDIC 和 CJK 多字节编码(GBK,Shift-JIS,Big5,EUC-x,CP9xx 等。 )。

虽然我们鼓励提交日志消息以 UTF-8 编码,但核心和 Git 瓷器都不是为了强制项目使用 UTF-8。如果特定项目的所有参与者发现使用遗留编码更方便,Git 不会禁止它。但是,有一些事情需要牢记。

git commitgit commit-tree 发出警告,如果提供给它的提交日志消息看起来不像有效的 UTF-8 字符串,除非你明确说你的项目使用了遗产编码。说这个的方法是在.git/config文件中使用 i18n.commitencoding,如下所示:

代码语言:javascript复制
[i18n]
	commitEncoding = ISO-8859-1

使用上述设置创建的提交对象在其encoding标题中记录i18n.commitEncoding的值。这是为了帮助其他人以后再看。缺少此标头意味着提交日志消息以 UTF-8 编码。

git loggit showgit blame 和朋友们查看提交对象的encoding头,并尝试将日志消息重新编码为除非另有说明,否则为 UTF-8。您可以使用.git/config文件中的i18n.logOutputEncoding指定所需的输出编码,如下所示:

代码语言:javascript复制
[i18n]
	logOutputEncoding = ISO-8859-1

如果您没有此配置变量,则使用i18n.commitEncoding的值。

请注意,我们故意选择在提交以在提交对象级别强制使用 UTF-8 时不重新编写提交日志消息,因为重新编码为 UTF-8 不一定是可逆操作。

组态

对于核心变量,请参见 git-config [1] ,对于差异生成,请参见 git-diff [1] 。

代码语言:javascript复制
 format.pretty 

--format选项的默认值。 (参见上面的 _ 漂亮格式 _。)默认为medium

代码语言:javascript复制
 i18n.logOutputEncoding 

显示日志时使用的编码。 (参见上面的 _ 讨论 _。)如果设置,则默认为i18n.commitEncoding的值,否则为 UTF-8。

代码语言:javascript复制
 log.date 

人类可读日期的默认格式。 (比较--date选项。)默认为“默认”,表示写入Sat May 8 19:35:34 2010 -0500等日期。

如果格式设置为“auto:foo”并且正在使用寻呼机,则格式“foo”将用于日期格式。否则将使用“默认”。

代码语言:javascript复制
 log.follow 

如果truegit log将像单个<路径>一样使用--follow选项。给出。这与--follow具有相同的限制,即它不能用于跟踪多个文件,并且在非线性历史记录上不能很好地工作。

代码语言:javascript复制
 log.showRoot 

如果falsegit log和相关命令不会将初始提交视为大创建事件。 git log -p输出中的任何根提交都将显示没有附加差异。默认值为true

代码语言:javascript复制
 log.showSignature 

如果truegit log和相关命令的作用就像传递了--show-signature选项一样。

代码语言:javascript复制
 mailmap.* 

见 git-shortlog [1] 。

代码语言:javascript复制
 notes.displayRef 

除了core.notesRefGIT_NOTES_REF设置的默认值之外,还使用log系列命令显示提交消息时的注释。见 git-notes [1] 。

可以是未缩写的引用名称或 glob,可以多次指定。将为不存在的引用发出警告,但是会自动忽略与任何引用不匹配的 glob。

可以通过--no-notes选项禁用此设置,由GIT_NOTES_DISPLAY_REF环境变量覆盖,并由--notes=&lt;ref&gt;选项覆盖。

GIT

部分 git [1] 套件

git-stash

原文: git-scm.com/docs/git-stash

名称

git-stash - 将更改存储在脏工作目录中

概要

代码语言:javascript复制
git stash list [<options>]
git stash show [<stash>]
git stash drop [-q|--quiet] [<stash>]
git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
	     [-u|--include-untracked] [-a|--all] [-m|--message <message>]
	     [--] [<pathspec>…​]]
git stash clear
git stash create [<message>]
git stash store [-m|--message <message>] [-q|--quiet] <commit>

描述

如果要记录工作目录和索引的当前状态,但想要返回到干净的工作目录,请使用git stash。该命令将保存您的本地修改并恢复工作目录以匹配HEAD提交。

此命令隐藏的修改可以使用git stash list列出,使用git stash show进行检查,并使用git stash apply恢复(可能在不同的提交之上)。不带任何参数调用git stash等同于git stash push。默认情况下,存储被列为“ branchname 上的 WIP …”,但您可以在创建存储时在命令行上提供更具描述性的消息。

您创建的最新存储存储在refs/stash中;在此引用的 reflog 中可以找到较旧的 stashes,并且可以使用通常的 reflog 语法命名(例如stash@{0}是最近创建的 stash,stash@{1}是之前的那个,stash@{2.hours.ago}也是可能的)。也可以通过仅指定存储索引来引用状态(例如,整数n等同于stash@{n})。

OPTIONS

代码语言:javascript复制
 push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--] [<pathspec>…​] 

将本地修改保存到新的 _ 存储条目 _ 并将它们回滚到 HEAD(在工作树和索引中)。 < message> part 是可选的,并提供描述以及 stashed 状态。

要快速创建快照,可以省略“推送”。在此模式下,不允许使用非选项参数来防止拼写错误的子命令生成不需要的存储条目。对此的两个例外是stash -p,它作为stash push -p和 pathspecs 的别名,在双连字符--之后允许消除歧义。

当 pathspec 被赋予 git stash push 时,新的存储条目仅记录与 pathspec 匹配的文件的修改状态。然后,索引条目和工作树文件也仅针对这些文件回滚到 HEAD 中的状态,从而保留与 pathspec 不匹配的文件。

如果使用--keep-index选项,则已添加到索引的所有更改都将保持不变。

如果使用--include-untracked选项,所有未跟踪的文件也会被隐藏,然后使用git clean清除,使工作目录处于非常干净的状态。如果使用--all选项,则除了未跟踪的文件外,还会隐藏和清除被忽略的文件。

使用--patch,您可以交互式地从 HEAD 和工作树之间的差异中选择要存储的数据。构建存储条目,使其索引状态与存储库的索引状态相同,并且其工作树仅包含您以交互方式选择的更改。然后,从您的工作树中回滚所选更改。请参阅 git-add [1] 的“交互模式”部分,了解如何操作--patch模式。

--patch选项意味着--keep-index。您可以使用--no-keep-index覆盖它。

代码语言:javascript复制
 save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>] 

不推荐使用此选项,而使用 git stash push 。它与“stash push”的不同之处在于它不能采用 pathspecs,并且任何非选项参数都构成了消息。

代码语言:javascript复制
 list [<options>] 

列出您当前拥有的存储条目。列出每个 _ 存储条目 _ 及其名称(例如stash@{0}是最新条目,stash@{1}是之前的条目,等等),条目的当前分支名称,以及条目所基于的提交的简短描述。

代码语言:javascript复制
stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation
stash@{1}: On master: 9cc0589... Add git-stash

该命令采用适用于 git log 命令的选项来控制显示的内容和方式。参见 git-log [1] 。

代码语言:javascript复制
 show [<stash>] 

将存储条目中记录的更改显示为隐藏内容与首次创建存储条目时的提交之间的差异。如果没有给出&lt;stash&gt;,则显示最新的一个。默认情况下,该命令显示 diffstat,但它将接受 git diff 已知的任何格式(例如,git stash show -p stash@{1}以补丁形式查看第二个最新条目)。您可以使用 stash.showStat 和/或 stash.showPatch 配置变量来更改默认行为。

代码语言:javascript复制
 pop [--index] [-q|--quiet] [<stash>] 

从存储列表中删除单个隐藏状态并将其应用于当前工作树状态之上,即执行git stash push的反向操作。工作目录必须与索引匹配。

应用国家可能会因冲突而失败;在这种情况下,它不会从隐藏列表中删除。您需要手动解决冲突并随后手动调用git stash drop

如果使用--index选项,则尝试不仅恢复工作树的更改,还尝试恢复索引的更改。但是,如果存在冲突(存储在索引中,因此您无法再像以前那样应用更改),则可能会失败。

如果没有给出&lt;stash&gt;,则假定为stash@{0},否则&lt;stash&gt;必须是stash@{&lt;revision&gt;}形式的参考。

代码语言:javascript复制
 apply [--index] [-q|--quiet] [<stash>] 

pop类似,但不要从隐藏列表中删除状态。与pop不同,&lt;stash&gt;可能是任何看似由stash pushstash create创建的提交的提交。

代码语言:javascript复制
 branch <branchname> [<stash>] 

创建并检出一个名为&lt;branchname&gt;的新分支,从最初创建&lt;stash&gt;的提交开始,将&lt;stash&gt;中记录的更改应用于新的工作树和索引。如果成功,&lt;stash&gt;stash@{&lt;revision&gt;}形式的参考,则它会丢弃&lt;stash&gt;。如果没有给出&lt;stash&gt;,则应用最新的一个。

如果运行git stash push的分支已经发生了足够的变化,使得git stash apply因冲突而失败,这将非常有用。由于存储条目应用于git stash运行时 HEAD 的提交之上,因此它恢复原始存储状态而没有冲突。

代码语言:javascript复制
 clear 

删除所有存储条目。请注意,这些条目将进行修剪,并且可能无法恢复(请参阅下面的 _ 示例 _ 以获取可能的策略)。

代码语言:javascript复制
 drop [-q|--quiet] [<stash>] 

从存储条目列表中删除单个存储条目。如果没有给出&lt;stash&gt;,它将删除最新的一个。即stash@{0},否则&lt;stash&gt;必须是stash@{&lt;revision&gt;}形式的有效存储日志引用。

代码语言:javascript复制
 create 

创建一个存储条目(这是一个常规提交对象)并返回其对象名称,而不将其存储在 ref 命名空间中的任何位置。这对脚本非常有用。它可能不是你想要使用的命令;看到上面的“推”。

代码语言:javascript复制
 store 

存储通过 _git stash 创建的给定存储创建 _(这是一个悬空的合并提交)在存储引用中,更新存储 reflog。这对脚本非常有用。它可能不是你想要使用的命令;看到上面的“推”。

讨论

存储条目表示为提交,其树记录工作目录的状态,其第一个父项是创建条目时HEAD的提交。第二个父树的树在创建条目时记录索引的状态,并且它成为HEAD提交的子代。祖先图如下所示:

代码语言:javascript复制
       .----W
      /    /
-----H----I

其中HHEAD提交,I是记录索引状态的提交,W是记录工作树状态的提交。

例子

代码语言:javascript复制
 Pulling into a dirty tree 

当您处于某种状态时,您会发现存在可能与您正在进行的操作相关的上游更改。当您的本地更改不与上游的更改冲突时,一个简单的git pull将让您继续前进。

但是,在某些情况下,您的本地更改会与上游更改发生冲突,git pull会拒绝覆盖您的更改。在这种情况下,您可以隐藏您的更改,执行拉动,然后取消暂停,如下所示:

代码语言:javascript复制
$ git pull
 ...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
$ git stash pop
代码语言:javascript复制
 Interrupted workflow 

当你处于中间状态时,你的老板会进来并要求你立即修理。传统上,您将提交临时分支以存储您的更改,并返回到原始分支以进行紧急修复,如下所示:

代码语言:javascript复制
# ... hack hack hack ...
$ git checkout -b my_wip
$ git commit -a -m "WIP"
$ git checkout master
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git checkout my_wip
$ git reset --soft HEAD^
# ... continue hacking ...

您可以使用 git stash 来简化上述操作,如下所示:

代码语言:javascript复制
# ... hack hack hack ...
$ git stash
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git stash pop
# ... continue hacking ...
代码语言:javascript复制
 Testing partial commits 

如果要从工作树中的更改中进行两次或更多次提交,并且希望在提交之前测试每个更改,则可以使用git stash push --keep-index

代码语言:javascript复制
# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash push --keep-index    # save all other changes to the stash
$ edit/build/test first part
$ git commit -m 'First part'     # commit fully tested change
$ git stash pop                  # prepare to work on all other changes
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'
代码语言:javascript复制
 Recovering stash entries that were cleared/dropped erroneously 

如果您错误地删除或清除了存储条目,则无法通过正常的安全机制恢复它们。但是,您可以尝试以下咒语来获取仍在存储库中但不再可访问的存储条目列表:

代码语言:javascript复制
git fsck --unreachable |
grep commit | cut -d  -f3 |
xargs git log --merges --no-walk --grep=WIP

也可以看看

git-checkout [1] , git-commit [1] , git-reflog [1] , git-reset [1]

GIT

部分 git [1] 套件

git-tag

原文: git-scm.com/docs/git-tag

名称

git-tag - 创建,列出,删除或验证使用 GPG 签名的标记对象

概要

代码语言:javascript复制
git tag [-a | -s | -u <keyid>] [-f] [-m <msg> | -F <file>] [-e]
	<tagname> [<commit> | <object>]
git tag -d <tagname>…​
git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]
	[--points-at <object>] [--column[=<options>] | --no-column]
	[--create-reflog] [--sort=<key>] [--format=<format>]
	[--[no-]merged [<commit>]] [<pattern>…​]
git tag -v [--format=<format>] <tagname>…​

描述

refs/tags/中添加标记引用,除非-d/-l/-v用于删除,列出或验证标记。

除非给出-f,否则指定的标记必须不存在。

如果传递-a-s-u &lt;keyid&gt;之一,该命令将创建 _ 标签 _ 对象,并需要标记消息。除非给出-m &lt;msg&gt;-F &lt;file&gt;,否则将启动编辑器以供用户键入标记消息。

如果给出-m &lt;msg&gt;-F &lt;file&gt;并且-a-s-u &lt;keyid&gt;不存在,则暗示-a

否则,创建直接指向给定对象(即,轻量标签)的标签引用。

使用-s-u &lt;keyid&gt;时,将创建 GnuPG 签名标记对象。如果未使用-u &lt;keyid&gt;,则使用当前用户的提交者标识来查找用于签名的 GnuPG 密钥。配置变量gpg.program用于指定自定义 GnuPG 二进制文件。

标记对象(使用-a-s-u创建)称为“带注释”标记;它们包含创建日期,标记器名称和电子邮件,标记消息以及可选的 GnuPG 签名。而“轻量级”标签只是对象的名称(通常是提交对象)。

带注释的标签用于发布,而轻量级标签用于私有或临时对象标签。因此,一些用于命名对象的 git 命令(如git describe)将默认忽略轻量级标记。

OPTIONS

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --annotate 

创建一个未签名的带注释的标记对象

代码语言:javascript复制
 -s 
代码语言:javascript复制
 --sign 

使用默认电子邮件地址密钥创建 GPG 签名标记。

代码语言:javascript复制
 -u <keyid> 
代码语言:javascript复制
 --local-user=<keyid> 

使用给定密钥创建 GPG 签名标记。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

用给定名称替换现有标记(而不是失败)

代码语言:javascript复制
 -d 
代码语言:javascript复制
 --delete 

删除具有给定名称的现有标签。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verify 

验证给定标记名称的 GPG 签名。

代码语言:javascript复制
 -n<num> 

< NUM>指定在使用-l 时打印注释的行数(如果有)。意味着--list

默认情况下不打印任何注释行。如果-n没有给出编号,则只打印第一行。如果标记未注释,则显示提交消息。

代码语言:javascript复制
 -l 
代码语言:javascript复制
 --list 

列出标签。使用可选的&lt;pattern&gt;...,例如git tag --list 'v-*',仅列出与模式匹配的标记。

不带参数运行“git tag”也会列出所有标签。该模式是 shell 通配符(即,使用 fnmatch(3)匹配)。可以给出多种模式;如果它们中的任何一个匹配,则显示标记。

如果提供了任何其他类似列表的选项(如--contains),则会隐式提供此选项。有关详细信息,请参阅每个选项的文档。

代码语言:javascript复制
 --sort=<key> 

根据给定的密钥排序。前缀-按值的降序排序。您可以使用–sort =< key>选项多次,在这种情况下,最后一个键成为主键。还支持“version:refname”或“v:refname”(标记名称被视为版本)。 “version:refname”排序顺序也可能受“versionsort.suffix”配置变量的影响。支持的键与git for-each-ref中的键相同。排序顺序默认为tag.sort变量(如果存在)配置的值,否则为字典顺序。见 git-config [1] 。

代码语言:javascript复制
 --color[=<when>] 

尊重--format选项中指定的任何颜色。 &lt;when&gt;字段必须是alwaysneverauto之一(如果&lt;when&gt;不存在,则表现得好像always一样)。

代码语言:javascript复制
 -i 
代码语言:javascript复制
 --ignore-case 

排序和过滤标签不区分大小写。

代码语言:javascript复制
 --column[=<options>] 
代码语言:javascript复制
 --no-column 

在列中显示标记列表。有关选项语法,请参阅配置变量 column.tag。没有选项的--column--no-column分别相当于和 _ 永远不会 _。

此选项仅在列出没有注释行的标签时适用。

代码语言:javascript复制
 --contains [<commit>] 

仅列出包含指定提交的标记(如果未指定,则为 HEAD)。意味着--list

代码语言:javascript复制
 --no-contains [<commit>] 

仅列出不包含指定提交的标记(如果未指定,则为 HEAD)。意味着--list

代码语言:javascript复制
 --merged [<commit>] 

仅列出其提交可从指定提交到达的标记(如果未指定,则为HEAD),与--no-merged不兼容。

代码语言:javascript复制
 --no-merged [<commit>] 

仅列出其提交无法从指定提交到达的标记(如果未指定,则为HEAD),与--merged不兼容。

代码语言:javascript复制
 --points-at <object> 

仅列出给定对象的标签(如果未指定,则为 HEAD)。意味着--list

代码语言:javascript复制
 -m <msg> 
代码语言:javascript复制
 --message=<msg> 

使用给定的标记消息(而不是提示)。如果给出了多个-m选项,则它们的值将作为单独的段落连接在一起。如果没有给出-a-s-u &lt;keyid&gt;,则表示-a

代码语言:javascript复制
 -F <file> 
代码语言:javascript复制
 --file=<file> 

从给定文件中获取标记消息。使用 - 从标准输入读取信息。如果没有给出-a-s-u &lt;keyid&gt;,则表示-a

代码语言:javascript复制
 -e 
代码语言:javascript复制
 --edit 

从带有-F的文件和带有-m的命令行获取的消息通常用作未修改的标记消息。此选项允许您进一步编辑从这些来源获取的消息。

代码语言:javascript复制
 --cleanup=<mode> 

此选项设置清除标记消息的方式。 < mode> 可以是 _ 逐字 空白 _ 和 _ 条带 _ 之一。 _ 条 _ 模式是默认模式。 _ 逐字 _ 模式根本不改变消息,_ 空格 _ 只删除前导/尾随空白行,_ 条 _ 删除空白和评论。

代码语言:javascript复制
 --create-reflog 

为标记创建 reflog。要全局启用标签的 reflog,请参见 git-config [1] 中的core.logAllRefUpdates。否定形式--no-create-reflog仅覆盖较早的--create-reflog,但目前不会否定core.logAllRefUpdates的设置。

代码语言:javascript复制
 --format=<format> 

一个字符串,用于插入显示的标记 ref 中的%(fieldname)及其指向的对象。格式与 git-for-each-ref [1] 的格式相同。未指定时,默认为%(refname:strip=2)

代码语言:javascript复制
 <tagname> 

要创建,删除或描述的标记的名称。新标签名称必须通过 git-check-ref-format [1] 定义的所有检查。其中一些检查可能会限制标记名称中允许的字符。

代码语言:javascript复制
 <commit> 
代码语言:javascript复制
 <object> 

新标记将引用的对象,通常是提交。默认为 HEAD。

组态

默认情况下, _git 标签 _ 处于默认签名模式(-s)将使用您的提交者标识(Your Name &lt;your@email.address&gt;形式)来查找密钥。如果要使用其他默认密钥,可以在存储库配置中指定它,如下所示:

代码语言:javascript复制
[user]
    signingKey = <gpg-keyid>

仅在列出标签时,即使用或暗示-l时,才会遵守pager.tag。默认是使用寻呼机。见 git-config [1] 。

讨论

关于重新标记

当您标记错误的提交并且您想要重新标记时,您应该怎么做?

如果你从未推过任何东西,只需重新标记即可。使用“-f”替换旧的。而且你已经完成了。

但是如果你把事情搞砸了(或者其他人可以直接读取你的存储库),那么其他人就已经看到了旧的标签了。在这种情况下,您可以执行以下两项操作之一:

  1. 理智的事情。只是承认你搞砸了,并使用不同的名字。其他人已经看过一个标签名称,如果你保持相同的名字,你可能会遇到两个人都有“版本 X”的情况,但他们实际上有 _ 不同的 _“X”。所以只需称它为“X.1”并完成它。
  2. 疯狂的事情。你真的想把新版本称为“X”,_ 即使 _ 其他人已经看过旧版本。所以再次使用 git tag -f ,好像你还没有发布旧版本一样。

但是,Git 确实没有(它不应该)改变用户背后的标签。因此,如果有人已经得到了旧标签,那么在树上执行 git pull 不应该只是让它们覆盖旧标签。

如果有人从你那里得到了一个发布标签,你就不能通过更新自己的标签来改变标签。这是一个很大的安全问题,因为人们必须能够信任他们的标签名称。如果你真的想做疯狂的事情,你需要了解它,告诉别人你搞砸了。你可以通过发布一个非常公开的声明来做到这一点:

代码语言:javascript复制
Ok, I messed up, and I pushed out an earlier version tagged as X. I
then fixed something, and retagged the *fixed* tree as X again.

If you got the wrong tag, and want the new one, please delete
the old one and fetch the new one by doing:

	git tag -d X
	git fetch origin tag X

to get my updated tag.

You can test which tag you have by doing

	git rev-parse X

which should return 0123456789abcdef.. if you have the new version.

Sorry for the inconvenience.

这看起来有点复杂吗?它应该是。没有办法自动“修复”它是正确的。人们需要知道他们的标签可能已被更改。

关于自动跟随

如果您正在关注其他人的树,则您很可能使用远程跟踪分支(例如refs/remotes/origin/master)。您通常需要来自另一端的标签。

另一方面,如果你想要从其他人那里获取一次性合并,那么你通常不希望从那里获得标签。这种情况更常发生在靠近顶层但不限于它们的人身上。当彼此拉扯时,凡人都不一定想要从另一个人那里自动获得私人锚点标签。

通常,邮件列表上的“请拉”消息只提供两条信息:一个 repo URL 和一个分支名称;这是为了在 git fetch 命令行结束时轻松剪切和粘贴:

代码语言:javascript复制
Linus, please pull from

	git://git..../proj.git master

to get the following updates...

变为:

代码语言:javascript复制
$ git pull git://git..../proj.git master

在这种情况下,您不希望自动关注其他人的标签。

Git 的一个重要方面是它的分布式特性,这在很大程度上意味着系统中没有固有的“上游”或“下游”。从表面上看,上面的例子似乎表明标签命名空间由人的上层所有,而且标签只向下流动,但事实并非如此。它仅显示使用模式确定谁对其标签感兴趣。

一次性拉动表示提交历史现在正越过一个人圈之间的边界(例如“主要对内核的网络部分感兴趣的人”),他们可能拥有自己的一组标签(例如“这是来自网络组的第三个候选版本被提议用于 2.6.21 版本的一般消费“)到另一个人群(例如”整合各种子系统改进的人“)。后者通常对前一组内部使用的详细标签不感兴趣(这就是“内部”的含义)。这就是为什么在这种情况下不希望自动跟踪标签的原因。

很可能在网络人员中,他们可能想要在他们的组内部交换标签,但在该工作流程中,他们很可能通过具有远程跟踪分支来跟踪彼此的进度。同样,自动跟随这些标签的启发式是一件好事。

关于回溯标签

如果您从另一个 VCS 导入了一些更改,并且想为工作的主要版本添加标记,那么能够指定嵌入标记对象内部的日期是很有用的。例如,标签对象中的这种数据会影响 gitweb 界面中标签的排序。

要设置将来标记对象中使用的日期,请设置环境变量 GIT_COMMITTER_DATE(请参阅后面对可能值的讨论;最常见的形式是“YYYY-MM-DD HH:MM”)。

例如:

代码语言:javascript复制
$ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1

日期格式

GIT_AUTHOR_DATEGIT_COMMITTER_DATE环境变量支持以下日期格式:

代码语言:javascript复制
 Git internal format 

它是&lt;unix timestamp&gt; &lt;time zone offset&gt;,其中&lt;unix timestamp&gt;是自 UNIX 纪元以来的秒数。 &lt;time zone offset&gt;是 UTC 的正偏移或负偏移。例如,CET(比 UTC 早 1 小时)是 0100

代码语言:javascript复制
 RFC 2822 

RFC 2822 描述的标准电子邮件格式,例如Thu, 07 Apr 2005 22:13:13 0200

代码语言:javascript复制
 ISO 8601 

ISO 8601 标准规定的时间和日期,例如2005-04-07T22:13:13。解析器也接受空格而不是T字符。

| 注意 | 此外,日期部分以下列格式接受:YYYY.MM.DDMM/DD/YYYYDD.MM.YYYY。 |

也可以看看

git-check-ref-format [1] 。 git-config [1] 。

GIT

部分 git [1] 套件

git-worktree

原文: git-scm.com/docs/git-worktree

名称

git-worktree - 管理多个工作树

概要

代码语言:javascript复制
git worktree add [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]
git worktree list [--porcelain]
git worktree lock [--reason <string>] <worktree>
git worktree move <worktree> <new-path>
git worktree prune [-n] [-v] [--expire <expire>]
git worktree remove [-f] <worktree>
git worktree unlock <worktree>

描述

管理连接到同一存储库的多个工作树。

git 存储库可以支持多个工作树,允许您一次签出多个分支。使用git worktree add,新的工作树与存储库相关联。这个新的工作树称为“链接工作树”,而不是“git init”或“git clone”编写的“主工作树”。存储库有一个主要工作树(如果它不是裸存储库)和零个或多个链接工作树。完成链接的工作树后,使用git worktree remove将其删除。

如果在不使用git worktree remove的情况下删除工作树,则其关联的管理文件(位于下面的“详细信息”)最终将自动删除(请参阅 [git-config 中的gc.worktreePruneExpire [1] ]](https://git-scm.com/docs/git-config) ),或者您可以在主要或任何链接的工作树中运行git worktree prune来清理任何陈旧的管理文件。

如果链接的工作树存储在并非总是挂载的便携式设备或网络共享上,则可以通过发出git worktree lock命令来阻止其管理文件被修剪,可选择指定--reason来解释工作树被锁定的原因。

COMMANDS

代码语言:javascript复制
 add <path> [<commit-ish>] 

创建&lt;path&gt;并将&lt;commit-ish&gt;签出到其中。新的工作目录链接到当前存储库,共享除工作目录特定文件(如 HEAD,索引等)之外的所有内容。-也可以指定为&lt;commit-ish&gt;;它与@{-1}同义。

如果< commit-ish>是一个分支名称(称之为&lt;branch&gt;)并且未找到,并且既没有使用-b也没有-B--detach,但是在一个远程中确实存在跟踪分支(称之为&lt;remote&gt;)使用匹配的名称,视为等效于:

代码语言:javascript复制
$ git worktree add --track -b <branch> <path> <remote>/<branch>

如果分支存在于多个遥控器中,并且其中一个由checkout.defaultRemote配置变量命名,我们将使用该分支用于消除歧义,即使&lt;branch&gt;在所有遥控器中都不是唯一的。将其设置为例如如果&lt;branch&gt;不明确但存在于 _ 原点 _ 遥控器上,checkout.defaultRemote=origin总是从那里检出远程分支。另见 git-config [1] 中的checkout.defaultRemote

如果省略&lt;commit-ish&gt;并且既不使用-b也不使用-B--detach,那么为方便起见,新工作树与以$(basename &lt;path&gt;)命名的分支(称为&lt;branch&gt;)相关联。如果&lt;branch&gt;不存在,将自动创建基于 HEAD 的新分支,就像给出-b &lt;branch&gt;一样。如果&lt;branch&gt;确实存在,它将在新的工作树中检出,如果它没有在其他任何地方检出,否则命令将拒绝创建工作树(除非使用--force)。

代码语言:javascript复制
 list 

列出每个工作树的详细信息。首先列出主要工作树,然后列出每个链接的工作树。输出详细信息包括工作树是否裸露,当前检出的修订版,以及当前检出的分支(或者 _ 分离 HEAD_ ,如果没有)。

代码语言:javascript复制
 lock 

如果工作树位于未始终安装的便携式设备或网络共享上,请将其锁定以防止其管理文件被自动修剪。这也可以防止它被移动或删除。 (可选)使用--reason指定锁定的原因。

代码语言:javascript复制
 move 

将工作树移动到新位置。请注意,无法移动主工作树或包含子模块的链接工作树。

代码语言:javascript复制
 prune 

修剪$ GIT_DIR / worktrees 中的工作树信息。

代码语言:javascript复制
 remove 

删除一个工作树。只能删除干净的工作树(没有未跟踪的文件,也不会删除跟踪文件中的修改)。可以使用--force删除不干净的工作树或带子模块的工作树。无法删除主工作树。

代码语言:javascript复制
 unlock 

解锁工作树,允许对其进行修剪,移动或删除。

OPTIONS

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

默认情况下,add拒绝创建新的工作树,当&lt;commit-ish&gt;是分支名称并且已经被另一个工作树检出,或者&lt;path&gt;已经分配给某个工作树但是丢失了(例如,如果&lt;path&gt;被手动删除)。此选项会覆盖这些安全措施。要添加缺失但已锁定的工作树路径,请指定--force两次。

move拒绝移动锁定的工作树,除非指定了两次--force

remove拒绝删除不干净的工作树,除非使用--force。要删除锁定的工作树,请指定--force两次。

代码语言:javascript复制
 -b <new-branch> 
代码语言:javascript复制
 -B <new-branch> 

使用add,从&lt;commit-ish&gt;开始创建一个名为&lt;new-branch&gt;的新分支,并将&lt;new-branch&gt;签出到新的工作树中。如果省略&lt;commit-ish&gt;,则默认为 HEAD。默认情况下,-b拒绝创建新分支(如果已存在)。 -B会覆盖此保护措施,将&lt;new-branch&gt;重置为&lt;commit-ish&gt;

代码语言:javascript复制
 --detach 

使用add,在新工作树中分离 HEAD。请参见 git-checkout [1] 中的“DETACHED HEAD”。

代码语言:javascript复制
 --[no-]checkout 

默认情况下,add检出&lt;commit-ish&gt;,但是,--no-checkout可用于抑制检出以进行自定义,例如配置稀疏检出。请参见 git-read-tree [1] 中的“稀疏检出”。

代码语言:javascript复制
 --[no-]guess-remote 

使用worktree add &lt;path&gt;,不使用&lt;commit-ish&gt;,而不是从 HEAD 创建新分支,如果在一个与&lt;path&gt;的基本名称匹配的远程中存在跟踪分支,则将新分支基于远程跟踪分支,并标记远程跟踪分支作为新分支的“上游”。

也可以使用worktree.guessRemote配置选项将其设置为默认行为。

代码语言:javascript复制
 --[no-]track 

创建新分支时,如果&lt;commit-ish&gt;是分支,则将其标记为新分支的“上游”。如果&lt;commit-ish&gt;是远程跟踪分支,则这是默认值。有关详细信息,请参阅 git-branch [1] 中的“–track”。

代码语言:javascript复制
 --lock 

创建后保持工作树锁定。这相当于git worktree add之后的git worktree lock,但没有竞争条件。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --dry-run 

使用prune时,不要删除任何东西;只需报告它将删除的内容。

代码语言:javascript复制
 --porcelain 

使用list,以易于解析的格式输出脚本。无论用户配置如何,这种格式在 Git 版本中都将保持稳定。请参阅下文了解详情。

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

使用 _ 添加 _,禁止反馈消息。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

使用prune,报告所有删除。

代码语言:javascript复制
 --expire <time> 

使用prune,仅使未使用的工作树超过< time>。

代码语言:javascript复制
 --reason <string> 

使用lock解释工作树被锁定的原因。

代码语言:javascript复制
 <worktree> 

工作树可以通过路径来识别,无论是相对的还是绝对的。

如果工作树路径中的最后一个路径组件在工作树中是唯一的,则可以使用它来识别工作树。例如,如果你只有两个工作树,在“/ abc / def / ghi”和“/ abc / def / ggg”,那么“ghi”或“def / ghi”足以指向前工作树。

REFS

在多个工作树中,一些参考树可以在所有工作树之间共享,一些参考树是本地的。一个例子是 HEAD 对于所有工作树都是不同的。本节介绍共享规则以及如何从另一个工作树访问 refs。

通常,所有伪引用都是每个工作树,并且所有以“refs /”开头的引用都是共享的。伪引用类似 HEAD,直接在 GIT_DIR 下而不是在 GIT_DIR / refs 内。这有一个例外:refs / bisect 中的 refs 和不共享 refs / worktree。

仍然可以通过两个特殊路径(main-worktree 和 worktree)从另一个工作树访问每个工作树的引用。前者允许访问主工作树的每个工作树参考,而后者访问所有链接的工作树。

例如,main-worktree / HEAD 或 main-worktree / refs / bisect / good 分别解析为与主工作树的 HEAD 和 refs / bisect / good 相同的值。类似地,worktrees / foo / HEAD 或 worktrees / bar / refs / bisect / bad 与 GIT_COMMON_DIR / worktrees / foo / HEAD 和 GIT_COMMON_DIR / worktrees / bar / refs / bisect / bad 相同。

要访问 refs,最好不要直接查看 GIT_DIR。而是使用诸如 git-rev-parse [1] 或 git-update-ref [1] 之类的命令,它们将正确处理 refs。

配置文件

默认情况下,存储库“config”文件在所有工作树之间共享。如果配置变量core.barecore.worktree已经存在于配置文件中,它们将仅应用于主工作树。

为了具有特定于工作树的配置,您可以打开“worktreeConfig”扩展名,例如:

代码语言:javascript复制
$ git config extensions.worktreeConfig true

在此模式下,特定配置保留在git rev-parse --git-path config.worktree指向的路径中。您可以使用git config --worktree在此文件中添加或更新配置。较旧的 Git 版本将拒绝使用此扩展名访问存储库。

请注意,在此文件中,core.barecore.worktree的例外消失了。如果您之前在$ GIT_DIR / config 中有它们,则必须将它们移动到主工作树的config.worktree。您也可以借此机会查看并移动您不想共享的其他配置到所有工作树:

  • 永远不要共享core.worktreecore.bare
  • 除非您确定始终对所有工作树使用稀疏检出,否则建议每个工作树使用core.sparseCheckout

细节

每个链接的工作树在存储库的 GIT_DIR / worktrees 目录中都有一个私有子目录。私有子目录的名称通常是链接工作树路径的基本名称,可能附加一个数字以使其唯一。例如,当GIT_DIR=/path/main/.git命令git worktree add /path/other/test-next next在/path/other/test-next中创建链接的工作树时,还会创建GIT_DIR/worktrees/test-next目录(如果已经test-next,则创建GIT_DIR/worktrees/test-next1)。

在链接的工作树中, GIT_DIR 设置为指向此私有目录(例如示例中的/path/main/.git/worktrees/test-next),并且 GIT_COMMON_DIR 设置为指向主工作树的

通过git rev-parse --git-path的路径分辨率使用 GIT_DIR 或 GIT_COMMON_DIR,具体取决于路径。例如,在链接的工作树git rev-parse --git-path HEAD中返回/path/main/.git/worktrees/test-next/HEAD(不是/path/other/test-next/.git/HEAD或/path/main/.git/HEAD),而git rev-parse --git-path refs/heads/master使用

有关详细信息,请参阅 gitrepository-layout [5] 。经验法则是,当您需要直接访问 GIT_DIR 内的某些内容时,不要对路径是属于 GIT_DIR 还是

如果手动移动链接的工作树,则需要更新条目目录中的 gitdir 文件。例如,如果链接的工作树移动到/newpath/test-next并且其.git文件指向/path/main/.git/worktrees/test-next,则将/path/main/.git/worktrees/test-next/gitdir更新为引用/newpath/test-next

要防止$ GIT_DIR / worktrees 条目被修剪(这在某些情况下很有用,例如当条目的工作树存储在便携式设备上时),请使用git worktree lock命令,该命令添加名为 _ 的文件锁定 _ 到条目的目录。该文件包含纯文本的原因。例如,如果链接的工作树的.git文件指向/path/main/.git/worktrees/test-next,则名为/path/main/.git/worktrees/test-next/locked的文件将阻止test-next条目被修剪。有关详细信息,请参阅 gitrepository-layout [5] 。

启用 extensions.worktreeConfig 时,在.git/config之后读取配置文件.git/worktrees/&lt;id&gt;/config.worktree

列表输出格式

worktree list 命令有两种输出格式。默认格式显示包含列的单行详细信息。例如:

代码语言:javascript复制
$ git worktree list
/path/to/bare-source            (bare)
/path/to/linked-worktree        abcd1234 [master]
/path/to/other-linked-worktree  1234abc  (detached HEAD)
瓷器格式

瓷器格式每个属性都有一行。列出的属性标签和值由单个空格分隔。布尔属性(如 _ 裸 _ 和 _ 分离 _)仅作为标签列出,仅当值为真时才存在。工作树的第一个属性始终是worktree,空行表示记录的结尾。例如:

代码语言:javascript复制
$ git worktree list --porcelain
worktree /path/to/bare-source
bare

worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master

worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached

例子

您正处于重构阶段,您的老板进来并要求您立即修复。您通常可以使用 git-stash [1] 临时存储您的更改,但是,您的工作树处于混乱状态(使用新的,移动的和删除的文件以及其他零碎的部分)散落在你周围,你不想冒任何干扰它的风险。相反,您创建一个临时链接工作树来进行紧急修复,完成后将其删除,然后恢复您之前的重构会话。

代码语言:javascript复制
$ git worktree add -b emergency-fix ../temp master
$ pushd ../temp
# ... hack hack hack ...
$ git commit -a -m 'emergency fix for boss'
$ popd
$ git worktree remove ../temp

BUGS

一般的多次检出仍然是实验性的,对子模块的支持是不完整的。建议不要对超级项目进行多次检出。

GIT

部分 git [1] 套件

git-fetch

原文: git-scm.com/docs/git-fetch

名称

git-fetch - 从另一个存储库下载对象和引用

概要

代码语言:javascript复制
git fetch [<options>] [<repository> [<refspec>…​]]
git fetch [<options>] <group>
git fetch --multiple [<options>] [(<repository> | <group>)…​]
git fetch --all [<options>]

描述

从一个或多个其他存储库中获取分支和/或标记(统称为“refs”),以及完成其历史记录所需的对象。远程跟踪分支已更新(有关控制此行为的方法,请参阅下面< refspec>的说明)。

默认情况下,还会获取指向要获取的历史记录的任何标记;效果是获取指向您感兴趣的分支的标记。可以使用–tags 或–no-tags 选项或配置远程来更改此默认行为。< name> .tagOpt。通过使用明确获取标记的 refspec,您可以获取不指向您感兴趣的分支的标记。

git fetch 可以从单个命名的存储库或 URL 获取,或者如果< group>则从一个存储库获取。给出并且有一个遥控器。< group>配置文件中的条目。 (参见 git-config [1] )。

如果未指定远程,则默认情况下将使用origin远程,除非为当前分支配置了上游分支。

获取的引用名称及其指向的对象名称将写入.git/FETCH_HEAD。脚本或其他 git 命令可以使用此信息,例如 git-pull [1] 。

OPTIONS

代码语言:javascript复制
 --all 

获取所有遥控器。

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --append 

将获取的引用的引用名称和对象名称附加到.git/FETCH_HEAD的现有内容。如果没有此选项,.git/FETCH_HEAD中的旧数据将被覆盖。

代码语言:javascript复制
 --depth=<depth> 

从每个远程分支历史记录的提示限制提取到指定的提交数。如果使用--depth=&lt;depth&gt;选项(参见 git-clone [1] )获取git clone创建的 _ 浅 _ 存储库,请将历史记录加深或缩短到指定的提交数。不提取深化提交的标记。

代码语言:javascript复制
 --deepen=<depth> 

与–depth 类似,不同之处在于它指定了当前浅边界而不是每个远程分支历史记录的提交数。

代码语言:javascript复制
 --shallow-since=<date> 

深化或缩短浅存储库的历史记录,以包括< date>之后的所有可访问提交。

代码语言:javascript复制
 --shallow-exclude=<revision> 

深化或缩短浅存储库的历史记录,以排除从指定的远程分支或标记可到达的提交。可以多次指定此选项。

代码语言:javascript复制
 --unshallow 

如果源存储库已完成,请将浅存储库转换为完整存储库,从而消除浅存储库所施加的所有限制。

如果源存储库很浅,则尽可能多地获取,以便当前存储库与源存储库具有相同的历史记录。

代码语言:javascript复制
 --update-shallow 

默认情况下,从浅存储库中获取时,git fetch拒绝需要更新.git / shallow 的引用。此选项更新.git / shallow 并接受此类引用。

代码语言:javascript复制
 --negotiation-tip=<commit|glob> 

默认情况下,Git 将向服务器报告可从所有本地引用访问的提交,以查找公共提交以尝试减少要接收的包文件的大小。如果指定,Git 将仅报告从给定提示可到达的提交。当用户知道哪个本地 ref 可能与正在获取的上游引用有共同提交时,这对于加速提取是有用的。

可以多次指定此选项;如果是这样,Git 将报告从任何给定提交可到达的提交。

此选项的参数可以是 ref 的名称,ref 或者提交的(可能缩写的)SHA-1 上的 glob。指定 glob 等效于多次指定此选项,每个匹配的 ref 名称一个。

另请参见 git-config [1] 中记录的fetch.negotiationAlgorithm配置变量。

代码语言:javascript复制
 --dry-run 

显示将要完成的任务,而不进行任何更改。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

git fetch&lt;src&gt;:&lt;dst&gt; refspec 一起使用时,它可能会拒绝更新本地分支,如下面&lt;refspec&gt;部分所述。此选项会覆盖该检查。

代码语言:javascript复制
 -k 
代码语言:javascript复制
 --keep 

保持下载的包。

代码语言:javascript复制
 --multiple 

允许多个< repository>和< group>要指定的参数。不能指定< refspec> s。

代码语言:javascript复制
 -p 
代码语言:javascript复制
 --prune 

在获取之前,删除远程不再存在的任何远程跟踪引用。如果仅由于默认标记自动跟踪或由于–tags 选项而提取标记,则不对其进行修剪。但是,如果由于显式 refspec(在命令行或远程配置中,例如,如果使用–mirror 选项克隆远程),则会提取标记,那么它们也会受到修剪。提供--prune-tags是提供标签 refspec 的简写。

有关详细信息,请参阅下面的 PRUNING 部分。

代码语言:javascript复制
 -P 
代码语言:javascript复制
 --prune-tags 

在获取之前,如果启用了--prune,则删除遥控器上不再存在的任何本地标签。应该更仔细地使用此选项,与--prune不同,它将删除已创建的任何本地引用(本地标记)。此选项是提供显式标记 refspec 和--prune的简写,请参阅其文档中有关该标记的讨论。

有关详细信息,请参阅下面的 PRUNING 部分。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --no-tags 

默认情况下,指向从远程存储库下载的对象的标记将被提取并存储在本地。此选项会禁用此自动标记。可以使用远程。< name> .tagOpt 设置指定远程的默认行为。见 git-config [1] 。

代码语言:javascript复制
 --refmap=<refspec> 

在获取命令行中列出的引用时,使用指定的 refspec(可以多次给出)将 refs 映射到远程跟踪分支,而不是远程存储库的remote.*.fetch配置变量的值。有关详细信息,请参阅“已配置的远程跟踪分支”部分。

代码语言:javascript复制
 -t 
代码语言:javascript复制
 --tags 

从远程获取所有标记(即,将远程标记refs/tags/*提取到具有相同名称的本地标记),以及否则将获取的任何其他标记。即使使用了–prune,单独使用此选项也不会对标记进行修剪(尽管如果它们也是显式 refspec 的目标,则无论如何都可以修剪标记;请参阅--prune)。

代码语言:javascript复制
 --recurse-submodules[=yes|on-demand|no] 

此选项控制是否以及在何种条件下应该提取已填充的子模块的新提交。当设置为 no 时,它可以用作布尔选项来完全禁用递归,或者当设置为 yes 时无条件地递归到所有填充的子模块,这是使用此选项时的默认值没有任何价值。当超级项目检索到更新子模块对尚未在本地子模块克隆中的提交的引用的提交时,使用 _ 按需 _ 仅递归到填充的子模块。

代码语言:javascript复制
 -j 
代码语言:javascript复制
 --jobs=<n> 

用于获取子模块的并行子节点数。每个都将从不同的子模块中获取,这样获取许多子模块的速度会更快。默认情况下,将一次提取一个子模块。

代码语言:javascript复制
 --no-recurse-submodules 

禁用递归获取子模块(这与使用--recurse-submodules=no选项具有相同的效果)。

代码语言:javascript复制
 --submodule-prefix=<path> 

前置<路径>在信息性消息中打印的路径,例如“获取子模块 foo”。在子模块上递归时,此选项在内部使用。

代码语言:javascript复制
 --recurse-submodules-default=[yes|on-demand] 

此选项在内部用于临时为–recurse-submodules 选项提供非负默认值。所有其他配置 fetch 子模块递归的方法(例如 gitmodules [5] 和 git-config [1] 中的设置)都会覆盖此选项,指定 - [no-] recurse-submodules 直接。

代码语言:javascript复制
 -u 
代码语言:javascript复制
 --update-head-ok 

默认情况下 git fetch 拒绝更新与当前分支对应的头部。此标志禁用检查。这纯粹是为 git pull 内部使用与 git fetch 进行通信,除非你实现自己的瓷器,否则你不应该使用它。

代码语言:javascript复制
 --upload-pack <upload-pack> 

当给定,并且要获取的存储库由 git fetch-pack 处理时,--exec=&lt;upload-pack&gt;被传递给命令以指定另一端运行的命令的非默认路径。

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

将–quiet 转换为 git-fetch-pack 并使任何其他内部使用的 git 命令静音。未向标准错误流报告进度。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

要冗长。

代码语言:javascript复制
 --progress 

除非指定了-q,否则在将标准错误流附加到终端时,默认情况下会报告进度状态。即使标准错误流未定向到终端,此标志也会强制进度状态。

代码语言:javascript复制
 -o <option> 
代码语言:javascript复制
 --server-option=<option> 

使用协议版本 2 进行通信时,将给定的字符串传输到服务器。给定的字符串不得包含 NUL 或 LF 字符。当给出多个--server-option=&lt;option&gt;时,它们都按照命令行中列出的顺序发送到另一侧。

代码语言:javascript复制
 -4 
代码语言:javascript复制
 --ipv4 

仅使用 IPv4 地址,忽略 IPv6 地址。

代码语言:javascript复制
 -6 
代码语言:javascript复制
 --ipv6 

仅使用 IPv6 地址,忽略 IPv4 地址。

代码语言:javascript复制
 <repository> 

“远程”存储库,它是获取或拉取操作的源。该参数可以是 URL(参见下面的 GIT URL 部分)或遥控器的名称(参见下面的 REMOTES 部分)。

代码语言:javascript复制
 <group> 

一个名称,指的是存储库列表作为遥控器的值。< group>在配置文件中。 (参见 git-config [1] )。

代码语言:javascript复制
 <refspec> 

指定要获取的引用和要更新的本地引用。如果命令行中没有< refspec> s,则从remote.&lt;repository&gt;.fetch变量中读取要获取的引用(参见下面的配置的远程跟踪分支)。

< refspec>的格式参数是可选加 ,后跟源< src>,后跟冒号:,后跟目标 ref< dst>。当< dst>时,可以省略冒号。是空的。 < SRC>通常是 ref,但它也可以是完全拼写的十六进制对象名称。

tag &lt;tag&gt;表示与refs/tags/&lt;tag&gt;:refs/tags/&lt;tag&gt;相同;它请求获取给定标记的所有内容。

匹配< src>的远程引用取出,如果< dst>不是空字符串,尝试更新与其匹配的本地引用。

在没有--force的情况下是否允许更新取决于它被提取到的 ref 命名空间,被提取的对象的类型,以及更新是否被认为是快进。通常,相同的规则适用于推送时的提取,请参阅 git-push [1] 的&lt;refspec&gt;...部分。 git fetch 特有的那些规则的例外情况如下所述。

直到 Git 版本 2.20,并且与使用 git-push [1] 推送时不同,对refs/tags/*的任何更新都将在 refspec(或--force)中没有 的情况下被接受。在获取时,我们会混淆地将远程的所有标记更新视为强制提取。从 Git 版本 2.20 开始,获取更新refs/tags/*的方式与推送时相同。即如果没有 refspec(或--force)中的 ,任何更新都将被拒绝。

与使用 git-push [1] 进行推送时不同,[refdpec(或--force)中的 将接受refs/{tags,heads}/*以外的任何更新,无论是否交换,例如一个 blob 的树对象,或另一个提交的提交,它没有先前的提交作为祖先等。

与使用 git-push [1] 进行推送不同,没有任何配置可以修改这些规则,也没有类似于pre-receive挂钩的pre-fetch挂钩。

与使用 git-push [1] 推送一样,可以通过向 refspec 添加可选的前导 (或使用--force来覆盖上面描述的关于不允许作为更新的所有规则。 ]命令行选项)。唯一的例外是没有任何强制将使refs/heads/*命名空间接受非提交对象。

| 注意 | 当你想要获取的远程分支被认为是经常倒带和重新定位时,预计它的新提示将不会是其上一个提示的后代(如上次提取时存储在远程跟踪分支中)。您可能希望使用 符号来指示此类分支将需要非快进更新。无法确定或声明具有此行为的存储库中的分支可用;拉动用户只需知道这是分支的预期使用模式。 |

GIT 网址

通常,URL 包含有关传输协议,远程服务器的地址以及存储库路径的信息。根据传输协议,可能缺少某些信息。

Git 支持 ssh,git,http 和 https 协议(此外,ftp 和 ftps 可用于获取,但这是低效的并且已弃用;请勿使用它)。

本机传输(即 git:// URL)不进行身份验证,应在不安全的网络上谨慎使用。

可以使用以下语法:

  • SSH:// [用户@] host.xz [:端口] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /path/to/repo.git/
  • HTTP [S]://host.xz [:端口] /path/to/repo.git/
  • FTP [S]://host.xz [:端口] /path/to/repo.git/

另一种类似 scp 的语法也可以与 ssh 协议一起使用:

  • [用户@] host.xz:路径/到/ repo.git /

只有在第一个冒号之前没有斜杠时才会识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径foo:bar可以指定为绝对路径或./foo:bar,以避免被误解为 ssh url。

ssh 和 git 协议还支持〜用户名扩展:

  • SSH:// [用户@] host.xz [:端口] /〜[用户] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /〜[用户] /path/to/repo.git/
  • [用户@] host.xz:/〜[用户] /path/to/repo.git/

对于本地也受 Git 支持的本地存储库,可以使用以下语法:

  • /path/to/repo.git/
  • 文件:///path/to/repo.git/

这两种语法大多是等价的,除了克隆时,前者暗示–local 选项。有关详细信息,请参阅 git-clone [1] 。

当 Git 不知道如何处理某种传输协议时,它会尝试使用 remote-< transport> 远程助手,如果存在的话。要显式请求远程帮助程序,可以使用以下语法:

  • <运输> ::<地址>

其中<地址>可以是路径,服务器和路径,或者由被调用的特定远程助手识别的任意类似 URL 的字符串。有关详细信息,请参阅 gitremote-helpers [1] 。

如果存在大量具有相似名称的远程存储库,并且您希望为它们使用不同的格式(以便将您使用的 URL 重写为有效的 URL),则可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		insteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

像“work:repo.git”这样的 URL 或类似“host.xz:/path/to/repo.git”的 URL 将在任何带有 URL 的上下文中被重写为“git://git.host.xz/repo” git 的”。

如果要为仅推送重写 URL,可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		pushInsteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”这样的网址将被重写为“ssh://example.org/path/to/repo.git”以进行推送,但是 pull 仍会使用原始网址。

遥控

可以使用以下某个名称而不是 URL 作为&lt;repository&gt;参数:

  • Git 配置文件中的一个遥控器:$GIT_DIR/config
  • $GIT_DIR/remotes目录中的文件,或
  • $GIT_DIR/branches目录中的文件。

所有这些也允许你从命令行省略 refspec,因为它们每个都包含一个 git 将默认使用的 refspec。

在配置文件中命名为 remote

您可以选择使用 git-remote [1] , git-config [1] 提供之前配置的遥控器的名称,甚至可以手动编辑$GIT_DIR/config文件。此远程的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则默认情况下将使用此远程的 refspec。配置文件中的条目如下所示:

代码语言:javascript复制
	[remote "<name>"]
		url = <url>
		pushurl = <pushurl>
		push = <refspec>
		fetch = <refspec>

&lt;pushurl&gt;仅用于推送。它是可选的,默认为&lt;url&gt;

$GIT_DIR/remotes中的命名文件

您可以选择在$GIT_DIR/remotes中提供文件名。此文件中的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则此文件中的 refspec 将用作默认值。该文件应具有以下格式:

代码语言:javascript复制
	URL: one of the above URL format
	Push: <refspec>
	Pull: <refspec>

git push 使用Push:行, git pullgit fetch 使用Pull:系。可以为其他分支映射指定多个Push:Pull:行。

$GIT_DIR/branches中的命名文件

您可以选择在$GIT_DIR/branches中提供文件名。此文件中的 URL 将用于访问存储库。该文件应具有以下格式:

代码语言:javascript复制
	<url>#<head>

&lt;url&gt;是必需的; #&lt;head&gt;是可选的。

根据操作,如果您没有在命令行上提供一个 refitpec,git 将使用以下 refspec 之一。 &lt;branch&gt;$GIT_DIR/branches中此文件的名称,&lt;head&gt;默认为master

git fetch 使用:

代码语言:javascript复制
	refs/heads/<head>:refs/heads/<branch>

git push 使用:

代码语言:javascript复制
	HEAD:refs/heads/<head>

配置的远程跟踪分支

您经常通过定期重复从中获取相同的远程存储库。为了跟踪这种远程存储库的进度,git fetch允许您配置remote.&lt;repository&gt;.fetch配置变量。

通常这样的变量可能如下所示:

代码语言:javascript复制
[remote "origin"]
	fetch =  refs/heads/*:refs/remotes/origin/*

此配置以两种方式使用:

  • 运行git fetch时未指定要在命令行上获取的分支和/或标记,例如, git fetch origingit fetchremote.&lt;repository&gt;.fetch值用作 refspecs-它们指定要获取的 refs 和要更新的本地 refs。上面的示例将获取origin中存在的所有分支(即,与值的左侧匹配的任何 ref,refs/heads/*)并更新refs/remotes/origin/*层次结构中的相应远程跟踪分支。
  • 当使用显式分支和/或标记运行git fetch以在命令行上获取时,例如, git fetch origin master,在命令行上给出的< refspec>确定要取出的内容(例如示例中的master,这是master:的简写,这反过来意味着“获取 ] master 分支但是我没有明确说出要从命令行“更新它的远程跟踪分支”,并且示例命令将只获取 _ 主 _ 分支。 remote.&lt;repository&gt;.fetch值确定更新哪个远程跟踪分支(如果有)。当以这种方式使用时,remote.&lt;repository&gt;.fetch值对决定 _ 获取 _ 的内容没有任何影响(即,当命令行列出 refspecs 时,这些值不用作 refspecs);它们仅用于决定 _ 其中 _ 通过充当映射来存储所获取的引用。

后一次使用remote.&lt;repository&gt;.fetch值可以通过在命令行上给出--refmap=&lt;refspec&gt;参数来覆盖。

修枝

Git 有一个默认的保存数据,除非它被明确地丢弃;这延伸到持有本地对引用的本地引用,这些引用本身已经删除了那些分支。

如果留下累积,这些过时的引用可能会使具有大量分支流失的大而繁忙的存储库的性能变差,例如使git branch -a --contains &lt;commit&gt;等命令的输出不必要地冗长,并影响任何可以使用完整的已知引用集的其他任何东西。

这些远程跟踪引用可以作为一次性删除,其中包括:

代码语言:javascript复制
# While fetching
$ git fetch --prune <name>

# Only prune, don't fetch
$ git remote prune <name>

要将引用修剪为正常工作流程的一部分而不需要记住运行它,请在配置中全局设置fetch.prune,或者在远程设置remote.&lt;name&gt;.prune。见 git-config [1] 。

事情变得棘手和具体。修剪功能实际上并不关心分支,而是将修剪本地<→远程引用作为远程 refspec 的函数(参见上面的&lt;refspec&gt;和配置远程跟踪分支] )。

因此,如果遥控器的 refspec 包括例如refs/tags/*:refs/tags/*,或您手动运行,例如git fetch --prune &lt;name&gt; "refs/tags/*:refs/tags/*"它不会是被删除的过时远程跟踪分支,而是远程上不存在的任何本地标记。

这可能不是您所期望的,即您想要修剪远程&lt;name&gt;,但也要从中明确地获取标记,因此当您从中获取时,您将删除所有本地标记,其中大多数可能不是来自&lt;name&gt; ]遥远的第一名。

因此在使用像refs/tags/*:refs/tags/*这样的 refspec 或任何其他可能将多个遥控器的引用映射到同一本地命名空间的 refspec 时要小心。

由于在遥控器上保持最新的分支和标签是一个常见的用例,--prune-tags选项可以与--prune一起提供,以修剪遥控器上不存在的本地标签,并强制 - 更新那些不同的标签。也可以使用配置中的fetch.pruneTagsremote.&lt;name&gt;.pruneTags启用标签修剪。见 git-config [1] 。

--prune-tags选项相当于在遥控器的 refspecs 中声明了refs/tags/*:refs/tags/*。这可能会导致一些看似奇怪的互动:

代码语言:javascript复制
# These both fetch tags
$ git fetch --no-tags origin 'refs/tags/*:refs/tags/*'
$ git fetch --no-tags --prune-tags origin

在没有--prune或其配置版本的情况下提供它时不会出错的原因是为了配置版本的灵活性,并在命令行标志之间以及配置版本之间保持 1 = 1 的映射。

例如,合理的是配置~/.gitconfig中的fetch.pruneTags=true,以便在git fetch --prune运行时修剪标签,而不会在没有--prune的情况下每次调用git fetch

使用--prune-tags修剪标签在获取 URL 而不是命名远程时也有效。这些将在原点上找不到所有修剪标签:

代码语言:javascript复制
$ git fetch origin --prune --prune-tags
$ git fetch origin --prune 'refs/tags/*:refs/tags/*'
$ git fetch <url of origin> --prune --prune-tags
$ git fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'

OUTPUT

“git fetch”的输出取决于所使用的传输方法;本节介绍通过 Git 协议(本地或通过 ssh)和 Smart HTTP 协议获取时的输出。

获取的状态以表格形式输出,每行代表单个 ref 的状态。每一行的形式如下:

代码语言:javascript复制
 <flag> <summary> <from> -> <to> [<reason>]

仅当使用–verbose 选项时,才会显示最新引用的状态。

在使用配置变量 fetch.output 指定的紧凑输出模式中,如果在另一个字符串中找到整个&lt;from&gt;&lt;to&gt;,则在另一个字符串中将其替换为*。例如,master -&gt; origin/master变为master -&gt; origin/*

代码语言:javascript复制
 flag 

一个表示 ref 状态的字符:

代码语言:javascript复制
 (space) 

成功获得快进;

代码语言:javascript复制
   

成功的强制更新;

代码语言:javascript复制
 - 

成功修剪参考;

代码语言:javascript复制
 t 

成功更新标签;

代码语言:javascript复制
 * 

成功获取新参考;

代码语言:javascript复制
 ! 

对于被拒绝或未能更新的引用;和

代码语言:javascript复制
 = 

对于一个最新的 ref,不需要提取。

代码语言:javascript复制
 summary 

对于成功获取的 ref,摘要以适合用作git log的参数的形式显示 ref 的旧值和新值(在大多数情况下这是&lt;old&gt;..&lt;new&gt;,而强制非快速的&lt;old&gt;...&lt;new&gt; - 转发更新)。

代码语言:javascript复制
 from 

从中获取远程引用的名称,减去其refs/&lt;type&gt;/前缀。在删除的情况下,远程 ref 的名称是“(none)”。

代码语言:javascript复制
 to 

要更新的本地引用的名称减去其refs/&lt;type&gt;/前缀。

代码语言:javascript复制
 reason 

一个人类可读的解释。在成功获取 refs 的情况下,不需要解释。对于失败的 ref,描述了失败的原因。

例子

更新远程跟踪分支:

代码语言:javascript复制
$ git fetch origin

上述命令从远程 refs / heads / namespace 复制所有分支,并将它们存储到本地 refs / remotes / origin / namespace,除非分支。< name> .fetch 选项用于指定非默认 refspec。

明确使用 refspecs:

代码语言:javascript复制
$ git fetch origin  pu:pu maint:tmp

这通过从远程存储库中的分支(分别)pumaint获取来更新(或根据需要创建)本地存储库中的分支putmp

pu分支即使不快进也会更新,因为它带有加号前缀; tmp不会。

查看远程分支,无需在本地存储库中配置远程:

代码语言:javascript复制
$ git fetch git://git.kernel.org/pub/scm/git/git.git maint
$ git log FETCH_HEAD

第一个命令从git://git.kernel.org/pub/scm/git/git.git的存储库中获取maint分支,第二个命令使用FETCH_HEAD检查 git-log [1] 的分支。最终将通过 git 的内置内务处理删除获取的对象(参见 git-gc [1] )。

安全

提取和推送协议的目的不是为了防止一方窃取不打算共享的其他存储库中的数据。如果您需要保护私有数据免受恶意对等方的攻击,那么最佳选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的命名空间对读访问控制无效;您应该只将命名空间的读访问权授予您信任的客户端,并具有对整个存储库的读访问权限。

已知的攻击向量如下:

  1. 受害者发送“有”行,宣传其拥有的对象的 ID,这些对象并未明确地用于共享,但如果对等方也拥有它们,则可用于优化转移。攻击者选择一个对象 ID X 来窃取并向 X 发送一个 ref,但不需要发送 X 的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有 X,并且稍后会将 X 的内容发送回攻击者。 (这种攻击对于客户端在服务器上执行是最直接的,通过在客户端有权访问的命名空间中创建 ref,然后获取它。服务器在客户端上执行它的最可能方式是“将“X”合并到一个公共分支中,并希望用户在此分支上执行其他工作,并将其推送回服务器,而不会注意到合并。)
  2. 与#1 一样,攻击者选择一个对象 ID X 来窃取。受害者发送攻击者已经拥有的对象 Y,并且攻击者错误地声称拥有 X 而不是 Y,因此受害者将 Y 作为针对 X 的增量发送。该增量显示 X 的区域与攻击者的 Y 类似。

BUGS

使用–recurse-submodules 只能在已检出的子模块中获取新的提交。例如,上游在超级项目的刚刚提取的提交中添加了一个新的子模块,子模块本身无法获取,因此无法在以后检查该子模块而无需再次进行提取。预计将在未来的 Git 版本中修复。

也可以看看

git-pull [1]

GIT

部分 git [1] 套件

git-pull

原文: git-scm.com/docs/git-pull 贡献者:Mrhuangyi

名称

git-pull - 从另一个存储库或本地分支获取并与其集成

概要

代码语言:javascript复制
git pull [<options>] [<repository> [<refspec>…​]]

描述

将来自远程存储库的更改合并到当前分支中。在默认模式下,git pullgit fetch的缩写,后跟git merge FETCH_HEAD

更确切地说, git pull 使用给定参数运行 git fetch 并调用 git merge 将检索到的分支头合并到当前分支中。使用--rebase,它运行 git rebase 而不是 git merge

<库>应该是传递给 git-fetch [1] 的一个远程存储库的名称。 <的 Refspec>可以命名任意远程引用(例如,标签的名称),或者甚至是具有相应远程跟踪分支的引用集合(例如,refs / heads / *:refs / remotes / origin / *),但通常它是远程存储库中分支的名称。

< repository>和< branch>的默认值从 git-branch [1] --track设置的当前分支的“远程”和“合并”配置中读取。

假设存在以下历史记录并且当前分支为“master”:

代码语言:javascript复制
	  A---B---C master on origin
	 /
    D---E---F---G master
	^
	origin/master in your repository

因为它偏离本地master(即E),所以“git pull”将从远程master分支获取并重放相应的更改,直到它的当前提交(C)在master上面并将结果记录在新提交中,同时记录两个父提交的名称以及描述更改的用户的日志消息。

代码语言:javascript复制
	  A---B---C origin/master
	 /         
    D---E---F---G---H master

有关详细信息,请参阅 git-merge [1] ,包括如何呈现和处理冲突。

在 Git 1.7.0 或更高版本中,要取消一个有冲突的合并,请使用git reset --merge警告:在旧版本的 Git 中,不鼓励使用未提交的更改运行 git pull :尽管或许可行,但它可能会使您处于难以退出的冲突状态

如果任何远程更改与本地未提交的更改重叠,则将自动取消合并并且不更改工作树。通过 git-stash [1] 拉动或存放它们之前,通常最好在工作顺序中进行任何局部更改。

OPTIONS

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

这将传递给基础 git-fetch 以在传输过程中进行静噪报告,并在合并期间将基础 git-merge 传递给静噪输出。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

传递–verbose 到 git-fetch 和 git-merge。

代码语言:javascript复制
 --[no-]recurse-submodules[=yes|on-demand|no] 

此选项控制是否应该获取和更新所有已填充子模块的新提交(请参阅 git-config [1] 和 gitmodules [5] )。

如果通过 rebase 完成检出,则本地子模块提交也会被重新设置。

如果通过合并完成更新,则解析并检出子模块冲突。

与合并相关的选项
代码语言:javascript复制
 --commit 
代码语言:javascript复制
 --no-commit 

执行合并并提交结果。此选项可用于覆盖–no-commit。

使用–no-commit 执行合并但假装合并失败并且不自动提交,以便让用户有机会在提交之前检查并进一步调整合并结果。

代码语言:javascript复制
 --edit 
代码语言:javascript复制
 -e 
代码语言:javascript复制
 --no-edit 

在提交成功的机械合并之前调用编辑器以进一步编辑自动生成的合并消息,以便用户可以解释并证明合并。 --no-edit选项可用于接受自动生成的消息(通常不鼓励这样做)。

较旧的脚本可能取决于不允许用户编辑合并日志消息的历史行为。他们将在运行git merge时看到编辑器打开。为了便于将此类脚本调整为更新的行为,可以在环境变量GIT_MERGE_AUTOEDIT的开头设置为no

代码语言:javascript复制
 --ff 

当合并解析为快进时,仅更新分支指针,而不创建合并提交。这是默认行为。

代码语言:javascript复制
 --no-ff 

即使合并解析为快进,也要创建合并提交。这是在 refs / tags / 层次结构中合并未存储在其自然位置的带注释(且可能已签名)的标记时的默认行为。

代码语言:javascript复制
 --ff-only 

拒绝以非零状态合并和退出,除非当前HEAD已经是最新的,或者合并可以解析为快进。

代码语言:javascript复制
 -S[<keyid>] 
代码语言:javascript复制
 --gpg-sign[=<keyid>] 

GPG 签署生成的合并提交。 keyid参数是可选的并且默认为提交者标识;如果具体指定,它必须粘在没有空格的选项上。

代码语言:javascript复制
 --log[=<n>] 
代码语言:javascript复制
 --no-log 

除了分支名称之外,还使用最多< n>的单行描述填充日志消息。正在合并的实际提交。另见 git-fmt-merge-msg [1] 。

使用–no-log 不会列出正在合并的实际提交中的单行描述。

代码语言:javascript复制
 --signoff 
代码语言:javascript复制
 --no-signoff 

在提交日志消息的末尾由提交者逐行添加签名。签收的含义取决于项目,但它通常证明提交者有权在同一许可下提交此作品并同意开发者原产地证书(参见 developercertificate.org/ ] 欲获得更多信息)。

使用–no-signoff 时不要添加类似 Sign-off-by 的短行。

代码语言:javascript复制
 --stat 
代码语言:javascript复制
 -n 
代码语言:javascript复制
 --no-stat 

在合并结束时显示 diffstat。 diffstat 也由配置选项 merge.stat 控制。

使用-n 或–no-stat 时,在合并结束时不显示 diffstat。

代码语言:javascript复制
 --squash 
代码语言:javascript复制
 --no-squash 

生成工作树和索引状态,就好像发生了真正的合并(合并信息除外),但实际上没有提交,移动HEAD或记录$GIT_DIR/MERGE_HEAD(导致下一个git commit命令到创建合并提交)。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支(或章鱼的情况下更多)相同。

使用–no-squash 执行合并并提交结果。此选项可用于覆盖–squash。

代码语言:javascript复制
 -s <strategy> 
代码语言:javascript复制
 --strategy=<strategy> 

使用给定的合并策略;可以多次提供,以按照应该尝试的顺序指定它们。如果没有-s选项,则使用内置的策略列表(合并单个头时 git merge-recursive ,否则使用 git merge-octopus )。

代码语言:javascript复制
 -X <option> 
代码语言:javascript复制
 --strategy-option=<option> 

将合并策略特定选项传递给合并策略。

代码语言:javascript复制
 --verify-signatures 
代码语言:javascript复制
 --no-verify-signatures 

验证正在合并的侧分支的提示提交是否使用有效密钥签名,即具有有效 uid 的密钥:在默认信任模型中,这意味着签名密钥已由可信密钥签名。如果侧分支的提示提交未使用有效密钥签名,则合并将中止。

代码语言:javascript复制
 --summary 
代码语言:javascript复制
 --no-summary 

同义词–stat 和–no-stat;这些已被弃用,将来会被删除。

代码语言:javascript复制
 --allow-unrelated-histories 

默认情况下,git merge命令拒绝合并不共享共同祖先的历史记录。在合并独立开始生命的两个项目的历史时,此选项可用于覆盖此安全性。由于这是一种非常罕见的情况,因此默认情况下不会启用任何配置变量来启用它,也不会添加。

代码语言:javascript复制
 -r 
代码语言:javascript复制
 --rebase[=false|true|merges|preserve|interactive] 

如果为 true,则在获取后将当前分支重新绑定在上游分支的顶部。如果存在与上游分支对应的远程跟踪分支,并且自上次提取以来上游分支已重新定位,则 rebase 使用该信息来避免重新定位非本地更改。

设置为merges时,使用git rebase --rebase-merges进行 rebase,以便本地合并提交包含在 rebase 中(有关详细信息,请参阅 git-rebase [1] )。

设置为 preserve 时,将--preserve-merges选项的 rebase 传递给git rebase,以便本地创建的合并提交不会被展平。

如果为 false,则将当前分支合并到上游分支中。

当为interactive时,启用 rebase 的交互模式。

如果要使git pull始终使用--rebase而不是合并,请参见 git-config [1] 中的pull.rebasebranch.&lt;name&gt;.rebasebranch.autoSetupRebase

| 注意 | 这是一种潜在的 _ 危险 _ 操作模式。它重写了历史,当你已经发布了这段历史时,它并不是一个好兆头。除非您仔细阅读 git-rebase [1] ,否则不能使用此选项。 |

代码语言:javascript复制
 --no-rebase 

先覆盖–rebase。

代码语言:javascript复制
 --autostash 
代码语言:javascript复制
 --no-autostash 

在开始 rebase 之前,根据需要隐藏本地修改(参见 git-stash [1] ),并在完成后应用存储条目。 --no-autostash用于覆盖rebase.autoStash配置变量(参见 git-config [1] )。

此选项仅在使用“–rebase”时有效。

与获取相关的选项
代码语言:javascript复制
 --all 

获取所有遥控器。

代码语言:javascript复制
 -a 
代码语言:javascript复制
 --append 

将获取的引用的引用名称和对象名称附加到.git/FETCH_HEAD的现有内容。如果没有此选项,.git/FETCH_HEAD中的旧数据将被覆盖。

代码语言:javascript复制
 --depth=<depth> 

从每个远程分支历史记录的提示限制提取到指定的提交数。如果使用--depth=&lt;depth&gt;选项(参见 git-clone [1] )获取git clone创建的 _ 浅 _ 存储库,请将历史记录加深或缩短到指定的提交数。不提取深化提交的标记。

代码语言:javascript复制
 --deepen=<depth> 

与–depth 类似,不同之处在于它指定了当前浅边界而不是每个远程分支历史记录的提交数。

代码语言:javascript复制
 --shallow-since=<date> 

深化或缩短浅存储库的历史记录,以包括< date>之后的所有可访问提交。

代码语言:javascript复制
 --shallow-exclude=<revision> 

深化或缩短浅存储库的历史记录,以排除从指定的远程分支或标记可到达的提交。可以多次指定此选项。

代码语言:javascript复制
 --unshallow 

如果源存储库已完成,请将浅存储库转换为完整存储库,从而消除浅存储库所施加的所有限制。

如果源存储库很浅,则尽可能多地获取,以便当前存储库与源存储库具有相同的历史记录。

代码语言:javascript复制
 --update-shallow 

默认情况下,从浅存储库中获取时,git fetch拒绝需要更新.git / shallow 的引用。此选项更新.git / shallow 并接受此类引用。

代码语言:javascript复制
 --negotiation-tip=<commit|glob> 

默认情况下,Git 将向服务器报告可从所有本地引用访问的提交,以查找公共提交以尝试减少要接收的包文件的大小。如果指定,Git 将仅报告从给定提示可到达的提交。当用户知道哪个本地 ref 可能与正在获取的上游引用有共同提交时,这对于加速提取是有用的。

此选项可以多次被指定;如果是这样,Git 将报告从任何给定的提交中可访问的提交。

此选项的参数可以是 ref 的名称,ref 或者提交的(可能缩写的)SHA-1 上的 glob。指定 glob 等效于多次指定此选项,每个匹配对应的一个 ref 名称。

另请参见 git-config [1] 中记录的fetch.negotiationAlgorithm配置变量。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

git fetch&lt;src&gt;:&lt;dst&gt; refspec 一起使用时,它可能会拒绝更新本地分支,如 git-fetch [1] 文档的&lt;refspec&gt;部分所述。此选项会覆盖该检查。

代码语言:javascript复制
 -k 
代码语言:javascript复制
 --keep 

保持下载的包。

代码语言:javascript复制
 --no-tags 

默认情况下,指向从远程存储库下载的对象的标记将被提取并存储在本地。此选项会禁用此自动标记。可以使用远程。< name> .tagOpt 设置指定远程的默认行为。见 git-config [1] 。

代码语言:javascript复制
 -u 
代码语言:javascript复制
 --update-head-ok 

默认情况下 git fetch 拒绝更新与当前分支对应的头部。此标志禁用检查。这纯粹是为 git pullgit fetch 内部使用时进行通信,除非你实现你自己的瓷器,否则你不应该使用它。

代码语言:javascript复制
 --upload-pack <upload-pack> 

当给定,并且要获取的存储库由 git fetch-pack 处理时,--exec=&lt;upload-pack&gt;被传递给命令以指定另一端运行的命令的非默认路径。

代码语言:javascript复制
 --progress 

除非指定了-q,否则在将标准错误流附加到终端时,默认情况下会报告进度状态。即使标准错误流未定向到终端,此标志也会强制进度状态。

代码语言:javascript复制
 -o <option> 
代码语言:javascript复制
 --server-option=<option> 

使用协议版本 2 进行通信时,将给定的字符串传输到服务器。给定的字符串不得包含 NUL 或 LF 字符。当给出多个--server-option=&lt;option&gt;时,它们都按照命令行中列出的顺序发送到另一侧。

代码语言:javascript复制
 -4 
代码语言:javascript复制
 --ipv4 

仅使用 IPv4 地址,忽略 IPv6 地址。

代码语言:javascript复制
 -6 
代码语言:javascript复制
 --ipv6 

仅使用 IPv6 地址,忽略 IPv4 地址。

代码语言:javascript复制
 <repository> 

“远程”存储库,它是获取或拉取操作的源。该参数可以是 URL(参见下面的 GIT URL 部分)或 remote 的名称(参见下面的 REMOTES 部分)。

代码语言:javascript复制
 <refspec> 

指定要获取的引用和要更新的本地引用。如果命令行中没有< refspec> s,则从remote.&lt;repository&gt;.fetch变量读取 reff to fetch(参见 git-fetch [1] )。

< refspec>的格式参数是可选加 ,后跟源< src>,后跟冒号:,后跟目标 ref< dst>。当< dst>时,可以省略冒号。是空的。 < SRC>通常是 ref,但它也可以是完全拼写的十六进制对象名称。

tag &lt;tag&gt;表示与refs/tags/&lt;tag&gt;:refs/tags/&lt;tag&gt;相同;它请求获取给定标记的所有内容。

匹配< src>的远程引用取出,如果< dst>不是空字符串,尝试更新与其匹配的本地引用。

在没有--force的情况下是否允许更新取决于它被提取到的 ref 命名空间,被提取的对象的类型,以及更新是否被认为是快进。通常,相同的规则适用于推送时的提取,请参阅 git-push [1] 的&lt;refspec&gt;...部分。 git fetch 特有的那些规则的例外情况如下所述。

直到 Git 版本 2.20,并且与使用 git-push [1] 推送时不同,对refs/tags/*的任何更新都将在 refspec(或--force)中没有 的情况下被接受。在获取时,我们会混淆地将远程的所有标记更新视为强制提取。从 Git 版本 2.20 开始,获取更新refs/tags/*的方式与推送时相同。即如果没有 refspec(或--force)中的 ,任何更新都将被拒绝。

与使用 git-push [1] 进行推送时不同,[refdpec(或--force)中的 将接受refs/{tags,heads}/*以外的任何更新,无论是否交换,例如一个 blob 的树对象,或另一个提交的提交,它没有先前的提交作为祖先等。

与使用 git-push [1] 进行推送不同,没有任何配置可以修改这些规则,也没有类似于pre-receive挂钩的pre-fetch挂钩。

与使用 git-push [1] 推送一样,可以通过向 refspec 添加可选的前导 (或使用--force 命令行选项)来覆盖上面描述的关于不允许作为更新的所有规则。。唯一的例外是没有任何强制将使refs/heads/*命名空间接受非提交对象。

| 注意 | 当你想要获取的远程分支被认为是经常倒带和重新定位时,预计它的新提示将不会是其上一个提示的后代(如上次提取时存储在远程跟踪分支中)。您可能希望使用 符号来指示此类分支将需要非快进更新。无法确定或声明具有此行为的存储库中的分支可用;拉动用户只需知道这是分支的预期使用模式。 |

| 注意 | 在 git pull 命令行上直接列出多个< refspec&gt 和在您的配置中为< repository>提供多个remote.&lt;repository&gt;.fetch条目并运行 git pull 命令,没有任何明确的< refspec>参数之间存在差异。在命令行中明确列出的< refspec>在获取后始终合并到当前分支中。换句话说,如果你列出多个远程引用, git pull 将创建一个 Octopus 合并。另一方面,如果你没有列出任何明确的< refspec>在命令行上的参数, git pull 将获取它在remote.&lt;repository&gt;.fetch配置中找到的所有< refspec> s 并仅合并第一个找到的< refspec>到当前的分支。这是因为很少使用远程参考设备制作八达通,而通过提取一个以上来一次跟踪多个远程磁头通常很有用。 |

GIT 网址

通常,URL 包含有关传输协议,远程服务器的地址以及存储库路径的信息。根据传输协议,可能缺少某些信息。

Git 支持 ssh,git,http 和 https 协议(此外,ftp 和 ftps 可用于获取,但这是低效的并且已被弃用;请勿使用它)。

本机传输(即 git:// URL)不进行身份验证,在不安全的网络上应当谨慎使用。

可以使用以下语法:

  • SSH:// [用户@] host.xz [:端口] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /path/to/repo.git/
  • HTTP [S]://host.xz [:端口] /path/to/repo.git/
  • FTP [S]://host.xz [:端口] /path/to/repo.git/

另一种类似 scp 的语法也可以与 ssh 协议一起使用:

  • [用户@] host.xz:路径/到/ repo.git /

只有在第一个冒号之前没有斜杠时才会识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径foo:bar可以指定为绝对路径或./foo:bar,以避免被误解为一个 ssh url。

ssh 和 git 协议还支持〜用户名扩展:

  • SSH:// [用户@] host.xz [:端口] /〜[用户] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /〜[用户] /path/to/repo.git/
  • [用户@] host.xz:/〜[用户] /path/to/repo.git/

对于本地也受 Git 支持的本地存储库,可以使用以下语法:

  • /path/to/repo.git/
  • 文件:///path/to/repo.git/

这两种语法大多是等价的,除了克隆时,前者暗示–local 选项。有关详细信息,请参阅 git-clone [1] 。

当 Git 不知道如何处理某种传输协议时,它会尝试使用 remote-< transport> 远程助手,如果存在的话。要显式请求远程帮助程序,可以使用以下语法:

  • <运输> ::<地址>

其中<地址>可以是路径,服务器和路径,或者由被调用的特定远程助手识别的任意类似 URL 的字符串。有关详细信息,请参阅 gitremote-helpers [1] 。

如果存在大量具有相似名称的远程存储库,并且您希望为它们使用不同的格式(以便将您使用的 URL 重写为有效的 URL),则可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		insteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

像“work:repo.git”这样的 URL 或类似“host.xz:/path/to/repo.git”的 URL 将在任何带有 URL 的上下文中被重写为“git://git.host.xz/repo” git 的”。

如果要为仅推送重写 URL,可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		pushInsteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”这样的网址将被重写为“ssh://example.org/path/to/repo.git”以进行推送,但是 pull 仍会使用原始网址。

遥控

可以使用以下某个名称而不是 URL 作为&lt;repository&gt;参数:

  • Git 配置文件中的一个遥控器:$GIT_DIR/config
  • $GIT_DIR/remotes目录中的文件,或
  • $GIT_DIR/branches目录中的文件。

所有这些也允许你从命令行省略 refspec,因为它们每个都包含一个 git 将默认使用的 refspec。

在配置文件中命名为 remote

您可以选择使用 git-remote [1] , git-config [1] 提供之前配置的遥控器的名称,甚至可以手动编辑$GIT_DIR/config文件。此远程的 URL 将用于访问存储库。如果你未在命令行上提供 refspec,则默认情况下将使用此远程的 refspec。配置文件中的条目如下所示:

代码语言:javascript复制
	[remote "<name>"]
		url = <url>
		pushurl = <pushurl>
		push = <refspec>
		fetch = <refspec>

&lt;pushurl&gt;仅用于推送。它是可选的,默认为&lt;url&gt;

$GIT_DIR/remotes中的命名文件

您可以选择在$GIT_DIR/remotes中提供文件名。此文件中的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则此文件中的 refspec 将用作默认值。该文件应具有以下格式:

代码语言:javascript复制
	URL: one of the above URL format
	Push: <refspec>
	Pull: <refspec>

git push 使用Push:行, git pullgit fetch 使用Pull:系。可以为其他分支映射指定多个Push:Pull:行。

$GIT_DIR/branches中的命名文件

您可以选择在$GIT_DIR/branches中提供文件名。此文件中的 URL 将用于访问存储库。该文件应具有以下格式:

代码语言:javascript复制
	<url>#<head>

&lt;url&gt;是必需的; #&lt;head&gt;是可选的。

根据操作,如果您没有在命令行上提供一个 refitpec,git 将使用以下 refspec 中的一个。 &lt;branch&gt;$GIT_DIR/branches中此文件的名称,&lt;head&gt;默认为master

git fetch 使用:

代码语言:javascript复制
	refs/heads/<head>:refs/heads/<branch>

git push 使用:

代码语言:javascript复制
	HEAD:refs/heads/<head>

合并战略

合并机制(git mergegit pull命令)允许使用-s选项选择后端 _ 合并策略 _。一些策略也可以采用自己的选项,可以通过向git merge和/或git pull提供-X&lt;option&gt;参数来传递。

代码语言:javascript复制
 resolve 

这只能使用 3 向合并算法解析两个头(即当前分支和您从中拉出的另一个分支)。它试图仔细检测纵横交错的合并模糊,并且通常被认为是安全和快速的。

代码语言:javascript复制
 recursive 

这只能使用 3 向合并算法解析两个磁头。当有多个可用于 3 向合并的共同祖先时,它会创建共同祖先的合并树,并将其用作 3 向合并的参考树。据报道,这会导致更少的合并冲突,而不会因为从 Linux 2.6 内核开发历史记录中进行的实际合并提交所做的测试而导致错误。此外,这可以检测和处理涉及重命名的合并,但目前无法使用检测到的副本。这是拉动或合并一个分支时的默认合并策略。

_ 递归 _ 策略可以采用以下选项:

代码语言:javascript复制
 ours 

这个选项通过支持 _ 我们的 _ 版本来强制大块的冲突干净地自动解决。来自与我们方不冲突的其他树的更改将反映到合并结果中。对于二进制文件,整个内容都来自我们这边。

这不应该与 _ 我们的 _ 合并策略混淆,后者甚至不会查看其他树包含的内容。它丢弃了另一棵树所做的一切,声明 _ 我们的 _ 历史记录中包含了所有发生的事情。

代码语言:javascript复制
 theirs 

这与 _ 我们的 _ 相反;请注意,与 _ 我们的 _ 不同,没有 _ 他们的 _ 合并策略来混淆这个合并选项。

代码语言:javascript复制
 patience 

使用此选项, merge-recursive 花费一点额外的时间来避免由于不重要的匹配行(例如,来自不同函数的大括号)而有时发生的错误。当要合并的分支发生疯狂分歧时使用此选项。另见 git-diff [1] --patience

代码语言:javascript复制
 diff-algorithm=[patience|minimal|histogram|myers] 

告诉 merge-recursive 使用不同的 diff 算法,这有助于避免由于不重要的匹配行(例如来自不同函数的大括号)而发生的错误。另见 git-diff [1] --diff-algorithm

代码语言:javascript复制
 ignore-space-change 
代码语言:javascript复制
 ignore-all-space 
代码语言:javascript复制
 ignore-space-at-eol 
代码语言:javascript复制
 ignore-cr-at-eol 

为了进行三向合并,将具有指示类型的空白的行更改为未更改。与空行的其他更改混合的空白更改不会被忽略。另见 git-diff [1] -b-w--ignore-space-at-eol--ignore-cr-at-eol

  • 如果 _ 他们的 _ 版本只将空格更改引入一行,_ 我们的 _ 版本被使用;
  • 如果 _ 我们的 _ 版本引入了空格更改,但 _ 他们的 _ 版本包含了实质性更改,_ 使用了他们的 _ 版本;
  • 否则,合并以通常的方式进行。
代码语言:javascript复制
 renormalize 

在解析三向合并时,这将运行虚拟签出并检入文件的所有三个阶段。此选项适用于将分支与不同的清除过滤器或行尾规范化规则合并时使用。有关详细信息,请参阅 gitattributes [5] 中的“合并具有不同签入/签出属性的分支”。

代码语言:javascript复制
 no-renormalize 

禁用renormalize选项。这会覆盖merge.renormalize配置变量。

代码语言:javascript复制
 no-renames 

关闭重命名检测。这会覆盖merge.renames配置变量。另见 git-diff [1] --no-renames

代码语言:javascript复制
 find-renames[=<n>] 

打开重命名检测,可选择设置相似性阈值。这是默认值。这会覆盖 merge.renames 配置变量。另见 git-diff [1] --find-renames

代码语言:javascript复制
 rename-threshold=<n> 

已弃用find-renames=&lt;n&gt;的同义词。

代码语言:javascript复制
 subtree[=<path>] 

此选项是 _ 子树 _ 策略的更高级形式,其中策略猜测两个树在合并时必须如何移位以相互匹配。相反,指定的路径是前缀(或从头开始剥离),以使两个树的形状匹配。

代码语言:javascript复制
 octopus 

这解决了具有两个以上磁头的情况,但拒绝执行需要手动解决的复杂合并。它主要用于将主题分支头捆绑在一起。这是拉动或合并多个分支时的默认合并策略。

代码语言:javascript复制
 ours 

这会解析任意数量的头,但合并的结果树始终是当前分支头的树,实际上忽略了所有其他分支的所有更改。它旨在用于取代侧枝的旧发展历史。请注意,这与 _ 递归 _ 合并策略的-Xours 选项不同。

代码语言:javascript复制
 subtree 

这是一种修改后的递归策略。当合并树 A 和 B 时,如果 B 对应于 A 的子树,则首先调整 B 以匹配 A 的树结构,而不是读取相同级别的树。这种调整也是对共同的祖先树进行的。

使用三向合并的策略(包括默认的 _ 递归 _),如果在两个分支上进行了更改,但稍后在其中一个分支上进行了更改,则该更改将出现在合并结果中;有些人发现这种行为令人困惑。之所以会发生这种情况,是因为在执行合并时只考虑头和合并基础,而不是单个提交。因此,合并算法将恢复的更改视为完全没有更改,而是替换更改的版本。

违约行为

通常人们使用git pull而不给出任何参数。传统上,这相当于说git pull origin。但是,当在分支&lt;name&gt;上存在配置branch.&lt;name&gt;.remote时,将使用该值代替origin

为了确定用于获取的 URL,请参考配置remote.&lt;origin&gt;.url的值,如果没有任何此类变量,则使用$GIT_DIR/remotes/&lt;origin&gt;URL:行的值。

为了确定在命令行上没有任何 refspec 参数的情况下运行命令时要获取(并且可选地存储在远程跟踪分支中)的远程分支,将查询配置变量remote.&lt;origin&gt;.fetch的值,如果没有 t any,咨询$GIT_DIR/remotes/&lt;origin&gt;并使用其Pull:线。除了 OPTIONS 部分中描述的 refspec 格式之外,您还可以使用如下所示的 globbing refspec:

代码语言:javascript复制
refs/heads/*:refs/remotes/origin/*

globbing refspec 必须具有非空 RHS(即必须存储在远程跟踪分支中获取的内容),并且其 LHS 和 RHS 必须以/*结束。以上规定了使用相同名称的refs/remotes/origin/层次结构中的远程跟踪分支跟踪所有远程分支。

在获取之后确定要合并哪个远程分支的规则有点涉及,以便不破坏向后兼容性。

如果在git pull的命令行上给出了显式 refspec,则它们都被合并。

如果命令行上没有给出 refspec,则git pull使用配置中的 refspec 或$GIT_DIR/remotes/&lt;origin&gt;。在这种情况下,以下规则适用:

  1. 如果当前分支&lt;name&gt;branch.&lt;name&gt;.merge配置存在,那么这是合并的远程站点的分支的名称。
  2. 如果 refspec 是一个全局的,则不会合并任何内容。
  3. 否则,合并第一个 refspec 的远程分支。

例子

更新你克隆的存储库的远程跟踪分支,然后将其中一个合并到当前分支中:

代码语言:javascript复制
$ git pull
$ git pull origin

通常,合并的分支是远程存储库的 HEAD,但选择由分支确定。< name> .remote 和 branch。< name> .merge options;有关详细信息,请参阅 git-config [1] 。

合并到当前分支远程分支next

代码语言:javascript复制
$ git pull origin next

这会在 FETCH_HEAD 中暂时保留next的副本,但不会更新任何远程跟踪分支。使用远程跟踪分支,可以通过调用 fetch 和 merge 来完成相同的操作:

代码语言:javascript复制
$ git fetch origin
$ git merge origin/next

如果您尝试拉取后导致复杂冲突并且想要重新开始,则可以使用 git reset 进行恢复。

安全

设计提取和推送协议的目的不是为了防止一方窃取不打算共享的其他存储库中的数据。如果您需要保护私有数据免受恶意对等方的攻击,那么最佳选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的命名空间对读访问控制无效;您应该只将命名空间的读访问权授予您信任的客户端,并具有对整个存储库的读访问权限。

已知的攻击向量如下:

  1. 受害者发送“有”行,宣传其拥有的对象的 ID,这些对象并未明确地用于共享,但如果对等方也拥有它们,则可用于优化转移。攻击者选择一个对象 ID X 来窃取并向 X 发送一个 ref,但不需要发送 X 的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有 X,并且稍后会将 X 的内容发送回攻击者。 (这种攻击对于客户端在服务器上执行是最直接的,通过在客户端有权访问的命名空间中创建 ref,然后获取它。服务器在客户端上执行它的最可能方式是“将“X”合并到一个公共分支中,并希望用户在此分支上执行其他工作,并将其推送回服务器,而不会注意到合并。)
  2. 与#1 一样,攻击者选择一个对象 ID X 来窃取。受害者发送攻击者已经拥有的对象 Y,并且攻击者错误地声称拥有 X 而不是 Y,因此受害者将 Y 作为针对 X 的增量发送。该增量显示 X 的区域与攻击者的 Y 类似。

BUGS

使用–recurse-submodules 只能在已检出的子模块中获取新的提交。例如,当上游在超级项目的刚刚提取的提交中添加了一个新的子模块,子模块本身无法获取,因此无法在以后检查该子模块而无需再次进行提取。这预计将在未来的 Git 版本中被修复。

也可以看看

git-fetch [1] , git-merge [1] , git-config [1]

GIT

部分 git [1] 套件

git-push

原文: git-scm.com/docs/git-push

名称

git-push - 更新远程引用以及相关对象

概要

代码语言:javascript复制
git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
	   [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
	   [-u | --set-upstream] [-o <string> | --push-option=<string>]
	   [--[no-]signed|--signed=(true|false|if-asked)]
	   [--force-with-lease[=<refname>[:<expect>]]]
	   [--no-verify] [<repository> [<refspec>…​]]

描述

使用本地引用更新远程引用,同时发送完成给定引用所必需的对象。

通过在那里设置 _ 挂钩 _,当你每次推入存储库时都可以使存储库发生有趣的事情。请参阅 git-receive-pack [1] 的文档。

如果命令行未使用&lt;repository&gt;参数指定进行推送的位置,则会查询当前分支的branch.*.remote配置以确定推送位置。如果缺少相应配置,则默认为 _ 原点 _。

当命令行没有指定用&lt;refspec&gt;...参数或--all--mirror--tags选项推送什么时,该命令通过查询remote.*.push配置找到默认的&lt;refspec&gt;,如果找不到,根据push.default配置来决定推送什么(参见 git-config [1] 了解push.default的含义)。

当命令行和配置都没有指定要推送的内容时,则使用默认行为,它对应于push.defaultsimple值:当前分支被推送到相应的上游分支,但作为安全措施,如果上游分支与本地分支的名称不同,则推送被中止。

选项

代码语言:javascript复制
 <repository> 

作为推送操作目标的“远程”存储库。该参数可以是一个 URL(参见下面的 GIT URL 部分)或遥控器的名称(参见下面的 REMOTES 部分)。

代码语言:javascript复制
 <refspec>…​ 

使用什么源对象指定要更新的目标。 < refspec>参数的格式是可选加 ,后跟源对象< src>,后跟冒号:,后跟目标 ref< dst>。

< src>通常是您想要推送的分支的名称,但它可以是任意“SHA-1 表达式”,例如master~4HEAD(参见 gitrevisions [7] )。

< dst>通过此推送告知远程端的哪个 ref 已更新。这里不能使用任意表达式,必须命名实际的 ref。如果没有任何&lt;refspec&gt;参数的git push [&lt;repository&gt;]设置为使用&lt;src&gt;remote.&lt;repository&gt;.push配置变量更新目标的某些 ref,则可以省略:&lt;dst&gt;部分 - 这样的推送将更新&lt;src&gt;的参考号通常在命令行上没有任何&lt;refspec&gt;的情况下更新。否则,缺少:&lt;dst&gt;意味着更新与&lt;src&gt;相同的参考号。

如果< dst>不以refs/开头(例如refs/heads/master)我们将尝试推断目的地< repository>上的refs/*中的位置它属于< src>的类型被推,是否< dst>很暧昧。

  • 如果< dst>明确地引用远程< repository>上的引用。然后推送到那个参考。
  • 如果< src>被解析为以 refs / heads /或 refs / tags /开头的 ref,然后将其添加到< dst>。
  • 将来可能会添加其他歧义解决方案,但是现在任何其他情况都会出错,并指出我们尝试过的错误,并且取决于advice.pushUnqualifiedRefname配置(参见 git-config [1] )建议你可能想要推荐的 refs / namespace。

< src>引用的对象被用于更新< dst>远程参考。是否允许这取决于refs/*中< dst>的位置。参考活动如下面详细描述的那样,在这些部分中,“更新”是指除删除之外的任何修改,如下面几节中所述的不同处理。

refs/heads/*命名空间仅接受提交对象,并且只有在可以快速转发时才更新。

refs/tags/*命名空间将接受任何类型的对象(因为可以标记提交,树和 blob),并且将拒绝对它们的任何更新。

可以将任何类型的对象推送到refs/{tags,heads}/*之外的任何命名空间。对于标记和提交,这些将被视为它们是refs/heads/*内的提交,以确定是否允许更新。

即允许在refs/{tags,heads}/*之外快速提交提交和标记,即使在快速转发的内容不是提交的情况下,也允许标记对象恰好指向新提交,这是提交的快进它正在替换的最后一个标记(或提交)。如果标记指向相同的提交,并且推送剥离的标记,即推送现有标记对象指向的提交,或者现有提交指向的新标记对象,则也允许使用完全不同的标记替换标记。 。

refs/{tags,heads}/*之外的树和 blob 对象的处理方式与它们在refs/tags/*中的方式相同,任何对它们的更新都将被拒绝。

通过将可选的前导 添加到 refspec(或使用--force命令行选项),可以覆盖上面描述的关于不允许作为更新的所有规则。唯一的例外是没有任何强制将使refs/heads/*命名空间接受非提交对象。钩子和配置也可以覆盖或修改这些规则,参见例如 git-config [1] 中的receive.denyNonFastForwards和 githooks [5] 中的pre-receiveupdate

推空< src>允许您删除< dst>来自远程存储库的 ref。除非配置或挂钩禁止,否则始终在 refspec(或--force)中没有前导 的情况下接受删除。参见 git-config [1] 中的receive.denyDeletes和 githooks [5] 中的pre-receiveupdate

特殊 refspec :(或 :允许非快进更新)指示 Git 推送“匹配”分支:对于本地端存在的每个分支,如果远程端分支更新,则更新远程端名称已存在于远程端。

tag &lt;tag&gt;表示与refs/tags/&lt;tag&gt;:refs/tags/&lt;tag&gt;相同。

代码语言:javascript复制
 --all 

推送所有分支(即refs/heads/下的引用);不能与其他< refspec>一起使用。

代码语言:javascript复制
 --prune 

删除没有本地对应项的远程分支。例如,如果不再存在具有相同名称的本地分支,则将删除远程分支tmp。这也尊重 refspecs,例如如果refs/heads/foo不存在,git push --prune remote refs/heads/*:refs/tmp/*将确保远程refs/tmp/foo将被删除。

代码语言:javascript复制
 --mirror 

而不是将每个引用命名为 push,指定将refs/下的所有引用(包括但不限于refs/heads/refs/remotes/refs/tags/)镜像到远程存储库。新创建的本地引用将被推送到远程端,本地更新的引​​用将在远程端强制更新,并且已删除的引用将从远程端删除。如果设置了配置选项remote.&lt;remote&gt;.mirror,则这是默认值。

代码语言:javascript复制
 -n 
代码语言:javascript复制
 --dry-run 

做所有事情,除了实际发送更新。

代码语言:javascript复制
 --porcelain 

生成机器可读输出。每个引用的输出状态行将以制表符的形式分隔并发送到 stdout 而不是 stderr。我们将给出参考的完整符号名称。

代码语言:javascript复制
 -d 
代码语言:javascript复制
 --delete 

所有列出的引用都将从远程存储库中被删除。这与使用冒号为所有引号添加前缀相同。

代码语言:javascript复制
 --tags 

除了在命令行中明确列出的 refspec 之外,还会推送refs/tags下的所有引用。

代码语言:javascript复制
 --follow-tags 

推送没有此选项的将要被推送的所有引用,并且还在refs/tags中推送远程数据库中缺少的注释标记,但是指向可以从被推送的引用中访问的 commit-ish。也可以使用配置变量push.followTags指定。有关更多信息,请参阅 git-config [1] 中的push.followTags

代码语言:javascript复制
 --[no-]signed 
代码语言:javascript复制
 --signed=(true|false|if-asked) 

GPG 签署推送请求以更新接收方的 refs,以允许钩子检查和/或记录。如果记录为false--no-signed,则不会尝试签名。如果为true--signed,如果服务器不支持签名推送,则推送将失败。如果设置为if-asked,则当且仅当服务器支持签名推送时才签名。如果对gpg --sign的实际调用失败,推送也将失败。有关接收端的详细信息,请参阅 git-receive-pack [1] 。

代码语言:javascript复制
 --[no-]atomic 

如果可用,请在远程端使用原子事务。要么更新所有引用,要么在出错时,不更新引用。如果服务器不支持原子推送,则推送将失败。

代码语言:javascript复制
 -o <option> 
代码语言:javascript复制
 --push-option=<option> 

将给定的字符串传输到服务器,服务器将它们传递给预接收和后接收挂钩。给定的字符串不得包含 NUL 或 LF 字符。当给出多个--push-option=&lt;option&gt;时,它们都按照命令行中列出的顺序发送到另一侧。如果没有从命令行给出--push-option=&lt;option&gt;,则使用配置变量push.pushOption的值。

代码语言:javascript复制
 --receive-pack=<git-receive-pack> 
代码语言:javascript复制
 --exec=<git-receive-pack> 

远程端 git-receive-pack 程序的路径。当通过 ssh 推送到远程存储库时,有时很有用,并且您没有将程序放在默认$ PATH 上的目录中。

代码语言:javascript复制
 --[no-]force-with-lease 
代码语言:javascript复制
 --force-with-lease=<refname> 
代码语言:javascript复制
 --force-with-lease=<refname>:<expect> 

通常,“git push”拒绝更新远程 ref,该远程 ref 不是用于覆盖它的本地 ref 的祖先。

如果远程 ref 的当前值是预期值,则此选项将覆盖此限制。 否则“git push”会失败。

想象一下,你必须改变你已发表的内容。您必须绕过“必须快进”规则才能将最初发布的历史记录替换为重新定位的历史记录。如果其他人在您重新定位时建立在您的原始历史之上,那么远程分支的提示可能会随着她的提交而提前,并且盲目推动--force将失去她的工作。

此选项允许您说您希望更新的历史记录是您重新定义并想要替换的内容。如果远程引用仍然指向您指定的提交,您可以确定没有其他人对引用做过任何事情。这就像在 ref 上接受“租约”而没有明确地锁定它,并且仅当“lease”仍然有效时才会更新远程 ref。

单独--force-with-lease,没有指定细节,将通过要求它们的当前值与我们为它们提供的远程跟踪分支相同来保护将要更新的所有远程 ref。

--force-with-lease=&lt;refname&gt;,未指定期望值,将保护命名 ref(单独),如果要更新,则要求其当前值与我们为其设置的远程跟踪分支相同。

--force-with-lease=&lt;refname&gt;:&lt;expect&gt;将保护命名 ref(单独),如果它将要更新,通过要求其当前值与指定值&lt;expect&gt;相同(允许它与远程跟踪分支不同于我们的 refname,或者在使用此表单时我们甚至不必拥有这样的远程跟踪分支)。如果&lt;expect&gt;是空字符串,则指定的命名 ref 必须不存在。

请注意,除了--force-with-lease=&lt;refname&gt;:&lt;expect&gt;之外的所有明确指定 ref 的当前值的表单仍然是实验性的,并且随着我们获得与此功能相关的经验,它们的语义可能会发生变化。

“–no-force-with-lease”将在命令行中取消之前的所有–force-with-lease。

关于安全性的一般注意事项:提供没有预期值的该选项,即--force-with-lease--force-with-lease=&lt;refname&gt;与在遥控器上隐式运行git fetch以在后台推送的任何东西非常相互作用,例如,您在 Cronjob 中的存储库中的git fetch origin

它提供的保护优于--force,确保您的工作所依据的后续更改不会被破坏,但如果某些后台进程在后台更新引用,则这很容易被忽略。除了远程跟踪信息之外,我们没有任何其他内容作为您希望看到的能作为参考资料的启发式信息。有可能导致破坏。

如果您的编辑器或其他系统在后台运行git fetch,那么缓解这种情况的方法就是简单地设置另一个远程:

代码语言:javascript复制
git remote add origin-push $(git config remote.origin.url)
git fetch origin-push

现在,当后台进程运行git fetch origin时,origin-push上的引用将不会更新,因此命令如下:

代码语言:javascript复制
git push --force-with-lease origin-push

除非您手动运行git fetch origin-push,否则将失败。这种方法当然完全会被运行git fetch --all的东西所击败,在这种情况下你需要禁用它或做一些更乏味的事情,如:

代码语言:javascript复制
git fetch              # update 'master' from remote
git tag base master    # mark our base point
git rebase -i master   # rewrite some commits
git push --force-with-lease=master:base master:master

即为您已经看到并愿意覆盖的上游代码版本创建base标记,然后重写历史记录,如果远程版本仍在base,最后强制推送更改为master,无论是什么,您的本地remotes/origin/master已在后台更新。

代码语言:javascript复制
 -f 
代码语言:javascript复制
 --force 

通常,该命令拒绝更新远程 ref,该远程 ref 不是用于覆盖它的本地 ref 的祖先。此外,当使用--force-with-lease选项时,该命令拒绝更新当前值与预期值不匹配的远程 ref。

此标志禁用这些检查,并可能导致远程存储库丢失提交;小心使用它。

请注意,--force适用于所有被推送的引用,因此在push.default设置为matching或使用remote.*.push配置的多个推送目标时使用它可能会覆盖当前分支以外的引用(包括本地引用)严格落后于他们的远程对手)。要强制推送到一个分支,请使用 refspec 前面的 进行推送(例如git push origin master强制推送到master分支)。有关详细信息,请参阅上面的&lt;refspec&gt;...部分。

代码语言:javascript复制
 --repo=<repository> 

此选项等同于< repository>论点。如果同时指定了两者,则命令行参数优先。

代码语言:javascript复制
 -u 
代码语言:javascript复制
 --set-upstream 

对于每个最新或成功推送的分支,添加上游(跟踪)引用,由无参数 git-pull [1] 和其他命令使用。有关更多信息,请参阅 git-config [1] 中的branch.&lt;name&gt;.merge

代码语言:javascript复制
 --[no-]thin 

这些选项传递给 git-send-pack [1] 。当发送方和接收方共享许多相同的对象时,精简传输会显着减少发送的数据量。默认值为--thin

代码语言:javascript复制
 -q 
代码语言:javascript复制
 --quiet 

除非发生错误,否则禁止所有输出,包括更新的 ref 列表。未向标准错误流报告进度。

代码语言:javascript复制
 -v 
代码语言:javascript复制
 --verbose 

详细地运行。

代码语言:javascript复制
 --progress 

除非-q 已被指定,否则在将标准错误流附加到终端时,默认情况下会报告进度状态。即使标准错误流未定向到终端,此标志也会强制进度状态。

代码语言:javascript复制
 --no-recurse-submodules 
代码语言:javascript复制
 --recurse-submodules=check|on-demand|only|no 

可用于确保要推送的修订使用的所有子模块提交在远程跟踪分支上可用。如果使用 _ 检查 _,Git 将验证在子模块的至少一个远程处可用的所有要推送的修订中更改的子模块提交。如果缺少任何提交,则将中止推送并以非零状态退出。如果使用 _ 按需 _,则将推送在要推送的修订中更改的所有子模块。如果按需无法推送所有必要的修订,它也将被中止并退出非零状态。如果仅使用,则在超级项目未被按下时递归推送所有子模块。当不需要子模块递归时, no--no-recurse-submodules的值可用于覆盖 push.recurseSubmodules 配置变量。

代码语言:javascript复制
 --[no-]verify 

切换预推钩(参见 githooks [5] )。默认值为–verify,使钩子有机会阻止推送。使用–no-verify,挂钩完全被绕过。

代码语言:javascript复制
 -4 
代码语言:javascript复制
 --ipv4 

仅使用 IPv4 地址,忽略 IPv6 地址。

代码语言:javascript复制
 -6 
代码语言:javascript复制
 --ipv6 

仅使用 IPv6 地址,忽略 IPv4 地址。

GIT 网址

通常,URL 包含有关传输协议,远程服务器的地址以及存储库路径的信息。根据传输协议,可能缺少某些信息。

Git 支持 ssh,git,http 和 https 协议(此外,ftp 和 ftps 可用于获取,但这是低效的并且已弃用;请勿使用它)。

本机传输(即 git:// URL)不进行身份验证,在不安全的网络上应当谨慎使用。

可以使用以下语法:

  • SSH:// [用户@] host.xz [:端口] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /path/to/repo.git/
  • HTTP [S]://host.xz [:端口] /path/to/repo.git/
  • FTP [S]://host.xz [:端口] /path/to/repo.git/

另一种类似 scp 的语法也可以与 ssh 协议一起使用:

  • [用户@] host.xz:路径/到/ repo.git /

只有在第一个冒号之前没有斜杠时才会识别此语法。这有助于区分包含冒号的本地路径。例如,本地路径foo:bar可以指定为绝对路径或./foo:bar,以避免被误解为 ssh url。

ssh 和 git 协议还支持〜用户名扩展:

  • SSH:// [用户@] host.xz [:端口] /〜[用户] /path/to/repo.git/
  • GIT 中://host.xz [:端口] /〜[用户] /path/to/repo.git/
  • [用户@] host.xz:/〜[用户] /path/to/repo.git/

对于本地也受 Git 支持的本地存储库,可以使用以下语法:

  • /path/to/repo.git/
  • 文件:///path/to/repo.git/

这两种语法大多是等价的,除了克隆时,前者暗示–local 选项。有关详细信息,请参阅 git-clone [1] 。

当 Git 不知道如何处理某种传输协议时,它会尝试使用 remote-< transport> 远程助手,如果存在的话。要显式请求远程帮助程序,可以使用以下语法:

  • <运输> ::<地址>

其中<地址>可以是路径,服务器和路径,或者由被调用的特定远程助手识别的任意类似 URL 的字符串。有关详细信息,请参阅 gitremote-helpers [1] 。

如果存在大量具有相似名称的远程存储库,并且您希望为它们使用不同的格式(以便将您使用的 URL 重写为有效的 URL),则可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		insteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

像“work:repo.git”这样的 URL 或类似“host.xz:/path/to/repo.git”的 URL 将在任何带有 URL 的上下文中被重写为“git://git.host.xz/repo” git 的”。

如果要为仅推送重写 URL,可以创建表单的配置部分:

代码语言:javascript复制
	[url "<actual url base>"]
		pushInsteadOf = <other url base>

例如,有了这个:

代码语言:javascript复制
	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”这样的网址将被重写为“ssh://example.org/path/to/repo.git”以进行推送,但是 pull 仍会使用原始网址。

遥控

可以使用以下某个名称而不是 URL 作为&lt;repository&gt;参数:

  • Git 配置文件中的一个遥控器:$GIT_DIR/config
  • $GIT_DIR/remotes目录中的文件,或
  • $GIT_DIR/branches目录中的文件。

所有这些也允许你从命令行省略 refspec,因为它们每个都包含一个 git 将默认使用的 refspec。

在配置文件中命名为 remote

您可以选择使用 git-remote [1] , git-config [1] 提供之前配置的遥控器的名称,甚至可以手动编辑$GIT_DIR/config文件。此远程的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则默认情况下将使用此远程的 refspec。配置文件中的条目如下所示:

代码语言:javascript复制
	[remote "<name>"]
		url = <url>
		pushurl = <pushurl>
		push = <refspec>
		fetch = <refspec>

&lt;pushurl&gt;仅用于推送。它是可选的,默认为&lt;url&gt;

$GIT_DIR/remotes中的命名文件

您可以选择在$GIT_DIR/remotes中提供文件名。此文件中的 URL 将用于访问存储库。如果未在命令行上提供 refspec,则此文件中的 refspec 将用作默认值。该文件应具有以下格式:

代码语言:javascript复制
	URL: one of the above URL format
	Push: <refspec>
	Pull: <refspec>

git push 使用Push:行, git pullgit fetch 使用Pull:系。可以为其他分支映射指定多个Push:Pull:行。

$GIT_DIR/branches中的命名文件

您可以选择在$GIT_DIR/branches中提供文件名。此文件中的 URL 将用于访问存储库。该文件应具有以下格式:

代码语言:javascript复制
	<url>#<head>

&lt;url&gt;是必需的; #&lt;head&gt;是可选的。

根据操作,如果您没有在命令行上提供一个 refitpec,git 将使用以下 refspec 之一。 &lt;branch&gt;$GIT_DIR/branches中此文件的名称,&lt;head&gt;默认为master

git fetch 使用:

代码语言:javascript复制
	refs/heads/<head>:refs/heads/<branch>

git push 使用:

代码语言:javascript复制
	HEAD:refs/heads/<head>

OUTPUT

“git push”的输出取决于所使用的传输方法;本节描述了推送 Git 协议时的输出(本地或通过 ssh)。

push 的状态以表格形式输出,每行代表一个 ref 的状态。每一行的形式如下:

代码语言:javascript复制
 <flag> <summary> <from> -> <to> (<reason>)

如果使用了–porcelain,那么输出的每一行都是以下形式:

代码语言:javascript复制
 <flag> t <from>:<to> t <summary> (<reason>)

仅当使用–porcelain 或–verbose 选项时,才会显示最新引用的状态。

代码语言:javascript复制
 flag 

一个表示 ref 状态的字符:

代码语言:javascript复制
 (space) 

为了成功快进推送;

代码语言:javascript复制
   

成功的强制更新;

代码语言:javascript复制
 - 

成功删除参考;

代码语言:javascript复制
 * 

成功推出新的参考;

代码语言:javascript复制
 ! 

对于拒绝或未能推送的裁判;和

代码语言:javascript复制
 = 

对于一个最新的 ref 并且不需要推送的 ref。

代码语言:javascript复制
 summary 

对于成功推送的 ref,摘要以适合用作git log的参数的形式显示 ref 的旧值和新值(在大多数情况下这是&lt;old&gt;..&lt;new&gt;,而强制非快速的&lt;old&gt;...&lt;new&gt; - 转发更新)。

对于失败的更新,提供了更多详细信息:

代码语言:javascript复制
 rejected 

Git 根本没有尝试发送引用,通常是因为它不是快进而你没有强制更新。

代码语言:javascript复制
 remote rejected 

远程端拒绝更新。通常由远程端的挂钩引起,或者因为远程存储库具有以下安全选项之一:receive.denyCurrentBranch(用于推送到已检出的分支),receive.denyNonFastForwards(用于强制非快进更新) ),receive.denyDeletesreceive.denyDeleteCurrent。见 git-config [1] 。

代码语言:javascript复制
 remote failure 

远程端没有报告 ref 的成功更新,可能是因为远程端的临时错误,网络连接中断或其他瞬态错误。

代码语言:javascript复制
 from 

被推送的本地引用的名称减去其refs/&lt;type&gt;/前缀。在删除的情况下,省略本地引用的名称。

代码语言:javascript复制
 to 

要更新的远程引用的名称减去其refs/&lt;type&gt;/前缀。

代码语言:javascript复制
 reason 

一个人类可读的解释。在成功推送 refs 的情况下,不需要解释。对于失败的 ref,描述了失败的原因。

关于快速前进的说明

当更新更改一个分支(或更多,一般来说,一个 ref),它曾经指向提交 A,当指向另一个提交 B 时,当且仅当 B 是 A 的后代时,它才被称为快进更新。

在从 A 到 B 的快速更新中,原始提交 A 构建在其上的提交集是新提交 B 构建在其上的提交的子集。因此,它不会失去任何历史。

相反,非快进更新将丢失历史记录。例如,假设您和其他人在同一个提交 X 中启动,并且您构建了一个导致提交 B 的历史记录,而另一个人构建了一个导致提交 A 的历史记录。历史记录如下所示:

代码语言:javascript复制
      B
     /
 ---X---A

进一步假设另一个人已经将更改导致 A 返回到原始存储库,您从中获得了原始提交 X.

由另一个人完成的推送更新了用于指向提交 X 的分支以指向提交 A.这是一个快进。

但是如果你试图推送,你将尝试用提交 B 更新分支(现在指向 A)。这样做 _ 而不是 _ 快进。如果你这样做,提交 A 引入的更改将会丢失,因为每个人现在都将开始在 B 之上构建。

默认情况下,该命令不允许更新不是快进以防止此类历史记录丢失。

如果您不想丢失您的工作(从 X 到 B 的历史记录)或其他人的工作(从 X 到 A 的历史记录),您需要先从存储库中获取历史记录,创建包含已完成更改的历史记录由双方共同推动结果。

你可以执行“git pull”,解决潜在的冲突,并“git push”结果。 “git pull”将在提交 A 和 B 之间创建合并提交 C.

代码语言:javascript复制
      B---C
     /   /
 ---X---A

使用生成的合并提交更新 A 将快进并且您的推送将被接受。

或者,您可以使用“git pull --rebase”在 A 之上重新定义 X 和 B 之间的更改,然后将结果推回。 rebase 将创建一个新的提交 D,它在 A 之上构建 X 和 B 之间的变化。

代码语言:javascript复制
      B   D
     /   /
 ---X---A

同样,使用此提交更新 A 将快进并且您的推送将被接受。

还有一种常见的情况是,当您尝试推送时,您可能会遇到非快进拒绝,甚至当您进入存储库时,也有可能没有其他人推进。在你自己推送提交 A 之后(在本节的第一张图片中),将其替换为“git commit --amend”以生成提交 B,并尝试将其推出,因为忘记已经将 A 推出了。在这种情况下,并且只有当您确定没有人同时获取您之前的提交 A(并开始在其上构建)时,您可以运行“git push --force”来覆盖它。换句话说,“git push --force”是一种保留用于表示失去历史记录的情况的方法。

例子

代码语言:javascript复制
 git push 

git push &lt;remote&gt;一样工作,其中< remote>是当前分支的远程(或origin,如果没有为当前分支配置远程)。

代码语言:javascript复制
 git push origin 

如果没有其他配置,则将当前分支推送到已配置的上游(remote.origin.merge配置变量),如果它与当前分支具有相同的名称,则错误输出而不推送。

没有< refspec>时此命令的默认行为给定可以通过设置遥控器的push选项或push.default配置变量来配置。

例如,要默认仅将当前分支推送到origin,请使用git config remote.origin.push HEAD。任何有效的< refspec> (如下例中的那些)可以配置为git push origin的默认值。

代码语言:javascript复制
 git push origin : 

将“匹配”分支推送到origin。见< refspec>在上面的 OPTIONS 部分中,对“匹配”分支进行了描述。

代码语言:javascript复制
 git push origin master 

找到与源存储库中的master匹配的引用(很可能,它会找到refs/heads/master),并用它更新origin存储库中的相同引用(例如refs/heads/master)。如果远程不存在master,则会创建它。

代码语言:javascript复制
 git push origin HEAD 

一种将当前分支推送到远程同名的便捷方法。

代码语言:javascript复制
 git push mothership master:satellite/master dev:satellite/dev 

使用与master匹配的源 ref(例如refs/heads/master)来更新mothership存储库中与satellite/master(最可能是refs/remotes/satellite/master)匹配的 ref;为devsatellite/dev做同样的事情。

有关匹配语义的讨论,请参阅上面描述&lt;refspec&gt;...的部分。

这是为了模拟在mothership上运行的git fetch在相反方向上运行git push,以便集成在satellite上完成的工作,当你只能以一种方式进行连接时,通常需要这样做(即卫星可以进入母舰,但母舰无法启动与卫星的连接,因为后者位于防火墙后面或不运行 sshd)。

satellite机器上运行git push后,您将进入mothership并在那里运行git merge以完成在mothership上运行的git pull的仿真,以提取在satellite上进行的更改。

代码语言:javascript复制
 git push origin HEAD:master 

将当前分支推送到origin存储库中与master匹配的远程 ref。此表单便于在不考虑其本地名称的情况下推送当前分支。

代码语言:javascript复制
 git push origin master:refs/heads/experimental 

通过复制当前master分支在origin存储库中创建分支experimental。仅当本地名称和远程名称不同时,才需要此表单在远程存储库中创建新分支或标记;否则,引用名称本身就可以使用。

代码语言:javascript复制
 git push origin :experimental 

找到与origin存储库中的experimental匹配的引用(例如refs/heads/experimental),并将其删除。

代码语言:javascript复制
 git push origin  dev:master 

使用 dev 分支更新原始存储库的主分支,允许非快进更新。 这可以在原始存储库中悬挂未引用的提交。 考虑以下情况:无法进行快进:

代码语言:javascript复制
	    o---o---o---A---B  origin/master
		     
		      X---Y---Z  dev

上面的命令会将原始存储库更改为

代码语言:javascript复制
		      A---B  (unnamed branch)
		     /
	    o---o---o---X---Y---Z  master

提交 A 和 B 将不再属于具有符号名称的分支,因此将无法访问。因此,这些提交将通过源存储库上的git gc命令删除。

安全

提取和推送协议的目的不是为了防止一方窃取不打算共享的其他存储库中的数据。如果您需要保护私有数据免受恶意对等方的攻击,那么最佳选择是将其存储在另一个存储库中。这适用于客户端和服务器。特别是,服务器上的命名空间对读访问控制无效;您应该只将命名空间的读访问权授予您信任的客户端,并具有对整个存储库的读访问权限。

已知的攻击向量如下:

  1. 受害者发送“have”行,宣传其拥有的对象的 ID,这些对象并未明确地用于共享,但如果对等方也拥有它们,则可用于优化转移。攻击者选择一个对象 ID X 来窃取并向 X 发送一个 ref,但不需要发送 X 的内容,因为受害者已经拥有它。现在,受害者认为攻击者拥有 X,并且稍后会将 X 的内容发送回攻击者。 (这种攻击对于客户端在服务器上执行是最直接的,通过在客户端有权访问的命名空间中创建 ref,然后获取它。服务器在客户端上执行它的最可能方式是“将“X”合并到一个公共分支中,并希望用户在此分支上执行其他工作,并将其推送回服务器,而不会注意到合并。)
  2. 与#1 一样,攻击者选择一个对象 ID X 来窃取。受害者发送攻击者已经拥有的对象 Y,并且攻击者错误地声称拥有 X 而不是 Y,因此受害者将 Y 作为针对 X 的增量发送。该增量显示 X 的区域与攻击者的 Y 类似。

GIT

部分 git [1] 套件

0 人点赞