设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
-
2.52.0
2025-11-17
- 2.51.1 → 2.51.2 无更改
-
2.51.0
2025-08-18
- 2.50.1 无更改
-
2.50.0
2025-06-16
- 2.49.1 无更改
-
2.49.0
2025-03-14
- 2.48.1 → 2.48.2 无更改
-
2.48.0
2025-01-10
- 2.47.1 → 2.47.3 无更改
-
2.47.0
2024-10-06
- 2.46.2 → 2.46.4 无更改
-
2.46.1
2024-09-13
- 2.45.1 → 2.46.0 无变化
-
2.45.0
2024-04-29
- 2.43.2 → 2.44.4 无变化
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.42.2 → 2.42.4 无更改
-
2.42.1
2023-11-02
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 无更改
-
2.41.0
2023-06-01
- 2.39.1 → 2.40.4 无更改
-
2.39.0
2022-12-12
- 2.38.3 → 2.38.5 无更改
-
2.38.2
2022-12-11
- 2.38.1 无更改
-
2.38.0
2022-10-02
- 2.37.1 → 2.37.7 无更改
-
2.37.0
2022-06-27
- 2.36.1 → 2.36.6 无更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 无更改
-
2.35.0
2022-01-24
- 2.33.1 → 2.34.8 无变化
-
2.33.0
2021-08-16
- 2.32.1 → 2.32.7 无变更
-
2.32.0
2021-06-06
- 2.28.1 → 2.31.8 无更改
-
2.28.0
2020-07-27
- 2.27.1 无更改
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 无更改
-
2.25.0
2020-01-13
- 2.22.2 → 2.24.4 无更改
-
2.22.1
2019-08-11
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 无更改
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 无更改
-
2.19.2
2018-11-21
- 2.17.1 → 2.19.1 无更改
-
2.17.0
2018-04-02
- 2.14.6 → 2.16.6 无更改
-
2.13.7
2018-05-22
- 2.12.5 无更改
-
2.11.4
2017-09-22
- 2.10.5 无更改
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.5.6 → 2.7.6 无变更
-
2.4.12
2017-05-05
-
2.3.10
2015-09-28
- 2.2.3 无变更
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
此信息专用于 Git 项目
请注意,如果您打算为 Git 项目本身做贡献,此信息才与您相关。它绝不是普通 Git 用户的必读内容。
与其他项目一样,我们也有一些代码规范。对于 Git 而言,一些粗略的规则是:
-
最重要的是,我们从不说“它在 POSIX 中;如果您的系统不符合,我们将愉快地忽略您的需求。”我们生活在现实世界中。
-
然而,我们经常说:“让我们远离那种构造,它甚至不在 POSIX 中。”
-
尽管有以上两条规则,我们有时也会说:“虽然这不在 POSIX 中,但它(非常方便 | 使代码更具可读性 | 具有其他优点),并且我们关心的所有平台几乎都支持它,所以让我们使用它。”
Again, we live in the real world, and it is sometimes a judgement call, the decision based more on real world constraints people face than what the paper standard says.
-
在处理实际更改时,修复样式违规作为准备性的清理步骤是好的,但除此之外,要避免为了符合样式而进行无用的代码搅动。
"Once it _is_ in the tree, it's not really worth the patch noise to go and fix it up." Cf. https://lore.kernel.org/all/20100126160632.3bdbe172.akpm@linux-foundation.org/
-
解释您更改的日志消息与更改本身一样重要。清晰编写的代码和代码内注释解释了代码如何工作以及从周围上下文中假设了什么。日志消息解释了更改想要达到的目标以及为什么更改是必要的(更多信息请参阅随附的 SubmittingPatches 文档)。
使您的代码可读且明智,不要试图表现得很聪明。
至于更具体的指南,只需模仿现有代码(无论您为哪个项目做出贡献,这都是一个好指南)。始终首选匹配*本地*约定。添加到 Git 套件的新代码应匹配现有代码的整体风格。对现有代码的修改应匹配周围代码已经使用的风格(即使它不匹配现有代码的整体风格)。
但如果您必须有一个规则列表,这里有一些特定于语言的规则。请注意,Documentation/ToolsForGit.adoc 文档包含了一系列技巧,可帮助您使用一些外部工具来遵循这些指南。
特别是对于 shell 脚本(不详尽):
-
我们使用制表符进行缩进。
-
case 分支与 case 和 esac 行具有相同的缩进深度,如下所示:
case "$variable" in pattern1) do this ;; pattern2) do that ;; esac
-
重定向运算符应在它们之前留有空格,但在它们之后不留空格。换句话说,写 *echo test >"$file"* 而不是 *echo test> $file* 或 *echo test > $file*。请注意,即使 POSIX 不要求在变量中双引号重定向目标(如上所示),我们的代码也会这样做,因为某些 bash 版本会在没有引号时发出警告。
(incorrect) cat hello > world < universe echo hello >$world
(correct) cat hello >world <universe echo hello >"$world"
-
我们更喜欢 $( … ) 用于命令替换;与 `` 不同,它能正确嵌套。它本应是 Bourne 从一开始就使用的拼写方式,但可惜不是。
-
如果您想找出用户 $PATH 中是否可用某个命令,应使用 *type <command>*,而不是 *which <command>*。*which* 的输出不可机器解析,且其退出码在不同平台上不可靠。
-
我们使用符合 POSIX 的参数替换,并避免 bashism;即:
-
我们使用 ${parameter-word} 及其 [-=?+] 兄弟,以及它们的带冒号的“未设置或为空”形式。
-
我们使用 ${parameter#word} 及其 [#%] 兄弟,以及它们的双重“最长匹配”形式。
-
无“子字符串扩展” ${parameter:offset:length}。
-
无 shell 数组。
-
无模式替换 ${parameter/pattern/string}。
-
我们使用算术扩展 $…。
-
我们不使用进程替换 <(list) 或 >(list)。
-
不要将控制结构写在同一行并用分号分隔。“then”应在新的一行上用于 if 语句,而“do”应在新的一行上用于“while”和“for”。
(incorrect) if test -f hello; then do this fi
(correct) if test -f hello then do this fi
-
如果一个由 && 或 || 或 | 连接的命令序列跨越多行,将每个命令放在单独的行上,并将 && 和 || 和 | 运算符放在每行的末尾,而不是开头。这意味着您不需要使用 \ 来连接行,因为上述运算符意味着序列尚未完成。
(incorrect) grep blob verify_pack_result \ | awk -f print_1.awk \ | sort >actual && ...
(correct) grep blob verify_pack_result | awk -f print_1.awk | sort >actual && ...
-
我们更喜欢 "test" 而不是 "[ … ]"。
-
我们不在 shell 函数前写多余的“function”关键字。
-
我们更喜欢函数名和括号之间有一个空格,而括号内部没有空格。开头的“{”也应在同一行。
(incorrect) my_function(){ ...(correct) my_function () { ... -
关于 grep 的使用,为了可移植性,请坚持使用 BRE 的子集(即,不使用 \{m,n\}, [::], [==], 或 [..])。
-
我们不使用 \{m,n\};
-
我们不使用 ? 或 +(它们在 BRE 中分别是 \{0,1\} 和 \{1,\}),但这不言而喻,因为这些是 ERE 元素而不是 BRE(请注意,\? 和 \+ 甚至不是 BRE 的一部分 — 使它们可以从 BRE 中访问是 GNU 扩展)。
-
使用 Git 的 gettext 包装器在 git-sh-i18n 中使用户界面可翻译。请参阅 po/README 中的“标记字符串以供翻译”。
-
我们不使用 "-a" 和 "-o" 来编写我们的 "test" 命令,而是使用 "&&" 或 "||" 来连接多个 "test" 命令,因为 "-a/-o" 的使用经常出错。例如:
test -n "$x" -a "$a" = "$b"
is buggy and breaks when $x is "=", but
test -n "$x" && test "$a" = "$b"
does not have such a problem.
-
虽然 "local" 不是 POSIX 的一部分,但我们在测试套件中大量使用它。我们不在脚本化的 Porcelains 中使用它,并希望没有人开始使用 "local" 在所有我们关心的 shell 支持它之前(特别是,来自 AT&T Research 的 ksh 尚不支持它)。
-
某些版本的 shell 不理解 "export variable=value",因此我们将其写为 "variable=value" 然后在两个单独的行上写 "export variable"。
-
某些版本的 dash 在变量赋值前加上 "local"、"export" 和 "readonly" 时存在错误的变量赋值,即要赋值的值会经过字段拆分在 $IFS 上,除非被引用。
(incorrect) local variable=$value local variable=$(command args)
(correct) local variable="$value" local variable="$(command args)"
-
常见的构造
VAR=VAL command args
to temporarily set and export environment variable VAR only while "command args" is running is handy, but this triggers an unspecified behaviour according to POSIX when used for a command that is not an external command (like shell functions). Indeed, dash 0.5.10.2-6 on Ubuntu 20.04, /bin/sh on FreeBSD 13, and AT&T ksh all make a temporary assignment without exporting the variable, in such a case. As it does not work portably across shells, do not use this syntax for shell functions. A common workaround is to do an explicit export in a subshell, like so:
(incorrect) VAR=VAL func args
(correct) ( VAR=VAL && export VAR && func args )
but be careful that the effect "func" makes to the variables in the current shell will be lost across the subshell boundary.
-
在 printf 格式字符串中使用八进制转义序列(例如 "\302\242"),而不是十六进制(例如 "\xc2\xa2"),因为十六进制转义序列不可移植。
对于 C 程序:
-
我们使用制表符进行缩进,并将制表符解释为最多 8 个空格。
-
嵌套的 C 预处理器指令在 # 之后按每个嵌套级别缩进一个空格。
#if FOO # include <foo.h> # if BAR # include <bar.h> # endif #endif
-
我们尽量将每行限制在 80 个字符以内。
-
作为 Git 开发者,我们假设您拥有一个相当现代的编译器,并建议您启用 DEVELOPER makefile 选项,以确保您的补丁清除所有我们关心的编译器警告,例如通过“echo DEVELOPER=1 >>config.mak”。
-
在使用 DEVELOPER=1 模式时,您可能会看到来自编译器的警告,例如“error: unused parameter foo [-Werror=unused-parameter]”,这表明一个函数忽略了它的参数。如果未使用的参数无法删除(例如,因为该函数被用作回调并且必须匹配某个接口),您可以使用 UNUSED(或 MAYBE_UNUSED)关键字来注解单个参数,例如“int foo UNUSED”。
-
我们尽量支持多种 C 编译器来编译 Git,包括旧的编译器。截至 Git v2.35.0,Git 需要 C99(我们检查“STDC_VERSION”)。您不应使用更新的 C 标准中的功能,即使您的编译器支持它们。
New C99 features have been phased in gradually, if something's new in C99 but not used yet don't assume that it's safe to use, some compilers we target have only partial support for it. These are considered safe to use:
-
自 2007 年左右(通过 2b6854c863a)以来,我们一直使用在加载时不可计算的初始化元素。例如:
const char *args[] = { "constant", variable, NULL }; -
自 2012 年初(通过 e1327023ea)以来,我们一直使用一个 enum 定义,其最后一个元素后面有一个逗号。这与以尾部逗号结尾的数组初始化器一样,可用于在添加新标识符时减少补丁噪音。
-
自 2017 年中期(通过 cbc0f81d)以来,我们一直使用结构体的指定初始化器(例如“struct t v = { .val = a };”)。
-
自 2017 年中期(通过 512f41cf)以来,我们一直使用数组的指定初始化器(例如“int array[10] = { [5] = 2 }”)。
-
自 2021 年初(通过 765dc168882)以来,我们一直使用可变参数宏,主要用于类似 printf 的跟踪和调试宏。
-
自 2021 年末(通过 44ba10d6)以来,我们在 for 循环中声明了变量“for (int i = 0; i < 10; i++)”。
-
自 2023 年末(通过 8277dbe987)以来,我们一直在使用来自 <stdbool.h> 的 bool 类型。
C99 features we have test balloons for:
-
自 2024 年末(通过 v2.48.0-rc0~20)以来,我们有用于复合字面量语法的测试气球,例如 (struct foo){ .member = value }; 我们希望我们关心的平台在使用它们时不会遇到问题,并将在 2026 年中期正式采纳其更广泛的使用。在此之前,请勿添加更多使用此语法的示例。
New C99 features that we cannot use yet:
-
%z 和 %zu 作为 size_t 的 printf() 参数(%z 用于 POSIX 特定的 ssize_t)。您应该改用 printf("%"PRIuMAX, (uintmax_t)v)。如今,我们依赖的 MSVC 版本支持 %z,但 MinGW 使用的 C 库不支持。
-
结构体初始化中的简写方式,如 ".a.b = *c",已知会导致旧版 IBM XLC 出现问题,请改用 ".a = { .b = *c }"。请参阅 33665d98(reftable: 使赋值对 AIX xlc v12.01 可移植,2022-03-28)。
-
-
变量必须在块开始处,第一个语句之前声明(即 -Wdeclaration-after-statement)。鼓励在声明结束和块内的第一个语句之间留一个空行。
-
不要显式将全局变量初始化为 0 或 NULL;相反,让 BSS 来处理零初始化。
-
NULL 指针应写为 NULL,而不是 0。
-
声明指针时,星号与变量名对齐,即 "char *string",而不是 "char** string" 或 "char * string"。这使得理解 "char *string, c;" 这样的代码更容易。
-
在运算符和关键字周围使用空格,但在括号内和函数周围不使用。所以:
while (condition) func(bar + 1);
and not:
while( condition ) func (bar+1);
-
二进制运算符(, 除外)和三元条件运算符 "?:" 在运算符两侧各有一个空格,将其与其操作数分开。例如 "A + 1",而不是 "A+1"。
-
一元运算符(. 和 → 除外)在其操作数之间不留空格。例如 "(char *)ptr",而不是 "(char *) ptr"。
-
不要将整数值与常量 0 或 *`\0`*,或指针值与常量 NULL 进行显式比较。例如,要验证计数的数组 <ptr, cnt> 已初始化但没有元素,请这样写:
if (!ptr || cnt) BUG("empty array expected");and not:
if (ptr == NULL || cnt != 0); BUG("empty array expected"); -
我们避免不必要地使用花括号。即:
if (bla) { x = 1; }is frowned upon. But there are a few exceptions:
-
当语句跨越多行时(例如,一个带有嵌入式条件的 while 循环,或一个注释)。例如:
while (foo) { if (x) one(); else two(); }if (foo) { /* * This one requires some explanation, * so we're better off with braces to make * it obvious that the indentation is correct. */ doit(); } -
当条件语句有多个分支,其中一些分支需要花括号时,即使是单行代码块也用花括号括起来以保持一致性。例如:
if (foo) { doit(); } else { one(); two(); three(); } -
我们尽量避免在 "if" 语句的条件中使用赋值。
-
尽量使您的代码易于理解。您可以添加注释,但注释的内容往往会随着其描述的代码的改变而过时。通常将一个函数拆分成两个会使代码的意图更加清晰。
-
多行注释将其分隔符放在与文本分开的行上。例如:
/* * A very long * multi-line comment. */
Note however that a comment that explains a translatable string to translators uses a convention of starting with a magic token "TRANSLATORS: ", e.g.
/* * TRANSLATORS: here is a comment that explains the string to * be translated, that follows immediately after it. */ _("Here is a translatable string explained by the above."); -
双重否定通常比根本没有否定更难理解。
-
关于比较,尤其是在循环内,有两种观点。一些人喜欢将不稳定的值放在左边,稳定的值放在右边,例如,如果您有一个从上到下计数变量 i 的循环,
while (i > lower_bound) { do something; i--; }Other people prefer to have the textual order of values match the actual order of values in their comparison, so that they can mentally draw a number line from left to right and place these values in order, i.e.
while (lower_bound < i) { do something; i--; }Both are valid, and we use both. However, the more "stable" the stable side becomes, the more we tend to prefer the former (comparison with a constant, "i > 0", is an extreme example). Just do not mix styles in the same part of the code and mimic existing styles in the neighbourhood.
-
关于将长逻辑行拆分成多行,有两种观点。一些人将第二行及后续行向右推得足够远,并使用制表符对齐它们。
if (the_beginning_of_a_very_long_expression_that_has_to || span_more_than_a_single_line_of || the_source_text) { ...while other people prefer to align the second and the subsequent lines with the column immediately inside the opening parenthesis, with tabs and spaces, following our "tabstop is always a multiple of 8" convention:
if (the_beginning_of_a_very_long_expression_that_has_to || span_more_than_a_single_line_of || the_source_text) { ...Both are valid, and we use both. Again, just do not mix styles in the same part of the code and mimic existing styles in the neighbourhood.
-
拆分长逻辑行时,有些人会在二进制运算符之前换行,这样当你将头部逆时针旋转 90 度时,结果看起来就像一个解析树。
if (the_beginning_of_a_very_long_expression_that_has_to || span_more_than_a_single_line_of_the_source_text) {while other people prefer to leave the operator at the end of the line:
if (the_beginning_of_a_very_long_expression_that_has_to || span_more_than_a_single_line_of_the_source_text) {Both are valid, but we tend to use the latter more, unless the expression gets fairly complex, in which case the former tends to be easier to read. Again, just do not mix styles in the same part of the code and mimic existing styles in the neighbourhood.
-
拆分长逻辑行时,在其他条件相同的情况下,更倾向于在解析树中级别较高的运算符之后拆分。也就是说,这样做更可取:
if (a_very_long_variable * that_is_used_in + a_very_long_expression) { ...than
if (a_very_long_variable * that_is_used_in + a_very_long_expression) { ... -
一些聪明的技巧,比如对算术构造使用 !! 运算符,可能会让别人非常困惑。除非有令人信服的理由,否则避免使用它们。
-
使用 API。不,真的。我们有 strbuf(可变长度字符串)、几个带有 ALLOC_GROW() 宏的数组、一个用于排序字符串列表的 string_list,一个名为 "struct decorate" 的哈希映射(映射 struct 对象),等等。
-
当您提出一个 API 时,请在将 API 暴露给调用者的头文件中记录其函数和结构。使用 "strbuf.h" 中的内容作为适当的语气和详细程度的模型。
-
C 文件中的第一个 #include(除了平台特定的 compat/ 实现和 sha1dc/ 之外),必须是 <git-compat-util.h>。这个头文件将其他头文件和源文件与平台差异隔离开来,例如需要按什么顺序包含哪些系统头文件,以及必须定义哪些 C 预处理器功能宏来触发我们期望从系统中获得的某些功能。其推论是 C 文件本身不应直接包含系统头文件。
There are some exceptions, because certain group of files that implement an API all have to include the same header file that defines the API and it is convenient to include <git-compat-util.h> there. Namely:
-
位于 "builtin/" 目录下的内置命令的实现,它们包含 "builtin.h" 以获取 cmd_foo() 的原型定义。
-
位于 "t/helper/" 目录下的测试辅助程序,它们包含 "t/helper/test-tool.h" 以获取 cmd__foo() 的原型定义。
-
位于 "xdiff/" 目录下的 xdiff 实现,它们包含 "xdiff/xinclude.h" 以获取 xdiff 机器内部。
-
位于 "t/unit-tests/" 目录下的单元测试程序,它们包含 "t/unit-tests/test-lib.h",这为它们提供了单元测试框架。
-
位于 "reftable/" 目录下的 reftable 实现的源文件,它们包含 "reftable/system.h" 以获取 reftable 内部。
are allowed to assume that they do not have to include <git-compat-util.h> themselves, as it is included as the first '#include' in these header files. These headers must be the first header file to be "#include"d in them, though.
-
C 文件必须直接包含声明其使用的函数和类型的头文件,但通过包含先前规则所必需的头文件之一而可用的函数和类型除外。
-
如果您计划开发一个新命令,请考虑先用 shell 或 perl 编写它,以便语义上的更改可以轻松地进行修改和讨论。许多 Git 命令都是这样开始的,其中一些仍然是脚本。
-
避免为 Git 引入新的依赖项。这意味着您通常应该远离 Git 核心命令集中尚未使用的脚本语言(除非您的命令明显与之分开,例如用于将随机 SCM-X 存储库转换为 Git 的导入器)。
-
当我们将 <string, length> 对传递给函数时,我们应该尝试按此顺序传递它们。
-
使用 Git 的 gettext 包装器使用户界面可翻译。请参阅 po/README 中的“标记字符串以供翻译”。
-
仅限于给定源文件的变量和函数应标记为 "static"。对其他源文件可见的变量必须在头文件中用 "extern" 声明。但是,函数声明不应使用 "extern",因为这是默认的。
-
您可以使用简写 GIT_DEBUGGER 来启动 gdb 围绕您的程序。运行
GIT_DEBUGGER=1./bin-wrappers/gitfoo来直接使用 gdb,或运行GIT_DEBUGGER="<debugger> <debugger-args>"./bin-wrappers/gitfoo来使用您自己的调试器和参数。示例:GIT_DEBUGGER="ddd--gdb"./bin-wrappers/gitlog(参见bin-wrappers/wrap-for-bin.sh)。 -
子系统 *S* 所处理的主要数据结构称为
structS。操作structS的函数命名为S_<verb>(),并且通常应将指向structS的指针作为第一个参数。例如:struct strbuf;
void strbuf_add(struct strbuf *buf, ...);
void strbuf_reset(struct strbuf *buf);
is preferred over:
struct strbuf;
void add_string(struct strbuf *buf, ...);
void reset_strbuf(struct strbuf *buf);
-
对于对结构
S执行特定任务的函数,有几种常见的惯用名称: -
S_init() 初始化一个结构,而不分配结构本身。 -
S_release() 释放结构的内容,而不重新初始化结构以供立即重用,也不释放结构本身。 -
S_clear() 等同于S_release() 后跟S_init(),以便结构在清除后可直接使用。当提供S_clear() 时,S_init() 不应分配需要再次释放的资源。 -
S_free() 释放结构的内容并释放结构。 -
函数名应清晰且具有描述性,准确反映其目的或行为。不添加有意义上下文的任意后缀可能会导致混淆,尤其是对于新加入代码库的人来说。
Historically, the '_1' suffix has been used in situations where:
-
一个函数处理一组需要类似处理的元素中的一个。
-
递归函数已与其设置阶段分开。
The '_1' suffix can be used as a concise way to indicate these specific cases. However, it is recommended to find a more descriptive name wherever possible to improve the readability and maintainability of the code.
-
位字段定义时不应在冒号周围留有空格。例如:
unsigned my_field:1; unsigned other_field:1; unsigned field_with_longer_name:1;
对于 Perl 程序:
-
上面的大多数 C 指导原则也适用。
-
我们尝试支持 Perl 5.8.1 及更高版本("use Perl 5.008001")。
-
强烈建议使用 strict 和 warnings。
-
除非使用它们能使结果更容易理解,否则不要过度使用语句修饰符。
-
do something … do_this() unless (condition);
-
do something else …
is more readable than:
-
do something … unless (condition) { do_this(); }
-
do something else …
*only* when the condition is so rare that do_this() will be almost always called.
-
-
我们尽量避免在 "if ()" 条件中使用赋值。
-
如果您需要该功能,请学习并使用 Git.pm。
对于 Python 脚本:
-
我们遵循 PEP-8(https://peps.pythonlang.cn/pep-0008/)。
-
至少,我们的目标是兼容 Python 2.7。
-
在必需的库不限制我们使用 Python 2 的情况下,我们还尝试兼容 Python 3.1 及更高版本。
程序输出
We make a distinction between a Git command's primary output and output which is merely chatty feedback (for instance, status messages, running transcript, or progress display), as well as error messages. Roughly speaking, a Git command's primary output is that which one might want to capture to a file or send down a pipe; its chatty output should not interfere with these use-cases.
As such, primary output should be sent to the standard output stream (stdout), and chatty output should be sent to the standard error stream (stderr). Examples of commands which produce primary output include `git log`, `git show`, and `git branch --list` which generate output on the stdout stream.
Not all Git commands have primary output; this is often true of commands whose main function is to perform an action. Some action commands are silent, whereas others are chatty. An example of a chatty action commands is `git clone` with its "Cloning into '<path>'..." and "Checking connectivity..." status messages which it sends to the stderr stream.
Error messages from Git commands should always be sent to the stderr stream.
错误消息
-
不要在单句错误消息的末尾加上句点。
-
不要将第一个词大写,仅仅因为它是一个句子中的第一个词("unable to open %s",而不是 "Unable to open %s")。但 "SHA-3 not supported" 是可以的,因为第一个词大写的原因不是因为它位于句子的开头,而是因为即使出现在句子中间,该词也会以大写字母拼写。
-
先说明错误是什么("cannot open %s",而不是 "%s: cannot open")。
-
在错误的主题两侧加上一对单引号,例如
die(_("unabletoopen%s'"),path)。 -
除非有令人信服的理由不这样做,否则 porcelain 命令的错误消息应标记为可翻译,例如
die(_("badrevision%s"),revision)。 -
plumbing 命令的错误消息有时是供机器使用的,不应标记为可翻译,例如
die("badrevision%s",revision)。 -
BUG("message") 用于向开发者传达特定错误,因此不应被翻译。
外部可见名称
-
对于配置变量名,请遵循现有约定。
-
节名指示受影响的子系统。
-
子节名(如果存在)指示要设置值的无界集合中的哪个。
-
变量名描述了调整此控件的效果。
The section and variable names that consist of multiple words are formed by concatenating the words without punctuation marks (e.g. `-`), and are broken using bumpyCaps in documentation as a hint to the reader.
When choosing the variable namespace, do not use variable name for specifying possibly unbounded set of things, most notably anything an end user can freely come up with (e.g. branch names). Instead, use subsection names or variable values, like the existing variable branch.<name>.description does.
-
编写文档
Most (if not all) of the documentation pages are written in the AsciiDoc format in *.adoc files (e.g. Documentation/git.adoc), and processed into HTML and manpages (e.g. git.html and git.1 in the same directory).
The documentation liberally mixes US and UK English (en_US/UK) norms for spelling and grammar, which is somewhat unfortunate. In an ideal world, it would have been better if it consistently used only one and not the other, and we would have picked en_US (if you wish to correct the English of some of the existing documentation, please see the documentation-related advice in the Documentation/SubmittingPatches file).
In order to ensure the documentation is inclusive, avoid assuming that an unspecified example person is male or female, and think twice before using "he", "him", "she", or "her". Here are some tips to avoid use of gendered pronouns:
-
倾向于简洁地、实事求是地描述抽象功能。例如:
--short-
以短格式输出。
and avoid something like these overly verbose alternatives:
--short-
使用此选项以短格式输出。
--short-
您可以使用此选项以短格式获取输出。
--short-
偏好短输出的用户可能会……
--short-
如果某人或程序想要更短的输出,他们/它就可以……
This practice often eliminates the need to involve human actors in your description, but it is a good practice regardless of the avoidance of gendered pronouns.
-
当坚持这种风格变得笨拙时,在称呼假设的用户时倾向于使用“you”,并在讨论程序如何响应用户时可能使用“we”。例如:
You can use this option instead of `--xyz`, but we might remove support for it in future versions.
while keeping in mind that you can probably be less verbose, e.g.
Use this instead of `--xyz`. This option might be removed in future versions.
-
如果您仍然需要引用一个假设的第三人称单数人物,您可以求助于“单数 they”来避免“he/she/him/her”,例如:
A contributor asks their upstream to pull from them.
Note that this sounds ungrammatical and unnatural to those who learned that "they" is only used for third-person plural, e.g. those who learn English as a second language in some parts of the world.
Every user-visible change should be reflected in the documentation. The same general rule as for code applies -- imitate the existing conventions.
标记
Literal parts (e.g. use of command-line options, command names, branch names, URLs, pathnames (files and directories), configuration and environment variables) must be typeset as verbatim (i.e. wrapped with backticks): `--pretty=oneline` `git rev-list` `remote.pushDefault` `http://git.example.com` `.git/config` `GIT_DIR` `HEAD` `umask`(2)
An environment variable must be prefixed with "$" only when referring to its value and not when referring to the variable itself, in this case there is nothing to add except the backticks: `GIT_DIR` is specified `$GIT_DIR/hooks/pre-receive`
Word phrases enclosed in `backtick characters` are rendered literally
and will not be further expanded. The use of `backticks` to achieve the
previous rule means that literal examples should not use AsciiDoc
escapes.
Correct:
`--pretty=oneline`
Incorrect:
`\--pretty=oneline`
Placeholders are spelled in lowercase and enclosed in
angle brackets surrounded by underscores:
_<file>_
_<commit>_
If a placeholder has multiple words, they are separated by dashes: _<new-branch-name>_ _<template-directory>_
When needed, use a distinctive identifier for placeholders, usually made of a qualification and a type: _<git-dir>_ _<key-id>_
字符也用下划线环绕:LF、CR、CR/LF、NUL、EOF
Git's Asciidoc processor has been tailored to treat backticked text
as complex synopsis. When literal and placeholders are mixed, you can
use the backtick notation which will take care of correctly typesetting
the content.
`--jobs <n>`
`--sort=<key>`
`<directory>/.git`
`remote.<name>.mirror`
`ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>`
作为副作用,反引号占位符会被正确排版,但这种风格不被推荐。
When documenting multiple related `git config` variables, place them on a separate line instead of separating them by commas. For example, do not write this: `core.var1`, `core.var2`:: Description common to `core.var1` and `core.var2`.
而是这样写:core.var1:: core.var2:: core.var1 和 core.var2 的共同描述。
Synopsis 语法
The synopsis (a paragraph with [synopsis] attribute) is automatically formatted by the toolchain and does not need typesetting.
A few commented examples follow to provide reference when writing or modifying command usage strings and synopsis sections in the manual pages:
Possibility of multiple occurrences is indicated by three dots: <file>... (One or more of <file>.)
Optional parts are enclosed in square brackets: [<file>...] (Zero or more of <file>.)
An optional parameter needs to be typeset with unconstrained pairs
[<repository>]
--exec-path[=<path>] (Option with an optional argument. Note that the "=" is inside the brackets.)
[<patch>...] (Zero or more of <patch>. Note that the dots are inside, not outside the brackets.)
Multiple alternatives are indicated with vertical bars: [-q | --quiet] [--utf8 | --no-utf8]
Use spacing around "|" token(s), but not immediately after opening or before closing a [] or () pair: Do: [-q | --quiet] Don't: [-q|--quiet]
Don't use spacing around "|" tokens when they're used to separate the alternate arguments of an option: Do: --track[=(direct|inherit)] Don't: --track[=(direct | inherit)]
Parentheses are used for grouping: [(<rev>|<range>)...] (Any number of either <rev> or <range>. Parens are needed to make it clear that "..." pertains to both <rev> and <range>.)
[(-p <parent>)...] (Any number of option -p, each with one <parent> argument.)
git remote set-head <name> (-a|-d|<branch>) (One and only one of "-a", "-d" or "<branch>" _must_ (no square brackets) be provided.)
And a somewhat more contrived example: --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]] Here "=" is outside the brackets, because "--diff-filter=" is a valid usage. "*" has its own pair of brackets, because it can (optionally) be specified only when one or more of the letters is also provided.
A note on notation: Use 'git' (all lowercase) when talking about commands i.e. something the user would type into a shell and use 'Git' (uppercase first letter) when talking about the version control system and its properties.
If some place in the documentation needs to typeset a command usage example with inline substitutions, it is fine to use +monospaced and inline substituted text+ instead of `monospaced literal text`, and with the former, the part that should not get substituted must be quoted/escaped.