Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.43.0 11/20/23
- 2.42.1 11/02/23
- 2.42.0 08/21/23
- 2.41.0 06/01/23
- 2.40.1 no changes
- 2.40.0 03/12/23
- 2.39.1 → 2.39.3 no changes
- 2.39.0 12/12/22
- 2.37.3 → 2.38.5 no changes
- 2.37.2 08/11/22
- 2.36.1 → 2.37.1 no changes
- 2.36.0 04/18/22
- 2.35.1 → 2.35.8 no changes
- 2.35.0 01/24/22
- 2.34.1 → 2.34.8 no changes
- 2.34.0 11/15/21
- 2.33.1 → 2.33.8 no changes
- 2.33.0 08/16/21
- 2.32.1 → 2.32.7 no changes
- 2.32.0 06/06/21
- 2.31.1 → 2.31.8 no changes
- 2.31.0 03/15/21
- 2.30.1 → 2.30.9 no changes
- 2.30.0 12/27/20
- 2.29.1 → 2.29.3 no changes
- 2.29.0 10/19/20
- 2.28.1 no changes
- 2.28.0 07/27/20
原始输出格式
"git-diff-index","git-diff-tree","git-diff-files" 和 "git diff --raw" 的原始输出格式非常相似。
这些命令都比较两组事物。但比较的内容有所不同:
"git-diff-tree" 命令在最开始输出被比较对象的哈希值。之后,所有命令都会为每个更改的文件打印一个输出行。
输出行的格式如下:
in-place edit :100644 100644 bcd1234 0123456 M file0 copy-edit :100644 100644 abcd123 1234567 C68 file1 file2 rename-edit :100644 100644 abcd123 1234567 R86 file1 file3 create :000000 100644 0000000 1234567 A file4 delete :100644 000000 1234567 0000000 D file5 unmerged :000000 000000 0000000 0000000 U file6
含义如下,从左到右依次:
-
a colon.
-
"src"(源文件)的模式;如果是新建或是未合并的,则为 000000。
-
空格。
-
"dst"(目标文件)的模式;如果被删除或未合并则为 000000。
-
空格。
-
"src"(源文件)的 sha1 值;如果为新建或未合并则为 0{40}。
-
空格。
-
sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
-
空格。
-
状态,在可选值 "score" 之后。
-
当使用
-z
选项时为制表符或 NUL。 -
"src" 的路径
-
使用
-z
选项时为制表符或 NUL;仅当状态为 C 或 R 时存在。 -
"dst" 的路径;仅当状态为 C 或 R 时存在。
-
当使用
-z
选项时为 LF 或 NUL,用于终止记录。
可能的状态字母为:
-
A:文件新增部分
-
C:复制到一个新文件
-
D:文件删除部分
-
M:文件内容或文件模式修改
-
R:文件重命名
-
T:文件类型改变
-
U:文件未合并(你必须在提交之前完成合并)
-
X:"unknown"(未知)更改类型(可能为错误,请报告)
状态字母 C 和 R 后面总是一个分数(表示移动或复制的源与目标之间的相似性百分比)。状态字母M后面可能有文件重写的分数(表示相异百分比)。
如果文件是文件系统上的新文件,并且与索引不同步,则 <sha1> 将显示为全0。
例如:
:100644 100644 5be4a4a 0000000 M file.c
Without the -z
option, pathnames with "unusual" characters are quoted as
explained for the configuration variable core.quotePath
(see
git-config[1]). Using -z
the filename is output verbatim and the
line is terminated by a NUL byte.
合并的差异格式
"git-diff-tree"、"git-diff-files" 和 "git-diff --raw" 可以使用 -c
或 --cc
选项来生成差异输出,也可以用于合并提交。其输出与上面描述的格式有以下不同:
-
每个父提交都有一个冒号
-
there are more "src" modes and "src" sha1
-
状态是每个父提交的状态字符的合并
-
无可选的分数("score")数字
-
以制表符分隔的文件路径名
For -c
and --cc
, only the destination or final path is shown even if the
file was renamed on any side of history. With --combined-all-paths
, the
name of the path in each parent is shown followed by the name of the path in
the merge commit.
以下为带 -c
和 --cc
选项且不带 --combined-all-paths
选项的示例:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c ::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM bar.sh ::100644 100644 100644 e07d6c5 9042e82 ee91881 RR phooey.c
以下为使用 --combined-all-paths
选项且使用 -c
或 --cc
选项的示例:
::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c desc.c desc.c ::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM foo.sh bar.sh bar.sh ::100644 100644 100644 e07d6c5 9042e82 ee91881 RR fooey.c fuey.c phooey.c
请注意 combined diff 只列出了从所有父提交中修改过的文件。
使用选项 -p
生成补丁文本
Running git-diff[1], git-log[1], git-show[1], git-diff-index[1], git-diff-tree[1], or git-diff-files[1] with the -p
option produces patch text. You can customize the creation of patch text via the GIT_EXTERNAL_DIFF
and the GIT_DIFF_OPTS
environment variables (see git[1]), and the diff
attribute (see gitattributes[5]).
-p 选项产生的内容与传统的差异格式略有不同:
-
它前面有一个
git diff
头,如下所示:diff --git a/file1 b/file2
a/
和b/
的文件名相同,除非涉及到重命名/复制。特别地,即使是创建或删除,也 不 使用/dev/null
来代替a/
或b/
文件名。当涉及到重命名/复制时,
file1
和file2
分别显示重命名/复制的源文件的名称和重命名/复制产生的文件的名称。 -
它的后面是一个或多个扩展头信息行:
old mode <模式> new mode <模式> deleted file mode <模式> new file mode <模式> copy from <路径> copy to <路径> rename from <路径> rename to <路径> similarity index <数字> dissimilarity index <数字> index <哈希>..<哈希> <模式>
文件模式被打印为6位八进制数字,包括文件类型和文件权限位。
扩展头信息中的路径名称不包括
a/
和b/
前缀。相似性指数是未改变的行占比,而不相似性指数是改变的行占比。它是四舍五入的整数,后有百分号。因此,100%的相似度指数指为两个文件相等,而 100% 的不相似度意味着入新文件中没有旧文件中的行。
索引行包括改变前和改变后的 blob 对象名称。如果文件模式没有变化,则包含 <模式>;否则,分别显示新旧模式。
-
含有 "不常见" 字符的路径名会被引用,这一点在配置变量` 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
-
块头提到了块头所适用的函数的名称。 参见 gitattributes[5] 中的 "定义自定义 hunk-header",以了解如何针对特定语言进行定制。
合并的差异格式
任何生成差异的命令都可以使用 -c
或 -cc
选项,在显示合并时产生一个 "合并差异"。当用 git-diff[1] 或 git-show[1] 显示合并时,这默认格式。还需要注意的是,你可以给这些命令适当的 --diff-merges
选项来强制生成特定格式的差异。
"合并的差异" 的格式如下:
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 <哈希>,<哈希>..<哈希> mode <模式>,<模式>..<模式> new file mode <模式> deleted file mode <模式>,<模式>
The
mode <mode>,<mode>..<mode>
line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected contents movement (renames and copying detection) are designed to work with diff of two <tree-ish> and are not used by combined diff format. -
它的后面是两行源文件/目标文件的头信息
--- a/file +++ b/file
类似于传统的 "统一" 差异格式的双行头,
/dev/null
用来表示创建或删除的文件。但是,如果提供了 --combined-all-paths 选项,你就会得到一个 N+1 行的源文件/目标文件头,其中 N 是合并提交中的父提交数量
--- a/file --- a/file --- a/file +++ b/file
如果重命名或复制检测处于活动状态,这种扩展格式可能很有用,可以让你在不同的父提交中看到文件的原始名称。
-
修改了文件块头信息的格式,以防止不小心将其送入
patch -p1
。合并的差异格式是为审查合并提交的修改而创建的,并不是为了应用。这个变化类似于扩展的 "索引" 头信息的变化:@@@ <from-file-range> <from-file-range> <to-file-range> @@@
块中有(父提交数量+1)
@
字符,用于合并的差异格式。
与传统的 "统一" 差异格式不同,这种格式显示两个文件 A 和 B 的列,其中有 -
(减号 — 在 A 中出现,但在 B 中删除),+
(加号 — 在 A 中缺少,但在 B 中增加),或 " "
(空格 — 不变)前缀,这种格式比较两个或多个文件与一个文件 X,并显示 X 与其中每个文件的差异。文件中的每一个都有一列被前置在输出行中,以指出 X 的行与它的不同之处。
第 N 列中的 -
字符意味着该行出现在文件 N 中,但它没有出现在结果文件中。第 N 列中的 +
字符意味着该行出现在结果文件中,而文件 N 中没有该行(换句话说,从该父提交的角度来看,该行是被添加的)。
在上面的输出示例中,两个文件中的函数签名都被改变了(因此从文件 1 和文件 2 中都有表示删除的 -
,而 ++
表示被添加的一行没有出现在文件 1 或文件 2 中)。另外还有 8 行与文件 1 中的相同,但没有出现在文件 2 中(因此前缀为 +
)。
当用 git diff-tree -c
显示时,它将合并提交的父提交文件与合并结果进行比较(即文件 1 … 文件 N 是父提交文件)。当用 git diff-files -c
显示时,它将两个未解决的合并父提交文件与工作树文件进行比较(即文件 1 是阶段 2 ,又称 "我们的版本",文件 2 是阶段 3,又称 "他们的版本")。
其他差异格式
--summary
选项描述新添加、删除、重命名和复制的文件。--stat
选项将 diffstat(1)
图添加到输出中。这些选项可以与其他选项组合在一起,如 -p
选项可以提高可读性。
当显示一个涉及到重命名或复制的更改时,--stat
输出会将路径名的前缀和后缀结合在一起,会以较紧凑的方式显示。例如,将
"arch/i386/Makefile" 移动到 "arch/x86/Makefile",同时修改了4行,就会显示出这样的变化:
arch/{i386 => x86}/Makefile | 4 +--
--numstat
选项提供了 diffstat(1) 的信息,但其是为了方便程序使用而设计的。--numstat
输出中的一个条目如下:
1 2 README 3 1 arch/{i386 => x86}/Makefile
从左至右依次是:
-
添加的行数;
-
制表符;
-
删除的行数;
-
制表符;
-
路径名(可能有重命名/复制信息);
-
换行符。
当 -z
输出选项生效时,输出的格式如下:
1 2 README NUL 3 1 NUL arch/i386/Makefile NUL arch/x86/Makefile NUL
依次是:
-
添加的行数;
-
制表符;
-
删除的行数;
-
制表符;
-
NUL(仅在重命名/复制时存在);
-
完整路径名;
-
NUL(仅在重命名/复制时存在);
-
完整路径名(仅在重命名/复制时存在);
-
NUL。
The extra NUL
before the preimage path in renamed case is to allow scripts
that read the output to tell if the current record being read is a
single-path record or a rename/copy record without reading ahead. After
reading added and deleted lines, reading up to NUL
would yield the
pathname, but if that is NUL
, the record will show two paths.
GIT
属于 git[1] 文档