Git 中文参考(四)(5)https://developer.aliyun.com/article/1565833
当你正在寻找一个确切的代码块(比如一个结构体)时,它很有用,并且想要知道该块首次出现以来的历史:迭代地使用该特征将原始图像中的有趣块反馈回-S
,继续前进,直到你获得该块的第一个版本。
也搜索二进制文件。
-G<regex>
查找补丁文本包含与< regex>匹配的添加/删除行的差异。
为了说明-S --pickaxe-regex
和-G
之间的区别,请考虑在同一文件中使用以下 diff 进行提交:
+ return !regexec(regexp, two->ptr, 1, ®match, 0); ... - hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
虽然git log -G"regexec\(regexp"
将显示此提交,但git log -S"regexec\(regexp" --pickaxe-regex
不会(因为该字符串的出现次数没有改变)。
除非提供--text
,否则将忽略没有 textconv 过滤器的二进制文件的补丁。
有关详细信息,请参阅 gitdiffcore [7] 中的 pickaxe 条目。
--find-object=<object-id>
查找更改指定对象出现次数的差异。与-S
类似,只是参数的不同之处在于它不搜索特定的字符串,而是搜索特定的对象 id。
该对象可以是 blob 或子模块提交。它意味着git-log
中的-t
选项也可以找到树。
--pickaxe-all
当-S
或-G
找到更改时,显示该更改集中的所有更改,而不仅仅是包含< string>中更改的文件。
--pickaxe-regex
对待< string>赋予-S
作为扩展的 POSIX 正则表达式以匹配。
-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
”。
-R
交换两个输入;也就是说,显示从索引或磁盘文件到树内容的差异。
--relative[=<path>]
从项目的子目录运行时,可以告诉它排除目录外的更改并使用此选项显示相对于它的路径名。当您不在子目录中时(例如,在裸存储库中),您可以通过给出< path>来命名哪个子目录以使输出相对。作为一个论点。
-a
--text
将所有文件视为文本。
--ignore-cr-at-eol
进行比较时,忽略行尾的回车。
--ignore-space-at-eol
忽略 EOL 中的空白更改。
-b
--ignore-space-change
忽略空格量的变化。这会忽略行尾的空格,并将一个或多个空白字符的所有其他序列视为等效。
-w
--ignore-all-space
比较线条时忽略空格。即使一行有空格而另一行没有空格,这也会忽略差异。
--ignore-blank-lines
忽略其行全部为空的更改。
--inter-hunk-context=<lines>
显示差异之间的上下文,直到指定的行数,从而融合彼此接近的帅哥。如果未设置配置选项,则默认为diff.interHunkContext
或 0。
-W
--function-context
显示整个周围的变化功能。
--ext-diff
允许执行外部 diff 助手。如果使用 gitattributes [5] 设置外部差异驱动程序,则需要将此选项与 git-log [1] 和朋友一起使用。
--no-ext-diff
禁止外部差异驱动程序。
--textconv
--no-textconv
在比较二进制文件时允许(或禁止)外部文本转换过滤器运行。有关详细信息,请参阅 gitattributes [5] 。由于 textconv 过滤器通常是单向转换,因此生成的差异适合人类使用,但无法应用。因此,默认情况下,textconv 过滤器仅针对 git-diff [1] 和 git-log [1] 启用,但不适用于 git-format-patch [ 1] 或差异管道命令。
--ignore-submodules[=<when>]
忽略差异生成中子模块的更改。 <当>可以是“none”,“untracked”,“dirty”或“all”,这是默认值。使用“none”时,如果子模块包含未跟踪或修改的文件,或者其 HEAD 与超级项目中记录的提交不同,则可以使用“无”来修改子模块,并可用于覆盖中 ignore 选项的任何设置 git-config [1] 或 gitmodules [5] 。当使用“未跟踪”时,如果子模块仅包含未跟踪的内容(但仍会扫描修改的内容),则子模块不会被视为脏。使用“脏”忽略对子模块工作树的所有更改,仅显示存储在超级项目中的提交的更改(这是 1.7.0 之前的行为)。使用“all”隐藏子模块的所有更改。
--src-prefix=<prefix>
显示给定的源前缀而不是“a /”。
--dst-prefix=<prefix>
显示给定的目标前缀而不是“b /”。
--no-prefix
不显示任何源或目标前缀。
--line-prefix=<prefix>
为每行输出预先附加前缀。
--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_DIFF
和GIT_DIFF_OPTS
环境变量自定义此类修补程序的创建。
-p 选项产生的内容与传统的 diff 格式略有不同:
- 它前面有一个“git diff”标题,如下所示:
diff --git a/file1 b/file2
- 除非涉及重命名/复制,否则
a/
和b/
文件名是相同的。特别是,即使是创建或删除,/dev/null
也是 _ 而不是 _ 来代替a/
或b/
文件名。
当涉及重命名/复制时,file1
和file2
分别显示重命名/复制的源文件的名称和重命名/复制的文件的名称。 - 它后跟一个或多个扩展标题行:
old mode <mode> new mode <mode> deleted file mode <mode> new file mode <mode> copy from <path> copy to <path> rename from <path> rename to <path> similarity index <number> dissimilarity index <number> index <hash>..<hash> <mode>
- 文件模式打印为 6 位八进制数,包括文件类型和文件权限位。
扩展标头中的路径名不包括a/
和b/
前缀。
相似性指数是未更改行的百分比,相异性指数是更改行的百分比。它是一个向下舍入的整数,后跟一个百分号。因此,100%的相似性索引值保留用于两个相等的文件,而 100%的相异性意味着旧文件中的任何行都不会成为新文件。
索引行包括更改前后的 SHA-1 校验和。 <模式>如果文件模式没有改变,则包括在内;否则,单独的行表示旧模式和新模式。 - 具有“异常”字符的路径名被引用,如配置变量
core.quotePath
所述(参见 git-config [1] )。 - 输出中的所有
file1
文件在提交之前引用文件,并且所有file2
文件在提交之后引用文件。将每个更改顺序应用于每个文件是不正确的。例如,此补丁将交换 a 和 b:
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_ 格式如下所示:
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
选项时):
diff --combined file
- 或者像这样(当使用
--cc
选项时):
diff --cc file
- 它后跟一个或多个扩展标题行(此示例显示了与两个父项的合并):
index <hash>,<hash>..<hash> mode <mode>,<mode>..<mode> new file mode <mode> deleted file mode <mode>,<mode>
- 只有当< mode>中的至少一个出现时,
mode ,..
行才会出现。与其他人不同。具有关于检测到的内容移动(重命名和复制检测)的信息的扩展标题被设计为与两个< tree-ish>的差异一起工作。并且不会被组合 diff 格式使用。 - 接下来是两行的文件/文件头
--- a/file +++ b/file
- 与传统 _ 统一 _ diff 格式的双行标题类似,
/dev/null
用于表示创建或删除的文件。 - 修改了块头格式以防止人们意外地将其馈送到
patch -p1
。创建组合差异格式用于审查合并提交更改,并不适用于应用。此更改类似于扩展 _ 索引 _ 标头中的更改:
@@@ <from-file-range> <from-file-range> <to-file-range> @@@
- 组合 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 又名“他们的版本”)。
例子
git log --no-merges
显示整个提交历史记录,但跳过任何合并
git log v2.6.12.. include/scsi drivers/scsi
显示自版本 v2.6.12 以来更改include/scsi
或drivers/scsi
子目录中的任何文件的所有提交
git log --since="2 weeks ago" -- gitk
在过去两周内将更改显示到文件 gitk 。 --
是必要的,以避免与名为 gitk 的分支混淆
git log --name-status release..test
显示“test”分支中但尚未在“release”分支中的提交,以及每个提交修改的路径列表。
git log --follow builtin/rev-list.c
显示更改builtin/rev-list.c
的提交,包括在文件被赋予其当前名称之前发生的提交。
git log --branches --not --remotes=origin
显示任何本地分支中的所有提交,但不显示 _ 原点 _ 的任何远程跟踪分支中的所有提交(您的原点没有)。
git log master --not --remotes=*/master
显示本地主服务器中但不在任何远程存储库主分支中的所有提交。
git log -p -m --first-parent
显示包含更改差异的历史记录,但仅显示“主分支”透视图,跳过来自合并分支的提交,并显示合并引入的完整更改差异。只有遵循严格的策略,在停留在单个集成分支上时合并所有主题分支才有意义。
git log -L '/int main/',/^}/:main.c
显示文件main.c
中的函数main()
如何随时间演变。
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 commit 和 git commit-tree 发出警告,如果提供给它的提交日志消息看起来不像有效的 UTF-8 字符串,除非你明确说你的项目使用了遗产编码。说这个的方法是在
.git/config
文件中使用 i18n.commitencoding,如下所示:
[i18n] commitEncoding = ISO-8859-1
- 使用上述设置创建的提交对象在其
encoding
标题中记录i18n.commitEncoding
的值。这是为了帮助其他人以后再看。缺少此标头意味着提交日志消息以 UTF-8 编码。 - git log , git show , git blame 和朋友们查看提交对象的
encoding
头,并尝试将日志消息重新编码为除非另有说明,否则为 UTF-8。您可以使用.git/config
文件中的i18n.logOutputEncoding
指定所需的输出编码,如下所示:
[i18n] logOutputEncoding = ISO-8859-1
- 如果您没有此配置变量,则使用
i18n.commitEncoding
的值。
请注意,我们故意选择在提交以在提交对象级别强制使用 UTF-8 时不重新编写提交日志消息,因为重新编码为 UTF-8 不一定是可逆操作。
组态
对于核心变量,请参见 git-config [1] ,对于差异生成,请参见 git-diff [1] 。
format.pretty
--format
选项的默认值。 (参见上面的 _ 漂亮格式 _。)默认为medium
。
i18n.logOutputEncoding
显示日志时使用的编码。 (参见上面的 _ 讨论 _。)如果设置,则默认为i18n.commitEncoding
的值,否则为 UTF-8。
log.date
人类可读日期的默认格式。 (比较--date
选项。)默认为“默认”,表示写入Sat May 8 19:35:34 2010 -0500
等日期。
如果格式设置为“auto:foo”并且正在使用寻呼机,则格式“foo”将用于日期格式。否则将使用“默认”。
log.follow
如果true
,git log
将像单个<路径>一样使用--follow
选项。给出。这与--follow
具有相同的限制,即它不能用于跟踪多个文件,并且在非线性历史记录上不能很好地工作。
log.showRoot
如果false
,git log
和相关命令不会将初始提交视为大创建事件。 git log -p
输出中的任何根提交都将显示没有附加差异。默认值为true
。
log.showSignature
如果true
,git log
和相关命令的作用就像传递了--show-signature
选项一样。
mailmap.*
见 git-shortlog [1] 。
notes.displayRef
除了core.notesRef
或GIT_NOTES_REF
设置的默认值之外,还使用log
系列命令显示提交消息时的注释。见 git-notes [1] 。
可以是未缩写的引用名称或 glob,可以多次指定。将为不存在的引用发出警告,但是会自动忽略与任何引用不匹配的 glob。
可以通过--no-notes
选项禁用此设置,由GIT_NOTES_DISPLAY_REF
环境变量覆盖,并由--notes=
选项覆盖。
GIT
部分 git [1] 套件
git-shortlog
名称
git-shortlog - 汇总 git log 输出
概要
git shortlog [<options>] [<revision range>] [[--] <path>…] git log --pretty=short | git shortlog [<options>]
描述
以适合包含在发布公告中的格式汇总 git log 输出。每个提交将按作者和标题分组。
此外,“[PATCH]”将从提交说明中删除。
如果命令行上没有传递任何修订,并且标准输入不是终端或者没有当前分支, git shortlog 将输出从标准输入读取的日志摘要,而不引用当前存储库。
OPTIONS
-n
--numbered
根据每位作者的提交次数而不是作者字母顺序对输出进行排序。
-s
--summary
禁止提交描述并仅提供提交计数摘要。
-e
--email
显示每位作者的电子邮件地址。
--format[=<format>]
而不是提交主题,使用一些其他信息来描述每个提交。 < format> 可以是 git log 的--format
选项接受的任何字符串,例如 * [%h]%s 。 (参见 git-log [1] 的“PRETTY FORMATS”部分。)
Each pretty-printed commit will be rewrapped before it is shown.
-c
--committer
收集并显示提交者身份而不是作者。
-w[<width>[,<indent1>[,<indent2>]]]
通过在width
处包裹每一行来包装输出。每个条目的第一行由indent1
空格缩进,第二行和后续行由indent2
空格缩进。 width
,indent1
和indent2
分别默认为 76,6 和 9。
如果 width 是0
(零),则缩进输出行而不包装它们。
<revision range>
仅显示指定修订范围内的提交。当没有<修订范围>如果指定,则默认为HEAD
(即导致当前提交的整个历史记录)。 origin..HEAD
指定从当前提交可以访问的所有提交(即HEAD
),但不是origin
。有关拼写< revision range>的完整列表,请参阅 gitrevisions [7] 的“指定范围”部分。
[--] <path>…
只考虑足以解释与指定路径匹配的文件的提交。
当出现混淆时,路径可能需要以--
作为前缀,以将它们与选项或修订范围分开。
Git 中文参考(四)(7)https://developer.aliyun.com/article/1565835