原文:Git Reference 协议:CC BY-NC-SA 4.0
git-format-patch
原文:
git-scm.com/docs/git-format-patch
名称
git-format-patch - 准备电子邮件提交补丁
概要
代码语言:javascript复制git format-patch [-k] [(-o|--output-directory) <dir> | --stdout]
[--no-thread | --thread[=<style>]]
[(--attach|--inline)[=<boundary>] | --no-attach]
[-s | --signoff]
[--signature=<signature> | --no-signature]
[--signature-file=<file>]
[-n | --numbered | -N | --no-numbered]
[--start-number <n>] [--numbered-files]
[--in-reply-to=Message-Id] [--suffix=.<sfx>]
[--ignore-if-in-upstream]
[--rfc] [--subject-prefix=Subject-Prefix]
[(--reroll-count|-v) <n>]
[--to=<email>] [--cc=<email>]
[--[no-]cover-letter] [--quiet] [--notes[=<ref>]]
[--interdiff=<previous>]
[--range-diff=<previous> [--creation-factor=<percent>]]
[--progress]
[<common diff options>]
[ <since> | <revision range> ]
描述
每次提交时,将每个提交的补丁准备在一个文件中,格式化为类似于 UNIX 邮箱格式。此命令的输出便于电子邮件提交或与 git am 一起使用。
有两种方法可以指定要操作的提交。
- 单个提交< since>,指定通往当前分支的提示的提交,这些提交不在历史记录中,导致< since>要输出。
- 通用<修订范围>表达式(参见 gitrevisions [7] 中的“指定修订”部分)表示指定范围内的提交。
在单个< commit>的情况下,第一个规则优先。要应用第二个规则,即从历史开始直到< commit>格式化所有内容,请使用--root
选项:git format-patch --root <commit>
。如果您只想格式化< commit>本身,您可以使用git format-patch -1 <commit>
执行此操作。
默认情况下,每个输出文件从 1 开始按顺序编号,并使用提交消息的第一行(为路径名安全性进行按摩)作为文件名。使用--numbered-files
选项,输出文件名将只是数字,而不会附加提交的第一行。除非指定了--stdout
选项,否则输出文件的名称将打印到标准输出。
如果指定了-o
,则输出文件将在< dir>中创建。否则,它们将在当前工作目录中创建。可以使用format.outputDirectory
配置选项设置默认路径。 -o
选项优先于format.outputDirectory
。要将补丁存储在当前工作目录中,即使format.outputDirectory
指向其他位置,也请使用-o .
。
默认情况下,单个补丁的主题是“[PATCH]”,后跟从提交消息到第一个空行的串联(参见 git-commit [1] 的讨论部分) 。
当输出多个补丁时,主题前缀将改为“[PATCH n / m]”。要强制为单个补丁添加 1/1,请使用-n
。要忽略主题中的色块编号,请使用-N
。
如果给出--thread
,git-format-patch
将生成In-Reply-To
和References
标题,以使第二个和后续的补丁邮件显示为对第一个邮件的回复;这也会生成一个Message-Id
标题来引用。
OPTIONS
代码语言:javascript复制 -p
代码语言:javascript复制 --no-stat
生成没有任何 diffstats 的普通补丁。
代码语言:javascript复制 -U<n>
代码语言:javascript复制 --unified=<n>
用< n>生成差异。上下文而不是通常的三行。
代码语言: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
选项。
--stat[=<width>[,<name-width>[,<count>]]]
生成 diffstat。默认情况下,文件名部分将使用必要的空间,图形部分的其余部分将使用。最大宽度默认为终端宽度,如果未连接到终端,则为 80 列,并且可以被<width>
覆盖。可以通过在逗号后面给出另一个宽度<name-width>
来限制文件名部分的宽度。可以使用--stat-graph-width=<width>
(影响生成统计图的所有命令)或设置diff.statGraphWidth=<width>
(不影响git format-patch
)来限制图形部分的宽度。通过给出第三个参数<count>
,可以将输出限制为第一个<count>
行,如果有更多,则可以将...
限制为...
。
也可以使用--stat-width=<width>
,--stat-name-width=<name-width>
和--stat-count=<count>
单独设置这些参数。
--compact-summary
输出扩展标题信息的精简摘要,例如文件创建或删除(“新”或“消失”,如果是符号链接,则可选“ l”)和模式更改(“ x”或“-x”用于添加或删除 diffstat 中的可执行位)。信息放在文件名部分和图形部分之间。意味着--stat
。
--numstat
与--stat
类似,但显示十进制表示法中添加和删除的行数以及没有缩写的路径名,以使其更加机器友好。对于二进制文件,输出两个-
而不是0 0
。
--shortstat
仅输出--stat
格式的最后一行,其中包含已修改文件的总数,以及已添加和已删除行的数量。
--dirstat[=<param1,param2,…>]
输出每个子目录的相对更改量的分布。 --dirstat
的行为可以通过以逗号分隔的参数列表传递来定制。默认值由diff.dirstat
配置变量控制(参见 git-config [1] )。可以使用以下参数:
changes
通过计算已从源中删除或添加到目标的行来计算 dirstat 数。这忽略了文件中纯代码移动的数量。换句话说,重新排列文件中的行不会像其他更改那样计算。这是没有给出参数时的默认行为。
代码语言:javascript复制 lines
通过执行常规的基于行的差异分析来计算 dirstat 数字,并对移除/添加的行数进行求和。 (对于二进制文件,计算 64 字节块,因为二进制文件没有自然的线条概念)。这是比changes
行为更昂贵的--dirstat
行为,但它确实计算文件中重新排列的行与其他更改一样多。结果输出与您从其他--*stat
选项获得的输出一致。
files
通过计算更改的文件数来计算 dirstat 数。在 dirstat 分析中,每个更改的文件都相同。这是计算上最便宜的--dirstat
行为,因为它根本不需要查看文件内容。
cumulative
计算父目录的子目录中的更改。请注意,使用cumulative
时,报告的百分比总和可能超过 100%。可以使用noncumulative
参数指定默认(非累积)行为。
<limit>
整数参数指定截止百分比(默认为 3%)。贡献低于此百分比变化的目录不会显示在输出中。
示例:以下将计算已更改的文件,同时忽略少于已更改文件总量的 10%的目录,并在父目录中累计子目录计数:--dirstat=files,10,cumulative
。
--summary
输出扩展标题信息的精简摘要,例如创建,重命名和模式更改。
代码语言:javascript复制 --no-renames
关闭重命名检测,即使配置文件提供默认值也是如此。
代码语言:javascript复制 --full-index
在生成补丁格式输出时,在“索引”行上显示完整的前映像和后映像 blob 对象名称,而不是第一个字符。
代码语言:javascript复制 --binary
除--full-index
外,还可输出可用git-apply
应用的二进制差异。
--abbrev[=<n>]
而不是在 diff-raw 格式输出和 diff-tree 标题行中显示完整的 40 字节十六进制对象名称,而是仅显示部分前缀。这与上面的--full-index
选项无关,后者控制 diff-patch 输出格式。可以使用--abbrev=<n>
指定非默认位数。
-B[<n>][/<m>]
代码语言:javascript复制 --break-rewrites[=[<n>][/<m>]]
将完整的重写更改分为删除和创建对。这有两个目的:
它影响了一个更改的方式,相当于一个文件的完全重写,而不是一系列的删除和插入混合在一起,只有几行恰好与文本作为上下文匹配,而是作为单个删除所有旧的后跟一个单个插入所有新内容,数字m
控制-B 选项的这一方面(默认为 60%)。 -B/70%
指定少于 30%的原始文本应保留在结果中,以便 Git 将其视为完全重写(即,否则生成的修补程序将是一系列删除和插入与上下文行混合在一起)。
当与-M 一起使用时,完全重写的文件也被视为重命名的源(通常-M 只考虑作为重命名源消失的文件),并且数字n
控制 - 的这方面 - B 选项(默认为 50%)。 -B20%
指定添加和删除的更改与文件大小的 20%或更多相比,有资格被选为可能的重命名源到另一个文件。
-M[<n>]
代码语言:javascript复制 --find-renames[=<n>]
检测重命名。如果指定了n
,则它是相似性指数的阈值(即与文件大小相比的添加/删除量)。例如,-M90%
表示如果超过 90%的文件未更改,Git 应将删除/添加对视为重命名。如果没有%
符号,则该数字将作为分数读取,并在其前面加上小数点。即,-M5
变为 0.5,因此与-M50%
相同。同样,-M05
与-M5%
相同。要将检测限制为精确重命名,请使用-M100%
。默认相似性指数为 50%。
-C[<n>]
代码语言:javascript复制 --find-copies[=<n>]
检测副本以及重命名。另见--find-copies-harder
。如果指定了n
,则其含义与-M<n>
的含义相同。
--find-copies-harder
出于性能原因,默认情况下,仅当在同一变更集中修改了副本的原始文件时,-C
选项才会查找副本。此标志使命令检查未修改的文件作为副本源的候选者。对于大型项目来说,这是一项非常昂贵的操作,因此请谨慎使用。提供多个-C
选项具有相同的效果。
-D
代码语言:javascript复制 --irreversible-delete
省略删除的原像,即只打印标题而不打印原像和/dev/null
之间的差异。得到的贴片不适用于patch
或git apply
;这仅适用于那些希望在更改后专注于审阅文本的人。此外,输出显然缺乏足够的信息来反向应用这样的补丁,甚至手动,因此选项的名称。
与-B
一起使用时,也省略删除/创建对的删除部分中的原像。
-l<num>
-M
和-C
选项需要 O(n ^ 2)处理时间,其中 n 是潜在的重命名/复制目标的数量。如果重命名/复制目标的数量超过指定的数量,此选项可防止重命名/复制检测运行。
-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
”。
-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。
-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] 。
代码语言:javascript复制 -<n>
从最顶层< n>准备补丁。提交。
代码语言:javascript复制 -o <dir>
代码语言:javascript复制 --output-directory <dir>
使用< dir>存储生成的文件,而不是当前的工作目录。
代码语言:javascript复制 -n
代码语言:javascript复制 --numbered
名称输出为 [PATCH n / m] 格式,即使只有一个补丁。
代码语言:javascript复制 -N
代码语言:javascript复制 --no-numbered
以 [PATCH] 格式输出名称。
代码语言:javascript复制 --start-number <n>
开始在< n>处对补丁进行编号。而不是 1。
代码语言:javascript复制 --numbered-files
输出文件名将是一个简单的数字序列,不附加提交的默认第一行。
代码语言:javascript复制 -k
代码语言:javascript复制 --keep-subject
不要从提交日志消息的第一行剥离/添加 [PATCH] 。
代码语言:javascript复制 -s
代码语言:javascript复制 --signoff
使用您自己的提交者标识将Signed-off-by:
行添加到提交消息中。有关详细信息,请参阅 git-commit [1] 中的签收选项。
--stdout
以 mbox 格式将所有提交打印到标准输出,而不是为每个提交创建文件。
代码语言:javascript复制 --attach[=<boundary>]
使用Content-Disposition: attachment
创建多部分/混合附件,第一部分是提交消息,第二部分是补丁本身。
--no-attach
禁用附件的创建,覆盖配置设置。
代码语言:javascript复制 --inline[=<boundary>]
使用Content-Disposition: inline
创建多部分/混合附件,第一部分是提交消息,第二部分是补丁本身。
--thread[=<style>]
代码语言:javascript复制 --no-thread
控制添加In-Reply-To
和References
标题以使第二个和后续邮件显示为对第一个邮件的回复。还控制Message-Id
标头的生成以供参考。
可选的< style>参数可以是shallow
或deep
。 _ 浅 _ 线程使每个邮件都回复到系列的头部,其中头部是从求职信,--in-reply-to
和第一个补丁邮件中按顺序选择的。 _ 深 _ 线程使每封邮件都回复上一封邮件。
除非设置了format.thread
配置,否则默认值为--no-thread
。如果指定--thread
时没有样式,则默认为format.thread
指定的样式(如果有),否则为shallow
。
请注意, git send-email 的默认设置是自行编排电子邮件。如果希望git format-patch
处理线程,则需要确保为git send-email
禁用线程。
--in-reply-to=Message-Id
使第一封邮件(或所有带有--no-thread
的邮件)显示为对给定 Message-Id 的回复,这可以避免破坏线程以提供新的补丁系列。
--ignore-if-in-upstream
请勿在< until> …< since>中包含与提交相匹配的修补程序。这将检查从< since>可到达的所有补丁。但不是来自< until>并将它们与正在生成的补丁进行比较,并忽略任何匹配的补丁。
代码语言:javascript复制 --subject-prefix=<Subject-Prefix>
而不是主题行中的标准 [PATCH] 前缀,而是使用 [< Subject-Prefix>] 。这允许对补丁系列进行有用的命名,并且可以与--numbered
选项组合使用。
--rfc
--subject-prefix="RFC PATCH"
的别名。 RFC 表示“征求意见”;发送实验补丁进行讨论而不是应用时使用此功能。
-v <n>
代码语言:javascript复制 --reroll-count=<n>
将该系列标记为该主题的第 n 次迭代。输出文件名前面有v<n>
,主题前缀(默认情况下为“PATCH”,但可通过--subject-prefix
选项配置)附加了“v< n>”。例如。 --reroll-count=4
可能会生成[主题:[PATCH v4 1/20]添加 makefile“的v4-0001-add-makefile.patch
文件。
--to=<email>
将To:
标头添加到电子邮件标头中。这是对任何已配置标头的补充,可以多次使用。否定形式--no-to
丢弃到目前为止添加的所有To:
标题(从配置或命令行)。
--cc=<email>
将Cc:
标头添加到电子邮件标头中。这是对任何已配置标头的补充,可以多次使用。否定形式--no-cc
丢弃到目前为止添加的所有Cc:
标题(从配置或命令行)。
--from
代码语言:javascript复制 --from=<ident>
在每个提交电子邮件的From:
标题中使用ident
。如果提交的作者标识在文本上与提供的ident
不同,则在原始作者的消息正文中放置From:
标题。如果没有给出ident
,请使用提交者标识。
请注意,此选项仅在您实际发送电子邮件并希望将自己标识为发件人时才有用,但保留原始作者(并且git am
将正确选取体内标题)。另请注意,git send-email
已经为您处理了此转换,如果将结果输入git send-email
,则不应使用此选项。
--add-header=<header>
向电子邮件标头添加任意标头。这是对任何已配置标头的补充,可以多次使用。例如,--add-header="Organization: git-foo"
。否定形式--no-add-header
丢弃到目前为止从配置或命令行添加的所有(To:
,Cc:
和自定义)标题。
--[no-]cover-letter
除了补丁之外,还生成一个包含分支描述,短信和整体 diffstat 的求职信文件。您可以在发送之前在文件中填写说明。
代码语言:javascript复制 --interdiff=<previous>
作为审阅者辅助工具,请在封面信中插入一个 interdiff,或作为单补丁系列的单个补丁的注释,显示补丁系列的先前版本与当前正在格式化的系列之间的差异。 previous
是一个单一的修订版,命名前一个系列的提示,它与正在格式化的系列共享一个共同的基础(例如git format-patch --cover-letter --interdiff=feature/v1 -3 feature/v2
)。
--range-diff=<previous>
作为评论者的帮助,将一个范围差异(参见 git-range-diff [1] )插入到求职信中,或作为单补丁系列的单个补丁的评论,显示之间的差异补丁系列的先前版本和当前正在格式化的系列。 previous
可以是命名前一系列提示的单个修订,如果它与正在格式化的系列共享一个公共基础(例如git format-patch --cover-letter --range-diff=feature/v1 -3 feature/v2
),或者如果系列的两个版本不相交,则为修订范围(例如git format-patch --cover-letter --range-diff=feature/v1~3..feature/v1 -3 feature/v2
)。
请注意,传递给命令的 diff 选项会影响format-patch
的主要产品的生成方式,并且它们不会传递给用于生成封面信函材料的基础range-diff
机器(这可能在将来发生变化)。
--creation-factor=<percent>
与--range-diff
一起使用,通过调整创建/删除成本软糖因子,调整与先前和当前系列补丁之间的提交匹配的启发式。有关详细信息,请参阅 git-range-diff [1] )。
--notes[=<ref>]
在三个虚线后添加注释(参见 git-notes [1] )进行提交。
这种情况的预期用例是为不属于提交日志消息的提交编写支持说明,并将其包含在补丁提交中。虽然可以在format-patch
运行之后但在发送之前简单地编写这些解释,但将它们保留为 Git 注释允许它们在补丁系列的版本之间进行维护(但请参阅 git 中notes.rewrite
配置选项的讨论) -notes [1] 使用此工作流程)。
--[no-]signature=<signature>
为每条生成的消息添加签名。根据 RFC 3676,签名通过一条带有“ - ”的行与主体分开。如果省略签名选项,则签名默认为 Git 版本号。
代码语言:javascript复制 --signature-file=<file>
就像–signature 一样工作,除了从文件中读取签名。
代码语言:javascript复制 --suffix=.<sfx>
不使用.patch
作为生成的文件名的后缀,而是使用指定的后缀。一种常见的替代方案是--suffix=.txt
。保留此空将删除.patch
后缀。
请注意,前导字符不必是点;例如,您可以使用--suffix=-patch
来获取0001-description-of-my-change-patch
。
-q
代码语言:javascript复制 --quiet
不要将生成的文件的名称打印到标准输出。
代码语言:javascript复制 --no-binary
不要输出二进制文件中的更改内容,而是显示这些文件发生更改的通知。使用此选项生成的修补程序无法正确应用,但它们仍可用于代码审查。
代码语言:javascript复制 --zero-commit
在每个补丁的 From 头中输出一个全零散列,而不是提交的散列。
代码语言:javascript复制 --base=<commit>
记录基础树信息以识别修补程序系列适用的状态。有关详细信息,请参阅下面的“基础树信息”部分。
代码语言:javascript复制 --root
将修订参数视为< revision range>,即使它只是一次提交(通常将其视为< since>)。请注意,指定范围中包含的根提交始终格式化为创建修补程序,与此标志无关。
代码语言:javascript复制 --progress
在生成修补程序时显示有关 stderr 的进度报告。
组态
您可以指定要添加到每封邮件的额外邮件标题行,主题前缀和文件后缀的默认值,输出多个补丁时的编号补丁,添加“收件人”或“抄送:”标题,配置附件和签署补丁配置变量。
代码语言:javascript复制[format]
headers = "Organization: git-foon"
subjectPrefix = CHANGE
suffix = .txt
numbered = auto
to = <email>
cc = <email>
attach [ = mime-boundary-string ]
signOff = true
coverletter = auto
讨论
由 git format-patch 生成的补丁是 UNIX 邮箱格式,带有固定的“魔术”时间戳,表示文件是从格式补丁而不是真实邮箱输出的,如下所示:
代码语言:javascript复制From 8f72bad1baf19a53459661343e21d6491c3908d3 Mon Sep 17 00:00:00 2001
From: Tony Luck <tony.luck@intel.com>
Date: Tue, 13 Jul 2010 11:42:54 -0700
Subject: [PATCH] =?UTF-8?q?[IA64]=20Put=20ia64=20config=20files=20on=20the=20?=
=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig=20diet?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
arch/arm config files were slimmed down using a python script
(See commit c2330e286f68f1c408b4aa6515ba49d57f05beae comment)
Do the same for ia64 so we can have sleek & trim looking
...
通常情况下,它会被放置在 MUA 的草稿文件夹中,编辑后添加及时的评论,不应该在三个破折号后进入更改日志,然后作为消息发送,在我们的示例中,其主体以“arch / arm 配置文件”开头…”。在接收端,读者可以在 UNIX 邮箱中保存有趣的补丁,并将其应用于 git-am [1] 。
当补丁是正在进行的讨论的一部分时, git format-patch 生成的补丁可以调整以利用 git am --scissors 功能。在您对讨论的回复之后出现了一条仅包含“-- >8 --
”(剪刀和穿孔)的行,然后删除了不必要的标题字段的补丁:
...
> So we should do such-and-such.
Makes sense to me. How about this patch?
-- >8 --
Subject: [IA64] Put ia64 config files on the Uwe Kleine-K��nig diet
arch/arm config files were slimmed down using a python script
...
以这种方式发送补丁时,大多数情况下您都在发送自己的补丁,因此除了“From SHA1 magic_timestamp”标记外,您还应该省略补丁文件中的From:和Date:行。修补程序标题可能与修补程序响应的讨论主题不同,因此您可能希望保留 Subject:行,就像上面的示例一样。
检查修补程序损坏
如果没有正确设置许多邮件程序将破坏空白。以下是两种常见的腐败类型:
- 没有 _ 任何 _ 空格的空上下文行。
- 非空上下文行,在开头有一个额外的空格。
测试 MUA 设置是否正确的一种方法是:
除了使用不包含列表和维护者地址的 To:和 Cc:行之外,完全按照您的方式发送补丁。
将该修补程序保存为 UNIX 邮箱格式的文件。比如叫它 a.patch。
适用它:
代码语言:javascript复制$ git fetch <project> master:test-apply
$ git checkout test-apply
$ git reset --hard
$ git am a.patch
如果它没有正确应用,可能有各种原因。
- 补丁本身并不干净。那是 _ 坏 _,但与你的 MUA 没什么关系。在这种情况下重新生成之前,您可能需要使用 git-rebase [1] 来修改补丁。
- MUA 破坏了你的补丁; “我”会抱怨补丁不适用。查看.git / rebase-apply /子目录,查看 _ 补丁 _ 文件包含的内容,并检查上面提到的常见损坏模式。
- 在此期间,检查 _ 信息 _ 和 _ 最终提交 _ 文件。如果 final-commit 中的内容不是您希望在提交日志消息中看到的内容,那么接收器最终可能会在应用您的修补程序时手动编辑日志消息。诸如“嗨,这是我的第一个补丁。 n”在补丁电子邮件中的内容应该出现在表示提交消息结束的三个虚线之后。
特定于 MUA 的提示
以下是有关如何使用各种邮件程序成功提交内联补丁的一些提示。
GMail 的
GMail 无法在网络界面中关闭换行,因此它会破坏您发送的任何电子邮件。但是,您可以使用“git send-email”并通过 GMail SMTP 服务器发送补丁,或使用任何 IMAP 电子邮件客户端连接到 Google IMAP 服务器并通过该服务器转发电子邮件。
有关使用 git send-email 通过 GMail SMTP 服务器发送补丁的提示,请参阅 git-send-email [1] 的示例部分。
有关使用 IMAP 界面提交的提示,请参阅 git-imap-send [1] 的示例部分。
雷鸟
默认情况下,Thunderbird 会将电子邮件包装起来并将其标记为 format = flowed ,这两种情况都会导致 Git 无法使用该电子邮件。
有三种不同的方法:使用附加组件来关闭换行,配置 Thunderbird 以不破坏补丁,或者使用外部编辑器来防止 Thunderbird 破坏补丁。
方法#1(附加)
安装可从 addons.mozilla.org/thunderbird/addon/toggle-word-wrap/
获得的 Toggle Word Wrap 附加组件。它添加了一个菜单项“启用 Word Wrap”作曲家的“选项”菜单,您可以勾选。现在你可以像你一样编写消息(剪切 粘贴, git format-patch | git imap-send 等),但你必须在任何地方手动插入换行符您键入的文本。
方法#2(配置)
三个步骤:
- 将您的邮件服务器组成配置为纯文本:编辑…帐户设置…组合&amp;寻址,取消选中“以 HTML 格式撰写邮件”。
- 将常规合成窗口配置为不换行。
在 Thunderbird 2 中:Edit…Preferences…Composition,将纯文本消息包装在 0
在 Thunderbird 3:Edit…Preferences…Advanced…Config 编辑器。搜索“mail.wrap_long_lines”。切换它以确保它设置为
false
。此外,搜索“mailnews.wraplength”并将值设置为 0。 - 禁用 format = flowed:Edit…Preferences…Advanced…Config Editor。搜索“mailnews.send_plaintext_flowed”。切换它以确保它设置为
false
。
完成之后,你应该能够像你一样编写电子邮件(剪切 粘贴, _git 格式补丁 _ | git imap-send 等),补丁将不被破坏。
方法#3(外部编辑)
需要以下 Thunderbird 扩展:来自 aboutconfig.mozdev.org/
的 AboutConfig 和来自的外部编辑 http://globs.org/articles.php?lng=en&pg= 8
使用您选择的方法将补丁准备为文本文件。
在打开撰写窗口之前,请使用编辑→帐户设置取消选中要用于发送修补程序的帐户的“撰写和寻址”面板中的“以 HTML 格式撰写邮件”设置。
在主要的 Thunderbird 窗口中,之前的 _ 打开补丁的撰写窗口,使用工具→about:config 将以下内容设置为指示的值:_
代码语言:javascript复制 mailnews.send_plaintext_flowed => false
mailnews.wraplength => 0
打开撰写窗口,然后单击外部编辑器图标。
在外部编辑器窗口中,读入补丁文件并正常退出编辑器。
附注:可以使用 about:config 和以下设置执行第 2 步,但尚未尝试过任何人。
代码语言:javascript复制 mail.html_compose => false
mail.identity.default.compose_html => false
mail.identity.id?.compose_html => false
contrib / thunderbird-patch-inline 中有一个脚本可以帮助您以简单的方式包含 Thunderbird 的补丁。要使用它,请执行上述步骤,然后将脚本用作外部编辑器。
KMail 的
这应该可以帮助您使用 KMail 内联提交补丁。
- 准备补丁作为文本文件。
- 单击“新邮件”。
- 转到 Composer 窗口中的“选项”下,确保未设置“自动换行”。
- 使用消息→插入文件…并插入补丁。
- 回到撰写窗口:在邮件中添加您希望的任何其他文本,完成寻址和主题字段,然后按发送。
基础树信息
基础树信息块用于维护人员或第三方测试人员,以了解补丁系列适用的确切状态。它由 _ 基础提交 _ 组成,这是一个众所周知的提交,它是项目历史中其他人工作的稳定部分的一部分,以及零个或多个 _ 先决条件补丁 _,飞行中众所周知的补丁尚未成为 _ 基础提交 _ 的一部分,需要在应用补丁之前以拓扑顺序应用于 _ 基础提交 _ 之上。
base commit 显示为“base-commit:”,后跟提交对象名称的 40-hex。 _ 先决条件补丁 _ 显示为“prerequisite-patch-id:”,后跟 40-hex _ 补丁 ID_ ,可以通过git patch-id --stable
命令传递补丁获得。
想象一下,除了公共提交 P 之外,你从其他人那里应用了着名的补丁 X,Y 和 Z,然后构建了你的三个补丁系列 A,B,C,历史就像:
代码语言:javascript复制---P---X---Y---Z---A---B---C
使用git format-patch --base=P -3 C
(或其变体,例如使用--cover-letter
或使用Z..C
而不是-3 C
来指定范围),基本树信息块显示在命令输出的第一条消息的末尾(要么第一个补丁,或求职信),像这样:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
对于非线性拓扑,例如
代码语言:javascript复制---P---X---A---M---C
/
Y---Z---B
您还可以使用git format-patch --base=P -3 C
为 A,B 和 C 生成补丁,并在第一条消息的末尾附加 P,X,Y,Z 的标识符。
如果在 cmdline 中设置--base=auto
,它将自动跟踪基本提交,基本提交将是远程跟踪分支的提示提交和 cmdline 中指定的修订范围的合并基础。对于本地分支,您需要在使用此选项之前通过git branch --set-upstream-to
跟踪远程分支。
例子
在版本 R1 和 R2 之间提取提交,并使用 git am 将它们应用于当前分支之上以挑选它们:
代码语言:javascript复制$ git format-patch -k --stdout R1..R2 | git am -3 -k
提取当前分支中但不在原始分支中的所有提交:
代码语言:javascript复制$ git format-patch origin
对于每个提交,在当前目录中创建单独的文件。
从项目开始以来,提取导致 _ 起源 _ 的所有提交:
代码语言:javascript复制$ git format-patch --root origin
与前一个相同:
代码语言:javascript复制$ git format-patch -M -B origin
此外,它可以检测并处理重命名并智能地完成重写以生成重命名补丁。重命名补丁可减少文本输出量,并且通常可以更轻松地进行查看。请注意,非 Git“补丁”程序将无法理解重命名补丁,因此仅在您知道收件人使用 Git 应用补丁时才使用它。
从当前分支中提取三个最顶层的提交,并将它们格式化为可通过电子邮件发送的补丁:
代码语言:javascript复制$ git format-patch -3
也可以看看
git-am [1] , git-send-email [1]
GIT
部分 git [1] 套件
git-send-email
原文:
git-scm.com/docs/git-send-email
名称
git-send-email - 以电子邮件形式发送补丁集合
概要
代码语言:javascript复制git send-email [<options>] <file|directory|rev-list options>…
git send-email --dump-aliases
描述
获取命令行上给出的补丁并通过电子邮件发送出去。可以将修补程序指定为文件,目录(将发送目录中的所有文件),或直接指定为修订列表。在最后一种情况下, git-format-patch [1] 接受的任何格式都可以传递给 git send-email。
电子邮件的标题可通过命令行选项进行配置。如果未在命令行中指定,将提示用户启用 ReadLine 接口以提供必要信息。
补丁文件有两种格式:
- mbox 格式文件 这就是 git-format-patch [1] 生成的内容。大多数标头和 MIME 格式都会被忽略。
- Greg Kroah-Hartman 的 send_lots_of_email.pl 脚本使用的原始格式 此格式要求文件的第一行包含“Cc:”值和消息的“Subject:”作为第二行。
OPTIONS
构成
代码语言:javascript复制 --annotate
查看并编辑您即将发送的每个补丁。默认值是sendemail.annotate
的值。有关sendemail.multiEdit
的信息,请参阅配置部分。
--bcc=<address>,…
为每封电子邮件指定“密件抄送:”值。默认值是sendemail.bcc
的值。
可以多次指定此选项。
代码语言:javascript复制 --cc=<address>,…
为每封电子邮件指定起始“抄送:”值。默认值是sendemail.cc
的值。
可以多次指定此选项。
代码语言:javascript复制 --compose
调用文本编辑器(参见 git-var [1] 中的 GIT_EDITOR)来编辑补丁系列的介绍性消息。
使用--compose
时,git send-email 将使用消息中指定的 From,Subject 和 In-Reply-To 标头。如果邮件的正文(您在标题后面键入的内容和空行)仅包含空行(或 Git:前缀)行,则不会发送摘要,但是 From,Subject 和 In-Reply-To 标题将除非他们被删除使用。
将提示缺少 From 或 In-Reply-To 标头。
请参见sendemail.multiEdit
的 CONFIGURATION 部分。
--from=<address>
指定电子邮件的发件人。如果未在命令行中指定,则使用sendemail.from
配置选项的值。如果既未设置命令行选项也未设置sendemail.from
,则将提示用户输入值。提示的默认值将是 GIT_AUTHOR_IDENT 的值,如果未设置,则为 GIT_COMMITTER_IDENT,由“git var -l”返回。
--reply-to=<address>
指定收件人应答的地址。如果对消息的回复应该转到另一个地址而不是–from 参数指定的地址,请使用此选项。
代码语言:javascript复制 --in-reply-to=<identifier>
使第一封邮件(或所有带有--no-thread
的邮件)显示为对给定 Message-Id 的回复,这可以避免破坏线程以提供新的补丁系列。第二封及后续电子邮件将根据--[no-]chain-reply-to
设置作为回复发送。
因此,例如,当指定--thread
和--no-chain-reply-to
时,第二个和后续补丁将回复第一个补丁,如下图所示[PATCH v2 0/3]
回复[PATCH 0/2]
:
[PATCH 0/2] Here is what I did...
[PATCH 1/2] Clean up and tests
[PATCH 2/2] Implementation
[PATCH v2 0/3] Here is a reroll
[PATCH v2 1/3] Clean up
[PATCH v2 2/3] New tests
[PATCH v2 3/3] Implementation
仅在设置了–compose 时才需要。如果未设置–compose,则会提示。
代码语言:javascript复制 --subject=<string>
指定电子邮件线程的初始主题。仅在设置了–compose 时才需要。如果未设置–compose,则会提示。
代码语言:javascript复制 --to=<address>,…
指定生成的电子邮件的主要收件人。通常,这将是所涉及项目的上游维护者。默认值是sendemail.to
配置值的值;如果未指定,并且未指定–to-cmd,则会提示。
可以多次指定此选项。
代码语言:javascript复制 --8bit-encoding=<encoding>
遇到非 ASCII 消息或未声明其编码的主题时,添加标题/引用以指示它在< encoding>中编码。默认值是 sendemail.assume8bitEncoding 的值;如果未指定,则会在遇到任何非 ASCII 文件时提示。
请注意,不会尝试验证编码。
代码语言:javascript复制 --compose-encoding=<encoding>
指定撰写邮件的编码。默认值是 sendemail.composeencoding 的值;如果未指定,则假定为 UTF-8。
代码语言:javascript复制 --transfer-encoding=(7bit|8bit|quoted-printable|base64|auto)
指定用于通过 SMTP 发送邮件的传输编码。遇到非 ASCII 消息时,7 位将失败。当存储库包含包含回车符的文件时,quoted-printable 可能很有用,但是使原始补丁电子邮件文件(从 MUA 保存)更难以手动检查。 base64 更加傻瓜式,但也更加不透明。 auto 会尽可能使用 8bit,否则引用可打印。
默认值是sendemail.transferEncoding
配置值的值;如果未指定,则默认为auto
。
--xmailer
代码语言:javascript复制 --no-xmailer
添加(或阻止添加)“X-Mailer:”标题。默认情况下,会添加标题,但可以通过将sendemail.xmailer
配置变量设置为false
来关闭标题。
发出
代码语言:javascript复制 --envelope-sender=<address>
指定用于发送电子邮件的信封发件人。如果您的默认地址不是订阅列表的地址,这将非常有用。要使用 From 地址,请将值设置为“auto”。如果使用 sendmail 二进制文件,则必须具有-f 参数的适当权限。默认值是sendemail.envelopeSender
配置变量的值;如果未指定,则选择信封发件人将留给您的 MTA。
--smtp-encryption=<encryption>
指定要使用的加密, ssl 或 tls 。任何其他值都将恢复为纯 SMTP。默认值是sendemail.smtpEncryption
的值。
--smtp-domain=<FQDN>
指定 HELO / EHLO 命令中用于 SMTP 服务器的完全限定域名(FQDN)。某些服务器要求 FQDN 与您的 IP 地址匹配。如果未设置,git send-email 会尝试自动确定您的 FQDN。默认值是sendemail.smtpDomain
的值。
--smtp-auth=<mechanisms>
允许的 SMTP-AUTH 机制的以空格分隔的列表。此设置仅强制使用列出的机制。例:
代码语言:javascript复制$ git send-email --smtp-auth="PLAIN LOGIN GSSAPI" ...
如果至少一个指定的机制与 SMTP 服务器通告的机制匹配,并且所使用的 SASL 库支持该机制,则该机制用于身份验证。如果既未指定 sendemail.smtpAuth 也未指定--smtp-auth
,则可以使用 SASL 库支持的所有机制。特殊值 none 可能被指定为独立于--smtp-user
完全禁用认证
--smtp-pass[=<password>]
SMTP-AUTH 的密码。参数是可选的:如果未指定参数,则使用空字符串作为密码。默认值为sendemail.smtpPass
,但--smtp-pass
始终覆盖此值。
此外,无需在配置文件或命令行中指定密码。如果已指定用户名(使用--smtp-user
或sendemail.smtpUser
),但未指定密码(使用--smtp-pass
或sendemail.smtpPass
),则使用 git-credential 获取密码。
--no-smtp-auth
禁用 SMTP 身份验证。 --smtp-auth=none
的简写
--smtp-server=<host>
如果设置,则指定要使用的传出 SMTP 服务器(例如smtp.example.com
或原始 IP 地址)。或者,它可以指定类似 sendmail 的程序的完整路径名;该程序必须支持-i
选项。可以通过sendemail.smtpServer
配置选项指定默认值;内置默认值是在/usr/sbin
,/usr/lib
和$ PATH 中搜索sendmail
(如果此类程序可用),否则返回localhost
。
--smtp-server-port=<port>
指定与默认端口不同的端口(SMTP 服务器通常侦听 smtp 端口 25,但也可以侦听提交端口 587 或公共 SSL smtp 端口 465);也接受符号端口名称(例如“提交”而不是 587)。也可以使用sendemail.smtpServerPort
配置变量设置端口。
--smtp-server-option=<option>
如果设置,则指定要使用的传出 SMTP 服务器选项。可以通过sendemail.smtpServerOption
配置选项指定默认值。
必须为要传递给服务器的每个选项重复–smtp-server-option 选项。同样,必须为每个选项使用配置文件中的不同行。
代码语言:javascript复制 --smtp-ssl
–smtp-encryption ssl 的旧版别名。
代码语言:javascript复制 --smtp-ssl-cert-path
用于 SMTP SSL / TLS 证书验证的可信 CA 证书存储的路径(已由 c_rehash 处理的目录,或包含一个或多个 PEM 格式证书的单个文件连接在一起:请参阅 verify(1 )-CAfile 和-CApath 有关这些的更多信息)。将其设置为空字符串以禁用证书验证。默认为sendemail.smtpsslcertpath
配置变量的值(如果已设置),或者支持 SSL 库的默认编译(在大多数平台上应该是最佳选择)。
--smtp-user=<user>
SMTP-AUTH 的用户名。默认值是sendemail.smtpUser
的值;如果未指定用户名(使用--smtp-user
或sendemail.smtpUser
),则不会尝试进行身份验证。
--smtp-debug=0|1
启用(1)或禁用(0)调试输出。如果启用,将打印 SMTP 命令和答复。用于调试 TLS 连接和身份验证问题。
代码语言:javascript复制 --batch-size=<num>
某些电子邮件服务器(例如 smtp.163.com)限制每个会话(连接)发送的电子邮件数量,这将导致发送许多邮件时出现故障。使用此选项,send-email 将在发送$< num>后断开连接。消息并等待几秒钟(请参阅–relogin-delay)并重新连接,以解决此类限制。您可能希望使用某种形式的凭据帮助程序,以避免每次发生这种情况时都必须重新键入密码。默认为sendemail.smtpBatchSize
配置变量。
--relogin-delay=<int>
等待$< int>重新连接到 SMTP 服务器之前的秒数。与–batch-size 选项一起使用。默认为sendemail.smtpReloginDelay
配置变量。
自动化
代码语言:javascript复制 --to-cmd=<command>
指定每个补丁文件执行一次的命令,该文件应生成特定于补丁文件的“收件人:”条目。此命令的输出必须是每行一个电子邮件地址。默认值为 sendemail.tocmd 配置值。
代码语言:javascript复制 --cc-cmd=<command>
指定每个补丁文件执行一次的命令,该文件应生成特定于补丁文件的“Cc:”条目。此命令的输出必须是每行一个电子邮件地址。默认值是sendemail.ccCmd
配置值的值。
--[no-]chain-reply-to
如果设置了此项,则每封电子邮件都将作为对上一封电子邮件的回复发送。如果使用“–no-chain-reply-to”禁用,则第一封后的所有电子邮件将作为对第一封电子邮件的回复发送。使用它时,建议给出的第一个文件是整个补丁系列的概述。默认情况下禁用,但sendemail.chainReplyTo
配置变量可用于启用它。
--identity=<identity>
配置标识。给定时,会导致 sendemail 中的值。< identity> 子部分优先于 sendemail 部分中的值。默认标识是sendemail.identity
的值。
--[no-]signed-off-by-cc
如果设置了此项,请将在 Signed-off-by:或 Cc:行中找到的电子邮件添加到 cc 列表中。默认值是sendemail.signedoffbycc
配置值的值;如果未指定,则默认为–signed-off-by-cc。
--[no-]cc-cover
如果设置了此项,则系列的第一个补丁中的 Cc:标题中的电子邮件(通常是求职信)将添加到每个电子邮件集的 cc 列表中。默认值为 sendemail.cccover 配置值;如果未指定,则默认为–no-cc-cover。
代码语言:javascript复制 --[no-]to-cover
如果设置了此项,则系列的第一个补丁中的 To:标题中找到的电子邮件(通常是求职信)将添加到每个电子邮件集的列表中。默认值为 sendemail.tocover 配置值;如果未指定,则默认为–no-to-cover。
代码语言:javascript复制 --suppress-cc=<category>
指定其他类别的收件人以禁止 auto-cc:
- _ 作者 _ 将避免包括补丁作者。
- _ 自 _ 将避免包含发件人。
- cc 将避免包括除自我之外的补丁标题中的 Cc 行中提到的任何人(使用 self )。
- bodycc 将避免包括在补丁体(提交消息)中的 Cc 行中提到的任何人,除了 self(使用 self )。
- _ 呜咽 _ 将避免包括除了自我之外的签名旁线中提到的任何人(使用 _ 自 _)。
- misc-by 将避免包括在 Acked-by,Review-by,Tested-by 和补丁体中的其他“-by”行中提到的任何人,除了 Signed-off-by(使用 sob 为此)。
- cccmd 将避免运行–cc-cmd。
- _ 体 _ 相当于 sob bodycc misc-by 。
- _ 所有 _ 将抑制所有自动 cc 值。
默认值是sendemail.suppresscc
配置值的值;如果未指定,如果指定了–suppress-from,则默认为 self ,如果指定了–no-signed-off-cc,则默认为 body 。
--[no-]suppress-from
如果设置了此项,请不要将 From:地址添加到 cc:列表。默认值是sendemail.suppressFrom
配置值的值;如果未指定,则默认为–no-suppress-from。
--[no-]thread
如果设置了此项,则会将 In-Reply-To 和 References 标头添加到发送的每封电子邮件中。每个邮件是否引用前一封电子邮件(每个 git format-pat 措辞的deep
线程)或第一封电子邮件(shallow
线程)由“ - [no-]链式回复控制-至”。
如果使用“–no-thread”禁用,则不会添加这些标头(除非使用–in-reply-to 指定)。默认值是sendemail.thread
配置值的值;如果未指定,则默认为–thread。
当 git send-email 被要求添加它时,由用户确保不存在 In-Reply-To 标头(特别注意 git format-patch 可以是配置为执行线程本身)。如果不这样做,可能无法在收件人的 MUA 中产生预期的结果。
管理
代码语言:javascript复制 --confirm=<mode>
发送前确认:
- _ 始终 _ 将始终在发送前确认
- _ 从来没有 _ 在发送之前永远不会确认
- cc 将在发送之前确认 send-email 自动将补丁中的地址添加到抄送列表
- _ 撰写 _ 将在使用–compose 发送第一条消息之前确认。
- auto 相当于 cc _ 组成 _
默认值是sendemail.confirm
配置值的值;如果未指定,则默认为 auto ,除非指定了任何抑制选项,在这种情况下默认为 _ 组成 _。
--dry-run
做任何事情,除了实际发送电子邮件。
代码语言:javascript复制 --[no-]format-patch
当参数可以理解为引用或文件名时,选择将其理解为格式补丁参数(--format-patch
)或文件名(--no-format-patch
)。默认情况下,发生此类冲突时,git send-email 将失败。
--quiet
使 git-send-email 更简洁。每封电子邮件一行应该是输出的全部内容。
代码语言:javascript复制 --[no-]validate
对补丁进行健全性检查。目前,验证意味着以下内容:
- 如果存在,则调用 sendemail-validate 钩子(参见 githooks [5] )。
- 除非使用合适的传输编码( auto , base64 或 _ 引用的可打印 _),否则警告包含超过 998 个字符的行;这是由于
www.ietf.org/rfc/rfc5322.txt
所描述的 SMTP 限制。
默认值是sendemail.validate
的值;如果未设置,则默认为--validate
。
--force
即使安全检查会阻止它,也要发送电子邮件。
信息
代码语言:javascript复制 --dump-aliases
而不是正常操作,从已配置的别名文件中转储速记别名,每行按字母顺序排列一个。请注意,这仅包括别名,而不包括其扩展的电子邮件地址。有关别名的更多信息,请参见 _sendemail.aliases 文件 _。
组态
代码语言:javascript复制 sendemail.aliasesFile
要避免键入长电子邮件地址,请将其指向一个或多个电子邮件别名文件。您还必须提供sendemail.aliasFileType
。
sendemail.aliasFileType
sendemail.aliasesFile 中指定的文件格式。必须是 mutt , mailrc , pine , elm 或 gnus 或 _sendmail 之一 _。
可以在同名电子邮件程序的文档中找到每种格式的别名文件。标准格式的差异和限制如下所述:
代码语言:javascript复制 sendmail
- 不支持引用的别名和引用地址:忽略包含
"
符号的行。 - 不支持重定向到文件(
/path/name
)或管道(|command
)。 - 不支持文件包含(
:include: /path/name
)。 - 对于任何明确不受支持的构造以及解析器无法识别的任何其他行,标准错误输出上会显示警告。
sendemail.multiEdit
如果为 true(默认),将生成单个编辑器实例以编辑您必须编辑的文件(使用--annotate
时的补丁,以及使用--compose
时的摘要)。如果为 false,将逐个编辑文件,每次生成一个新的编辑器。
sendemail.confirm
设置发送前是否确认的默认值。必须是 _ 始终 , 永远 , cc , 组成 _ 或 auto 之一。有关这些值的含义,请参见上一节中的--confirm
。
例子
使用 gmail 作为 smtp 服务器
要使用 git send-email 通过 GMail SMTP 服务器发送补丁,请编辑〜/ .gitconfig 以指定您的帐户设置:
代码语言:javascript复制[sendemail]
smtpEncryption = tls
smtpServer = smtp.gmail.com
smtpUser = yourname@gmail.com
smtpServerPort = 587
如果您的 Gmail 帐户上有多重身份验证设置,则需要生成一个特定于应用程序的密码,以便与 git send-email 一起使用。访问 security.google.com/settings/security/apppasswords
进行创建。
一旦您的提交准备好发送到邮件列表,请运行以下命令:
代码语言:javascript复制$ git format-patch --cover-letter -M origin/master -o outgoing/
$ edit outgoing/0000-*
$ git send-email outgoing/*
第一次运行它时,系统将提示您输入凭据。根据需要输入特定于应用程序或常规密码。如果您配置了凭证帮助程序(请参阅 git-credential [1] ),密码将保存在凭证存储中,因此您不必在下次输入密码。
注意:以下 perl 模块需要 Net :: SMTP :: SSL,MIME :: Base64 和 Authen :: SASL
也可以看看
git-format-patch [1] , git-imap-send [1] ,mbox(5)
GIT
部分 git [1] 套件
git-request-pull
原文:
git-scm.com/docs/git-request-pull
名称
git-request-pull - 生成挂起更改的摘要
概要
代码语言:javascript复制git request-pull [-p] <start> <url> [<end>]
描述
生成一个请求,要求您的上游项目将更改提取到其树中。打印到标准输出的请求从分支描述开始,总结了更改并指示它们可以从哪里拉出。
上游项目应该具有<start>
命名的提交,并且输出要求它通过访问由<url>
命名的存储库来集成自提交以来所做的更改,直到<end>
命名的提交。
OPTIONS
代码语言:javascript复制 -p
在输出中包含补丁文本。
代码语言:javascript复制 <start>
承诺开始。这将命名已在上游历史记录中的提交。
代码语言:javascript复制 <url>
要从中提取的存储库 URL。
代码语言:javascript复制 <end>
承诺结束于(默认为 HEAD)。这会在您要求提取的历史记录的末尾命名提交。
当<url>
命名的存储库在 ref 的一端提交与本地的 ref 不同时,可以使用<local>:<remote>
语法,使其本地名称为冒号:
,并且远程名称。
例子
想象一下,您在v1.0
版本之上的master
分支上构建了您的工作,并希望将其集成到项目中。首先,您将该更改推送到您的公共存储库,供其他人查看:
git push https://git.ko.xz/project master
然后,运行以下命令:
代码语言:javascript复制git request-pull v1.0 https://git.ko.xz/project master
它将向上游发出请求,总结v1.0
版本和master
之间的变化,从公共存储库中提取它。
如果您将更改推送到名称与本地名称不同的分支,例如
代码语言:javascript复制git push https://git.ko.xz/project master:for-linus
然后你可以要求被拉
代码语言:javascript复制git request-pull v1.0 https://git.ko.xz/project master:for-linus
GIT
部分 git [1] 套件
git-svn
原文:
git-scm.com/docs/git-svn
名称
git-svn - Subversion 存储库和 Git 之间的双向操作
概要
代码语言:javascript复制git svn <command> [<options>] [<arguments>]
描述
git svn 是 Subversion 和 Git 之间变更集的简单管道。它提供 Subversion 和 Git 存储库之间的双向变化流。
git svn 可以使用–stdlayout 选项跟踪常见的“trunk / branches / tags”布局的标准 Subversion 存储库。它还可以使用-T / -t / -b 选项跟随任何布局中的分支和标签(请参阅下面的 init 选项,以及 clone 命令)。
一旦跟踪 Subversion 存储库(使用上述任何方法),就可以通过 fetch 命令从 Subversion 更新 Git 存储库,并通过 dcommit 命令从 Git 更新 Subversion。
COMMANDS
代码语言:javascript复制 init
使用 git svn 的其他元数据目录初始化一个空的 Git 存储库。 Subversion URL 可以指定为命令行参数,也可以指定为-T / -t / -b 的完整 URL 参数。可选地,可以将要操作的目标目录指定为第二个参数。通常,此命令初始化当前目录。
代码语言:javascript复制 -T<trunk_subdir>
代码语言:javascript复制 --trunk=<trunk_subdir>
代码语言:javascript复制 -t<tags_subdir>
代码语言:javascript复制 --tags=<tags_subdir>
代码语言:javascript复制 -b<branches_subdir>
代码语言:javascript复制 --branches=<branches_subdir>
代码语言:javascript复制 -s
代码语言:javascript复制 --stdlayout
这些是 init 的可选命令行选项。这些标志中的每一个都可以指向相对存储库路径(–tags = project / tags)或完整 URL(–tags = https://foo.org/project/tags)。如果您的 Subversion 存储库在多个路径下放置标记或分支,您可以指定多个–tags 和/或–branches 选项。选项–stdlayout 是将 trunk,tags,branches 设置为相对路径的简便方法,这是 Subversion 的默认设置。如果同时给出任何其他选项,则它们优先。
代码语言:javascript复制 --no-metadata
在[svn-remote]配置中设置 noMetadata 选项。建议不要使用此选项,请在使用此选项之前阅读本联机帮助页的 svn.noMetadata 部分。
代码语言:javascript复制 --use-svm-props
在[svn-remote]配置中设置 useSvmProps 选项。
代码语言:javascript复制 --use-svnsync-props
在[svn-remote]配置中设置 useSvnsyncProps 选项。
代码语言:javascript复制 --rewrite-root=<URL>
在[svn-remote]配置中设置 rewriteRoot 选项。
代码语言:javascript复制 --rewrite-uuid=<UUID>
在[svn-remote]配置中设置 rewriteUUID 选项。
代码语言:javascript复制 --username=<user>
对于 SVN 处理(http,https 和 plain svn)身份验证的传输,请指定用户名。对于其他传输(例如svn ssh://
),您必须在 URL 中包含用户名,例如svn ssh://foo@svn.bar.com/project
--prefix=<prefix>
如果指定了 trunk / branches / tags,则允许指定前缀为遥控器名称的前缀。前缀不会自动包含尾部斜杠,因此请确保在参数中包含一个前缀,如果这是您想要的。如果指定了–branches / -b,则前缀必须包含尾部斜杠。在任何情况下都强烈建议设置前缀(带斜杠),因为你的 SVN 跟踪引用将位于“refs / remotes / prefix / ”,这与 Git 自己的远程跟踪引用兼容 layout(refs / remotes / remote / )。如果要跟踪共享公共存储库的多个项目,则设置前缀也很有用。默认情况下,前缀设置为 origin / 。
| 注意 | 在 Git v2.0 之前,默认前缀是“”(没有前缀)。这意味着 SVN 跟踪引用被放在“refs / remotes / *”,这与 Git 自己的远程跟踪引用的组织方式不兼容。如果您仍然需要旧的默认值,可以通过在命令行上传递--prefix ""
来获取它(如果你的 Perl 的 Getopt :: Long 是< v2.37,--prefix=""
可能不起作用)。 |
--ignore-refs=<regex>
传递给 init 或 clone 时,此正则表达式将作为配置键保留。有关--ignore-refs
的说明,请参见 fetch 。
--ignore-paths=<regex>
传递给 init 或 clone 时,此正则表达式将作为配置键保留。有关--ignore-paths
的说明,请参见 fetch 。
--include-paths=<regex>
传递给 init 或 clone 时,此正则表达式将作为配置键保留。有关--include-paths
的说明,请参见 fetch 。
--no-minimize-url
当跟踪多个目录(使用–stdlayout, - blank 或–tags 选项)时,git svn 将尝试连接到 Subversion 存储库的根目录(或允许的最高级别)。如果整个项目在存储库中移动,则此默认设置允许更好地跟踪历史记录,但可能会导致读取访问限制到位的存储库出现问题。传递--no-minimize-url
将允许 git svn 按原样接受 URL,而不尝试连接到更高级别的目录。默认情况下,当仅跟踪一个 URL /分支时,此选项处于关闭状态(这样做不太好)。
fetch
从我们正在跟踪的 Subversion 远程获取未经修改的修订。 $ GIT_DIR / config 文件中[svn-remote“…”]部分的名称可以指定为可选的命令行参数。
如果需要,这会自动更新 rev_map(有关详细信息,请参阅下面的 FILES 部分中的 $ GIT_DIR / svn / * * /。rev_map。* )。
代码语言:javascript复制 --localtime
将 Git 提交时间存储在本地时区而不是 UTC 中。这使 git log (即使没有–date = local)显示与svn log
在本地时区相同的时间。
这不会干扰与您克隆的 Subversion 存储库的互操作,但如果您希望本地 Git 存储库能够与其他人的本地 Git 存储库进行互操作,请不要使用此选项,或者您应该同时使用它同一个当地时区。
代码语言:javascript复制 --parent
仅从当前 HEAD 的 SVN 父级获取。
代码语言:javascript复制 --ignore-refs=<regex>
忽略与 Perl 正则表达式匹配的分支或标记的引用。像^refs/remotes/origin/(?!tags/wanted-tag|wanted-branch).*$
这样的“负前瞻断言”可用于仅允许某些参考。
config key: svn-remote.<name>.ignore-refs
如果设置了 ignore-refs 配置键,并且还给出了命令行选项,则将使用两个正则表达式。
代码语言:javascript复制 --ignore-paths=<regex>
这允许指定 Perl 正则表达式,该表达式将导致从 SVN 的 checkout 跳过所有匹配路径。 --ignore-paths
选项应匹配每个 fetch (包括 _ 克隆 _, dcommit , rebase 等)的自动提取)给定存储库。
config key: svn-remote.<name>.ignore-paths
如果设置了 ignore-paths 配置密钥,并且还给出了命令行选项,则将使用两个正则表达式。
例子:
代码语言:javascript复制 Skip "doc*" directory for every fetch
代码语言:javascript复制--ignore-paths="^doc"
代码语言:javascript复制 Skip "branches" and "tags" of first level directories
代码语言:javascript复制--ignore-paths="^[^/] /(?:branches|tags)"
代码语言:javascript复制 --include-paths=<regex>
这允许指定一个 Perl 正则表达式,该表达式将仅包含来自 SVN 的 checkout 的匹配路径。 --include-paths
选项应匹配每个 fetch (包括 _ 克隆 _, dcommit , rebase 等)的自动提取)给定存储库。 --ignore-paths
优先于--include-paths
。
config key: svn-remote.<name>.include-paths
代码语言:javascript复制 --log-window-size=<n>
获取< n>扫描 Subversion 历史记录时每个请求的日志条目。默认值为 100.对于非常大的 Subversion 存储库, clone / fetch 可能需要更大的值才能在合理的时间内完成。但过大的值可能会导致更高的内存使用量和请求超时。
代码语言:javascript复制 clone
运行 init 和 _ 获取 _。它将根据传递给它的 URL 的基名自动创建一个目录;或者如果第二个论点通过;它将创建一个目录并在其中工作。它接受 init 和 fetch 命令接受的所有参数; --fetch-all
和--parent
除外。克隆存储库后, fetch 命令将能够在不影响工作树的情况下更新修订版;并且 rebase 命令将能够使用最新更改更新工作树。
--preserve-empty-dirs
在本地 Git 存储库中为从 Subversion 获取的每个空目录创建一个占位符文件。这包括通过删除 Subversion 存储库中的所有条目(但不是目录本身)而变为空的目录。不再需要时,也会跟踪和删除占位符文件。
代码语言:javascript复制 --placeholder-filename=<filename>
设置–preserve-empty-dirs 创建的占位符文件的名称。默认值:“。gitignore”
代码语言:javascript复制 rebase
这将从当前 HEAD 的 SVN 父级获取修订,并针对它重新定义当前(未提交到 SVN)的工作。
这与svn update
或 git pull 类似,只是它保留 git rebase 而不是 git merge 的线性历史,以便于 git 的同意 svn 。
这接受 git svn fetch 和 git rebase 接受的所有选项。但是,--fetch-all
仅从当前[svn-remote]获取,而不是所有[svn-remote]定义。
像 git rebase ;这要求工作树清洁并且没有未提交的更改。
如果需要,这会自动更新 rev_map(有关详细信息,请参阅下面的 FILES 部分中的 $ GIT_DIR / svn / * * /。rev_map。* )。
代码语言:javascript复制 -l
代码语言:javascript复制 --local
不要远程取;仅针对上游 SVN 上次提取的提交运行 git rebase 。
代码语言:javascript复制 dcommit
将每个 diff 从当前分支直接提交到 SVN 存储库,然后 rebase 或 reset(取决于 SVN 和 head 之间是否存在差异)。这将在 SVN 中为 Git 中的每个提交创建一个修订版本。
当可选的 Git 分支名称(或 Git 提交对象名称)被指定为参数时,子命令在指定的分支上工作,而不在当前分支上工作。
使用 dcommit 优于 set-tree (下文)。
代码语言:javascript复制 --no-rebase
提交后,不要改变或重置。
代码语言:javascript复制 --commit-url <URL>
提交此 SVN URL(完整路径)。这旨在允许使用一种传输方法创建的现有 git svn 存储库(例如,用于匿名读取的svn://
或http://
)如果用户稍后被授权访问备用传输方法(例如,用于提交的svn ssh://
或https://
)。
config key: svn-remote.<name>.commiturl
config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
请注意,commiturl 配置密钥的 SVN URL 包括 SVN 分支。如果您想要为整个 SVN 存储库设置提交 URL,请使用 svn-remote。< name> .pushurl。
强烈建议不要将此选项用于任何其他目的(不要问)。
代码语言:javascript复制 --mergeinfo=<mergeinfo>
在 dcommit 期间添加给定的合并信息(例如--mergeinfo="/branches/foo:1-10"
)。所有 svn 服务器版本都可以存储此信息(作为属性),从 1.5 版开始的 svn 客户端可以使用它。要指定来自多个分支的合并信息,请在分支之间使用单个空格字符(--mergeinfo="/branches/foo:1-10 /branches/bar:3,5-6,8"
)
config key: svn.pushmergeinfo
此选项将导致 git-svn 尝试在可能的情况下自动填充 SVN 存储库中的 svn:mergeinfo 属性。目前,这只能在提交非快进合并时才能完成,其中除第一个之外的所有父级已经被推入 SVN。
代码语言:javascript复制 --interactive
要求用户确认应该将补丁集实际发送到 SVN。对于每个补丁,可以回答“是”(接受此补丁),“否”(丢弃此补丁),“全部”(接受所有补丁)或“退出”。
git svn dcommit 如果回答为“no”或“quit”则立即返回,而不向 SVN 提交任何内容。
代码语言:javascript复制 branch
在 SVN 存储库中创建分支。
代码语言:javascript复制 -m
代码语言:javascript复制 --message
允许指定提交消息。
代码语言:javascript复制 -t
代码语言:javascript复制 --tag
使用 tags_subdir 而不是 git svn init 期间指定的 branches_subdir 创建标记。
代码语言:javascript复制 -d<path>
代码语言:javascript复制 --destination=<path>
如果为 init 或 clone 命令提供了多个 - 分支(或–tags)选项,则必须提供您希望的分支(或标记)的位置在 SVN 存储库中创建。 <路径>指定用于创建分支或标记的路径,并且应该与其中一个已配置的分支或标记 refspecs 的左侧模式匹配。您可以使用命令查看这些 refspecs
代码语言:javascript复制git config --get-all svn-remote.<name>.branches
git config --get-all svn-remote.<name>.tags
其中< name>是 init 的-R 选项(默认情况下为“svn”)指定的 SVN 存储库的名称。
代码语言:javascript复制 --username
指定要执行提交的 SVN 用户名。此选项会覆盖 _ 用户名 _ 配置属性。
代码语言:javascript复制 --commit-url
使用指定的 URL 连接到目标 Subversion 存储库。这在源 SVN 存储库是只读的情况下很有用。此选项会覆盖配置属性 commiturl 。
代码语言:javascript复制git config --get-all svn-remote.<name>.commiturl
代码语言:javascript复制 --parents
创建父文件夹。此参数等效于参数–parents on svn cp 命令,对非标准存储库布局很有用。
代码语言:javascript复制 tag
在 SVN 存储库中创建标记。这是 branch -t 的简写。
代码语言:javascript复制 log
当 svn 用户引用-r / - 版本号时,这应该可以很容易地查找 svn 日志消息。
支持’svn log’的以下功能:
代码语言:javascript复制 -r <n>[:<n>]
代码语言:javascript复制 --revision=<n>[:<n>]
支持,非数字 args 不是:HEAD,NEXT,BASE,PREV 等…
代码语言:javascript复制 -v
代码语言:javascript复制 --verbose
它与 svn log 中的–verbose 输出不完全兼容,但相当接近。
代码语言:javascript复制 --limit=<n>
与–max-count 不同,不计算合并/排除的提交
代码语言:javascript复制 --incremental
支持的
新功能:
代码语言:javascript复制 --show-commit
还显示了 Git commit sha1
代码语言:javascript复制 --oneline
我们的版本–pretty = oneline
| 注意 | SVN 本身只存储 UTC 时间,没有别的。常规 svn 客户端将 UTC 时间转换为本地时间(或基于 TZ =环境)。此命令具有相同的行为。 |
任何其他参数直接传递给 git log
代码语言:javascript复制 blame
显示修订版和作者上次修改文件的每一行。默认情况下,此模式的输出与’svn blame’的输出格式兼容。与 SVN blame 命令一样,忽略工作树中的本地未提交更改; HEAD 修订版中的文件版本已注释。未知参数直接传递给 git blame 。
代码语言:javascript复制 --git-format
以与 git blame 相同的格式生成输出,但使用 SVN 修订号而不是 Git 提交哈希值。在此模式下,尚未提交到 SVN 的更改(包括本地工作副本编辑)显示为修订版 0。
代码语言:javascript复制 find-rev
当给定形式为 rN 的 SVN 修订号时,返回相应的 Git 提交哈希(这可以选择后跟树,以指定应搜索哪个分支)。给定 tree-ish 时,返回相应的 SVN 修订号。
代码语言:javascript复制 -B
代码语言:javascript复制 --before
如果给出 SVN 修订版,则不需要完全匹配,而是在指定的修订版中找到与 SVN 存储库(在当前分支上)的状态相对应的提交。
代码语言:javascript复制 -A
代码语言:javascript复制 --after
如果给出 SVN 修订版,则不要求完全匹配;如果没有完全匹配,则返回在历史记录中向前搜索的最接近的匹配。
代码语言:javascript复制 set-tree
您应该考虑使用 dcommit 而不是此命令。将指定的提交或树对象提交给 SVN。这取决于您导入的获取数据是最新的。这使得在提交 SVN 时绝对不会尝试进行修补,它只是用树中指定的文件或提交覆盖文件。假设所有合并都独立于 git svn 功能发生。
代码语言:javascript复制 create-ignore
递归地在目录上找到 svn:ignore 属性并创建匹配的.gitignore 文件。生成的文件将暂存,但未提交。使用-r / - revision 来引用特定的修订版。
代码语言:javascript复制 show-ignore
递归查找并列出目录上的 svn:ignore 属性。输出适合附加到$ GIT_DIR / info / exclude 文件。
代码语言:javascript复制 mkdirs
尝试根据$ GIT_DIR / svn /< refname> /unhandled.log 文件中的信息重新创建核心 Git 无法跟踪的空目录。使用“git svn clone”和“git svn rebase”时会自动重新创建空目录,因此“mkdirs”适用于“git checkout”或“git reset”之类的命令。 (有关详细信息,请参阅 svn-remote。< name> .automkdirs 配置文件选项。)
代码语言:javascript复制 commit-diff
从命令行提交两个 tree-ish 参数的 diff。此命令不依赖于git svn init
-ed 存储库。该命令有三个参数,(a)要反对的原始树,(b)新的树结果,(c)目标 Subversion 存储库的 URL。如果您使用的是 git svn -aware 存储库(已经init
与 git svn 一起使用),则可以省略最终参数(URL)。 -r< revision>此选项是必需的。
提交消息直接使用-m
或-F
选项提供,或者在第二个 tree-ish 表示此类对象时间接提供标记或提交,或者通过调用编辑器请求提交消息(请参阅--edit
选项)下面)。
-m <msg>
代码语言:javascript复制 --message=<msg>
使用给定的msg
作为提交消息。此选项禁用--edit
选项。
-F <filename>
代码语言:javascript复制 --file=<filename>
从给定文件中获取提交消息。此选项禁用--edit
选项。
info
显示与“svn info”提供的文件或目录类似的信息。目前不支持-r / - revision 参数。使用–url 选项仅输出 URL: 字段的值。
代码语言:javascript复制 proplist
列出存储在 Subversion 存储库中的有关给定文件或目录的属性。使用-r / - revision 来引用特定的 Subversion 修订版。
代码语言:javascript复制 propget
获取作为文件的第一个参数给出的 Subversion 属性。可以使用-r / - revision 指定特定修订。
代码语言:javascript复制 propset
将作为第一个参数给出的 Subversion 属性设置为作为第三个参数给出的文件的第二个参数给出的值。
例:
代码语言:javascript复制git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile
这将为文件 devel / py-tipper / Makefile 设置属性 svn:keywords 到 FreeBSD =%H 。
代码语言:javascript复制 show-externals
显示 Subversion 外部。使用-r / - revision 指定特定修订。
代码语言:javascript复制 gc
压缩 GIT_DIR / svn /< refname> /unhandled.log 文件并删除
代码语言:javascript复制 reset
将 fetch 的效果撤消回指定的修订版。这允许您重新 _ 获取 _ SVN 修订版。通常,SVN 修订版的内容永远不会改变,并且 _ 重置 _ 不应该是必需的。但是,如果 SVN 权限发生更改,或者您更改了–ignore-paths 选项,则 fetch 可能会失败,并且“未在提交中找到”(文件以前未显示)或“校验和不匹配”(错过了修改)。如果问题文件永远不能被忽略(使用–ignore-paths)修复 repo 的唯一方法是使用 reset 。
仅更改了 rev_map 和 refs / remotes / git-svn(有关详细信息,请参阅下面 FILES 部分中的 $ GIT_DIR / svn / * * /。rev_map。* )。使用 fetch 然后 git reset 或 git rebase 关注 _ 重置 _,将本地分支移动到新树上。
代码语言:javascript复制 -r <n>
代码语言:javascript复制 --revision=<n>
指定要保留的最新修订。所有后来的修订都被丢弃了。
代码语言:javascript复制 -p
代码语言:javascript复制 --parent
同时丢弃指定的修订版,保留最近的父版本。
代码语言:javascript复制 Example:
假设您在“master”中有本地更改,但您需要重新获取“r2”。
代码语言:javascript复制 r1---r2---r3 remotes/git-svn
A---B master
修复了忽略路径或 SVN 权限问题,导致“r2”首先不完整。然后:
代码语言:javascript复制git svn reset -r2 -p
git svn fetch
代码语言:javascript复制 r1---r2'--r3' remotes/git-svn
r2---r3---A---B master
然后使用 git rebase 修复“master”。不要使用 git merge 或者您的历史记录将与以后的 dcommit 不兼容!
代码语言:javascript复制git rebase --onto remotes/git-svn A^ master
代码语言:javascript复制 r1---r2'--r3' remotes/git-svn
A'--B' master
OPTIONS
代码语言:javascript复制 --shared[=(false|true|umask|group|all|world|everybody)]
代码语言:javascript复制 --template=<template_directory>
仅用于 init 命令。这些直接传递给 git init 。
代码语言:javascript复制 -r <arg>
代码语言:javascript复制 --revision <arg>
与 fetch 命令一起使用。
这允许支持部分/烧灼历史的修订范围。 NUMBER, NUMBER1: NUMBER2(数字范围), NUMBER:HEAD 和 BASE:
这可以让你在运行 fetch 时制作部分镜像;但通常不推荐,因为历史将被跳过和丢失。
代码语言:javascript复制 -
代码语言:javascript复制 --stdin
仅用于 set-tree 命令。
从 stdin 读取提交列表并以相反的顺序提交它们。只从每一行读取前导 sha1,因此可以使用 git rev-list --pretty = oneline 输出。
代码语言:javascript复制 --rmdir
仅用于 dcommit , set-tree 和 commit-diff 命令。
如果没有留下文件,则从 SVN 树中删除目录。 SVN 可以对空目录进行编辑,如果没有文件,则默认情况下不会删除它们。 Git 无法对空目录进行版本控制。启用此标志将使提交到 SVN 的行为与 Git 相同。
代码语言:javascript复制config key: svn.rmdir
代码语言:javascript复制 -e
代码语言:javascript复制 --edit
仅用于 dcommit , set-tree 和 commit-diff 命令。
在提交 SVN 之前编辑提交消息。对于提交的对象,默认情况下处于关闭状态,并且在提交树对象时强制关闭。
代码语言:javascript复制config key: svn.edit
代码语言:javascript复制 -l<num>
代码语言:javascript复制 --find-copies-harder
仅用于 dcommit , set-tree 和 commit-diff 命令。
它们都直接传递给 git diff-tree ;有关详细信息,请参阅 git-diff-tree [1] 。
代码语言:javascript复制config key: svn.l
config key: svn.findcopiesharder
代码语言:javascript复制 -A<filename>
代码语言:javascript复制 --authors-file=<filename>
语法与 git cvsimport 使用的文件兼容,但 <>可以提供空的电子邮件地址。 :
代码语言:javascript复制 loginname = Joe User <user@example.com>
如果指定了此选项并且 git svn 遇到作者文件中不存在的 SVN 提交者名称, git svn 将中止操作。然后,用户必须添加适当的条目。修改 authors 文件后重新运行以前的 git svn 命令应继续操作。
代码语言:javascript复制config key: svn.authorsfile
代码语言:javascript复制 --authors-prog=<filename>
如果指定了此选项,则对于 authors 文件中不存在的每个 SVN 提交者名称,将使用提交者名称作为第一个参数执行给定文件。该程序预计将返回“Name< email>”形式的单行或“名称<>”,将被视为包含在作者文件中。
由于历史原因,首先相对于 init 和 clone 的当前目录搜索相对 _ 文件名 _ 并且相对于 _ 的工作树的根目录获取 _。如果找不到 _ 文件名 _,则会像 $ PATH 中的任何其他命令一样进行搜索。
代码语言:javascript复制config key: svn.authorsProg
代码语言:javascript复制 -q
代码语言:javascript复制 --quiet
使 git svn 不那么冗长。再次指定使其更简洁。
代码语言:javascript复制 -m
代码语言:javascript复制 --merge
代码语言:javascript复制 -s<strategy>
代码语言:javascript复制 --strategy=<strategy>
代码语言:javascript复制 -p
代码语言:javascript复制 --preserve-merges
这些仅用于 dcommit 和 rebase 命令。
当使用 dcommit 时,如果不能使用 git reset ,则直接传递给 git rebase (参见 dcommit )。
代码语言:javascript复制 -n
代码语言:javascript复制 --dry-run
这可以与 dcommit , rebase ,_ 分支 _ 和 _ 标签 _ 命令一起使用。
对于 dcommit ,打印出一系列 Git 参数,这些参数将显示哪些差异将被提交给 SVN。
对于 rebase ,显示与当前分支关联的上游 svn 存储库关联的本地分支以及将从中获取的 svn 存储库的 URL。
对于 _ 分支 _ 和 _ 标签 _,显示创建分支或标记时将用于复制的 URL。
代码语言:javascript复制 --use-log-author
当检索 svn 提交到 Git 中时(作为 fetch , rebase 或 dcommit 操作)的一部分,查找第一个From:
或Signed-off-by:
行日志消息并将其用作作者字符串。
config key: svn.useLogAuthor
代码语言:javascript复制 --add-author-from
当从 Git 提交 svn 时(作为 set-tree 或 dcommit 操作的一部分),如果现有的日志消息还没有From:
或Signed-off-by:
行,根据 Git 提交的作者字符串附加From:
行。如果您使用此,则--use-log-author
将为所有提交检索有效的作者字符串。
config key: svn.addAuthorFrom
高级选项
代码语言:javascript复制 -i<GIT_SVN_ID>
代码语言:javascript复制 --id <GIT_SVN_ID>
这设置了 GIT_SVN_ID(而不是使用环境)。这允许用户在跟踪单个 URL 时覆盖默认的 refname 以从中获取。 log 和 dcommit 命令不再需要此开关作为参数。
代码语言:javascript复制 -R<remote name>
代码语言:javascript复制 --svn-remote <remote name>
指定要使用的[svn-remote“< remote name>”]部分,这允许跟踪 SVN 多个存储库。默认值:“svn”
代码语言:javascript复制 --follow-parent
此选项仅在我们跟踪分支时使用(使用其中一个存储库布局选项–trunk, - label, - blank, - stdlayout)。对于每个跟踪的分支,尝试找出其修订版本的位置,并在分支的第一个 Git 提交中设置合适的父代。当我们跟踪已在存储库中移动的目录时,这尤其有用。如果禁用此功能, git svn 创建的分支将全部为线性且不共享任何历史记录,这意味着没有关于分支分支或合并的信息。但是,长时间/错综复杂的历史记录可能需要很长时间,因此禁用此功能可能会加快克隆过程。默认情况下启用此功能,使用–no-follow-parent 禁用它。
代码语言:javascript复制config key: svn.followparent
配置文件选项
代码语言:javascript复制 svn.noMetadata
代码语言:javascript复制 svn-remote.<name>.noMetadata
这会在每次提交结束时删除 git-svn-id: 行。
此选项只能用于一次性导入,因为 git svn 无法在没有元数据的情况下再次获取。另外,如果你丢失 $ GIT_DIR / svn / * * /。rev_map。* 文件, git svn 将无法重建它们。
git svn log 命令也不能在使用它的存储库上工作。使用这与 useSvmProps 选项冲突(希望)显而易见的原因。
建议不要使用此选项,因为这样很难在现有文档,错误报告和存档中跟踪对 SVN 修订号的旧引用。如果您计划最终从 SVN 迁移到 Git 并确定要删除 SVN 历史记录,请考虑 git-filter-branch [1] 。 filter-branch 还允许重新格式化元数据,以便于阅读和重写非“svn.authorsFile”用户的作者信息。
代码语言:javascript复制 svn.useSvmProps
代码语言:javascript复制 svn-remote.<name>.useSvmProps
这允许 git svn 从使用 SVN :: Mirror(或 svk)为元数据创建的镜像重新映射存储库 URL 和 UUID。
如果 SVN 修订版具有属性“svm:headrev”,则修订版很可能是由 SVN :: Mirror 创建的(也是 SVK 使用的)。该属性包含存储库 UUID 和修订版。我们希望看起来像是在镜像原始 URL,因此引入一个辅助函数,它返回原始标识 URL 和 UUID,并在提交消息中生成元数据时使用它。
代码语言:javascript复制 svn.useSvnsyncProps
代码语言:javascript复制 svn-remote.<name>.useSvnsyncprops
与 useSvmProps 选项类似;这适用于随 SVN 1.4.x 及更高版本一起发布的 svnsync(1)命令的用户。
代码语言:javascript复制 svn-remote.<name>.rewriteRoot
这允许用户从备用 URL 创建存储库。例如,管理员可以在本地服务器上运行 git svn (通过 file:// 访问)但希望使用公共 http://或 svn:/分发存储库/元数据中的 URL,以便用户看到公共 URL。
代码语言:javascript复制 svn-remote.<name>.rewriteUUID
与 useSvmProps 选项类似;这适用于需要手动重新映射 UUID 的用户。在通过 useSvmProps 或 useSvnsyncProps 无法使用原始 UUID 的情况下,这可能很有用。
代码语言:javascript复制 svn-remote.<name>.pushurl
与 Git 的remote.<name>.pushurl
类似,此密钥设计用于 url 通过只读传输指向 SVN 存储库的情况,以提供备用读/写传输。假设两个键都指向同一个存储库。与 commiturl 不同, pushurl 是基本路径。如果可以使用 commiturl 或 pushurl , commiturl 优先。
svn.brokenSymlinkWorkaround
这会禁用可能昂贵的检查,以解决由损坏的客户端检入 SVN 的损坏的符号链接。如果跟踪具有许多非符号链接的空 blob 的 SVN 存储库,请将此选项设置为“false”。当 git svn 正在运行时,此选项可能会更改,并在下一个修订版本生效时生效。如果未设置, git svn 假定此选项为“true”。
代码语言:javascript复制 svn.pathnameencoding
这指示 git svn 将路径名重新编码为给定的编码。它可以被 Windows 用户和非 utf8 语言环境中的用户使用,以避免使用非 ASCII 字符损坏文件名。有效编码是 Perl 的 Encode 模块支持的编码。
代码语言:javascript复制 svn-remote.<name>.automkdirs
通常,“git svn clone”和“git svn rebase”命令会尝试重新创建 Subversion 存储库中的空目录。如果此选项设置为“false”,则只有在显式运行“git svn mkdirs”命令时才会创建空目录。如果未设置, git svn 假定此选项为“true”。
由于 noMetadata,rewriteRoot,rewriteUUID,useSvnsyncProps 和 useSvmProps 选项都会影响 git svn 生成和使用的元数据;在导入任何历史记录之前,它们必须在配置文件中设置,并且一旦设置这些设置就不应该更改。
此外,每个 svn-remote 部分只能使用其中一个选项,因为它们会影响 git-svn-id: 元数据行,但可以一起使用的 rewriteRoot 和 rewriteUUID 除外。
基本实例
跟踪并贡献 Subversion 管理项目的主干(忽略标签和分支):
代码语言:javascript复制# Clone a repo (like git clone):
git svn clone http://svn.example.com/project/trunk
# Enter the newly cloned directory:
cd trunk
# You should be on master branch, double-check with 'git branch'
git branch
# Do some work and commit locally to Git:
git commit ...
# Something is committed to SVN, rebase your local changes against the
# latest changes in SVN:
git svn rebase
# Now commit your changes (that were committed previously using Git) to SVN,
# as well as automatically updating your working HEAD:
git svn dcommit
# Append svn:ignore settings to the default Git exclude file:
git svn show-ignore >> .git/info/exclude
跟踪并贡献整个 Subversion 管理的项目(包括主干,标签和分支):
代码语言:javascript复制# Clone a repo with standard SVN directory layout (like git clone):
git svn clone http://svn.example.com/project --stdlayout --prefix svn/
# Or, if the repo uses a non-standard directory layout:
git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/
# View all branches and tags you have cloned:
git branch -r
# Create a new branch in SVN
git svn branch waldo
# Reset your master to trunk (or any other branch, replacing 'trunk'
# with the appropriate name):
git reset --hard svn/trunk
# You may only dcommit to one branch/tag/trunk at a time. The usage
# of dcommit/rebase/show-ignore should be the same as above.
最初的 git svn clone 可能非常耗时(特别是对于大型 Subversion 存储库)。如果多个人(或一个拥有多台机器的人)想要使用 git svn 与同一个 Subversion 存储库进行交互,您可以将初始 git svn clone 作为服务器上的存储库让每个人用 git clone 克隆该存储库:
代码语言:javascript复制# Do the initial import on a server
ssh server "cd /pub && git svn clone http://svn.example.com/project [options...]"
# Clone locally - make sure the refs/remotes/ space matches the server
mkdir project
cd project
git init
git remote add origin server:/pub/project
git config --replace-all remote.origin.fetch ' refs/remotes/*:refs/remotes/*'
git fetch
# Prevent fetch/pull from remote Git server in the future,
# we only want to use git svn for future updates
git config --remove-section remote.origin
# Create a local branch from one of the branches just fetched
git checkout -b master FETCH_HEAD
# Initialize 'git svn' locally (be sure to use the same URL and
# --stdlayout/-T/-b/-t/--prefix options as were used on server)
git svn init http://svn.example.com/project [options...]
# Pull the latest changes from Subversion
git svn rebase
REBASE VS. PULL / MERGE
更喜欢使用 git svn rebase 或 git rebase ,而不是 git pull 或 git merge 来同步未整合的提交与 git svn 分支。这样做将使未集成提交的历史相对于上游 SVN 存储库保持线性,并允许使用首选 git svn dcommit 子命令将未集成的提交推送回 SVN。
最初, git svn 建议开发人员从 git svn 分支中撤出或合并。这是因为作者赞成git svn set-tree B
提交单个头而不是git svn set-tree A..B
符号来提交多个提交。使用 git pull 或 git merge 和git svn set-tree A..B
将导致非线性历史记录在提交到 SVN 时被平铺,这可能导致合并提交意外地反转 SVN 中的先前提交。
合并跟踪
虽然 git svn 可以跟踪采用标准布局的存储库的复制历史记录(包括分支和标记),但它还不能代表 git 内部发生在 SVN 用户上游的合并历史记录。因此,建议用户在 Git 内尽可能保持历史记录,以便于与 SVN 兼容(参见下面的 CAVEATS 部分)。
处理 SVN 分支机构
如果 git svn 配置为获取分支(并且–follow-branches 有效),它有时会为一个 SVN 分支创建多个 Git 分支,其中附加分支的名称为 branchname @nnn (nnn 是 SVN 版本号)。如果 git svn 无法在 SVN 分支中找到第一次提交的父提交,则将分支连接到其他分支的历史记录,从而创建这些附加分支。
通常,SVN 分支中的第一次提交包括复制操作。 git svn 将读取此提交以获取创建分支的 SVN 修订版。然后,它将尝试查找与此 SVN 修订版对应的 Git 提交,并将其用作分支的父级。但是,可能没有合适的 Git 提交作为父级。除其他原因外,如果 SVN 分支是 git svn 未提取的修订版本的副本(例如因为它是--revision
跳过的旧版本),或者如果在 SVN 中,复制了一个未被 git svn 跟踪的目录(例如根本没有跟踪的分支,或被跟踪分支的子目录)。在这些情况下, git svn 仍然会创建一个 Git 分支,但它不会使用现有的 Git 提交作为分支的父级,而是会读取分支从中复制的目录的 SVN 历史记录并创建适当的 Git 提交。这由消息“初始化父:< branchname>”表示。
此外,它将创建一个名为 < branchname> @< SVN-Revision>的特殊分支。 ,其中< SVN-Revision>是从中复制分支的 SVN 修订版号。该分支将指向新创建的分支的父提交。如果在 SVN 中分支被删除并且稍后从不同版本重新创建,则将存在多个具有 @ 的分支。
请注意,这可能意味着为单个 SVN 修订创建了多个 Git 提交。
例如:在具有标准中继/标签/分支布局的 SVN 存储库中,在 r.100 中创建目录中继/子。在 r.200 中,trunk / sub 通过将其复制到 branches /来分支。 git svn clone -s 然后会创建一个分支 sub 。它还将为 r.100 到 r.199 创建新的 Git 提交,并将它们用作分支 sub 的历史。因此,从 r.100 到 r.199 的每个修订版将有两个 Git 提交(一个包含 trunk /,一个包含 trunk / sub /)。最后,它将创建一个分支 sub @ 200 ,指向分支 sub 的新父提交(即 r.200 和 trunk / sub /的提交)。
CAVEATS
为了简单和与 Subversion 互操作,建议所有 git svn 用户直接从 SVN 服务器克隆,获取和提交,并避免所有 git clone / _ 拉 _ / _ 合并 _ / _ 推送 _ Git 存储库和分支之间的操作。在 Git 分支和用户之间交换代码的推荐方法是 git format-patch 和 git am ,或者只是’dcommit’ing 到 SVN 存储库。
在您计划 dcommit 的分支上不建议运行 git merge 或 git pull ,因为 Subversion 用户无法看到您所做的任何合并。此外,如果您从作为 SVN 分支镜像的 Git 分支合并或拉出, dcommit 可能会提交错误的分支。
如果你合并,请注意以下规则: git svn dcommit 将尝试在名为的 SVN 提交之上提交
代码语言:javascript复制git log --grep=^git-svn-id: --first-parent -1
你 _ 必须 _ 因此确保你想要提交的分支的最新提交是合并的 _ 第一 _ 父。否则会发生混乱,特别是如果第一个父级是同一 SVN 分支上的较旧提交。
git clone 不会在 refs / remotes / hierarchy 或任何 git svn 元数据或 config 下克隆分支。所以使用 git svn 创建和管理的存储库应该使用 rsync 进行克隆,如果要完成克隆的话。
由于 dcommit 内部使用 rebase,任何 Git 分支你 git push 到 dcommit 之前将需要强制覆盖远程存储库上的现有 ref。这通常被认为是不好的做法,详见 git-push [1] 文档。
对于您已经提交的更改,请勿使用 git-commit [1] 的–amend 选项。将 - 已经推送到其他用户的远程存储库提交的提交视为不好的做法,并且与 SVN 的命令类似于此。
克隆 SVN 存储库时,如果没有使用描述存储库布局的选项(–trunk, - targs, - .branches, - stdlayout), git svn clone 将创建一个 Git 存储库具有完全线性历史记录,其中分支和标记在工作副本中显示为单独的目录。虽然这是获取完整存储库副本的最简单方法,但对于具有多个分支的项目,它将导致工作副本比主干大许多倍。因此,对于使用标准目录结构(主干/分支/标签)的项目,建议使用选项--stdlayout
进行克隆。如果项目使用非标准结构,和/或不需要分支和标记,则最简单的方法是仅克隆一个目录(通常是主干),而不提供任何存储库布局选项。如果需要带分支和标签的完整历史记录,则必须使用选项--trunk
/ --branches
/ --tags
。
当使用多个 - 分支或–tags 时, git svn 不会自动处理名称冲突(例如,如果来自不同路径的两个分支具有相同的名称,或者分支和标记具有相同的名称冲突名称)。在这些情况下,使用 init 设置你的 Git 存储库然后,在你的第一个 fetch 之前,编辑$ GIT_DIR / config 文件,以便分支和标签与不同的名称空间相关联。例如:
代码语言:javascript复制branches = stable/*:refs/remotes/svn/stable/*
branches = debug/*:refs/remotes/svn/debug/*
BUGS
我们忽略除 svn:executable 之外的所有 SVN 属性。任何未处理的属性都会记录到$ GIT_DIR / svn /< refname> /unhandled.log
Git 未检测到重命名和复制的目录,因此在提交 SVN 时不会进行跟踪。我不打算为此添加支持,因为为所有可能的极端情况工作是非常困难和耗时的(Git 也没有这样做)。如果它们足够相似,Git 可以检测它们,则完全支持提交重命名和复制的文件。
在 SVN 中,可以(虽然不鼓励)提交对标记的更改(因为标记只是目录副本,因此在技术上与分支相同)。克隆 SVN 存储库时, git svn 无法知道将来是否会发生对标记的提交。因此它保守地运作并将所有 SVN 标签作为分支导入,在标签名称前加上 _ 标签/_ 。
组态
git svn 将[svn-remote]配置信息存储在存储库$ GIT_DIR / config 文件中。它类似于核心 Git [remote]部分,除了 fetch 键不接受 glob 参数;但它们由 _ 分支 _ 和 _ 标签 _ 键处理。由于某些 SVN 存储库奇怪地配置了多个项目,因此允许使用以下列出的扩展:
代码语言:javascript复制[svn-remote "project-a"]
url = http://server.org/svn
fetch = trunk/project-a:refs/remotes/project-a/trunk
branches = branches/*/project-a:refs/remotes/project-a/branches/*
branches = branches/release_*:refs/remotes/project-a/branches/release_*
branches = branches/re*se:refs/remotes/project-a/branches/*
tags = tags/*/project-a:refs/remotes/project-a/tags/*
请记住,本地参考的 * (星号)通配符(: 的右侧)必须是最右边的路径组件;但是远程通配符可以是任何地方,只要它是一个独立的路径组件(由 / 或 EOL 包围)。这种类型的配置不是由 init 自动创建的,应该使用文本编辑器或使用 git config 手动输入。
另请注意,每个单词只允许使用一个星号。例如:
代码语言:javascript复制branches = branches/re*se:refs/remotes/project-a/branches/*
将匹配分支 _ 释放 , 研究 _, re123se ,但
代码语言:javascript复制branches = branches/re*s*e:refs/remotes/project-a/branches/*
会产生错误。
也可以通过在大括号内使用逗号分隔的名称列表来获取分支或标记的子集。例如:
代码语言:javascript复制[svn-remote "huge-project"]
url = http://server.org/svn
fetch = trunk/src:refs/remotes/trunk
branches = branches/{red,green}/src:refs/remotes/project-a/branches/*
tags = tags/{1.0,2.0}/src:refs/remotes/project-a/tags/*
支持多个提取,分支和标记键:
代码语言:javascript复制[svn-remote "messy-repo"]
url = http://server.org/svn
fetch = trunk/project-a:refs/remotes/project-a/trunk
fetch = branches/demos/june-project-a-demo:refs/remotes/project-a/demos/june-demo
branches = branches/server/*:refs/remotes/project-a/branches/*
branches = branches/demos/2011/*:refs/remotes/project-a/2011-demos/*
tags = tags/server/*:refs/remotes/project-a/tags/*
在这样的配置中创建分支需要使用-d 或–destination 标志消除使用哪个位置的歧义:
代码语言:javascript复制$ git svn branch -d branches/server release-2-3-0
请注意,git-svn 会跟踪分支或标记出现的最高版本。如果在获取后更改了分支或标记的子集,则必须手动编辑$ GIT_DIR / svn / .metadata 以根据需要删除(或重置)branches-maxRev 和/或 tags-maxRev。
FILES
代码语言:javascript复制 $GIT_DIR/svn/**/.rev_map.*
Subversion 修订号和 Git 提交名之间的映射。在未设置 noMetadata 选项的存储库中,可以从每次提交结束时的 git-svn-id:行重建(有关详细信息,请参阅上面的 svn.noMetadata 部分)。
git svn fetch 和 git svn rebase 会自动更新 rev_map,如果它丢失或不是最新的。 git svn reset 自动倒带。
也可以看看
git-rebase [1]
GIT
部分 git [1] 套件
git-fast-import
原文:
git-scm.com/docs/git-fast-import
名称
git-fast-import - 快速 Git 数据导入器的后端
概要
代码语言:javascript复制frontend | git fast-import [<options>]
描述
该程序通常不是最终用户想要直接运行的程序。大多数最终用户希望使用现有的前端程序之一,该程序解析特定类型的外部源并将存储在那里的内容提供给 git fast-import 。
fast-import 从标准输入读取混合命令/数据流,并将一个或多个 packfiles 直接写入当前存储库。在标准输入上收到 EOF 时,快速导入会写出更新的分支和标记引用,使用新导入的数据完全更新当前存储库。
快速导入后端本身可以导入到空存储库(已经由 git init 初始化的存储库)或者逐步更新现有的已填充存储库。是否支持来自特定外部源的增量导入取决于正在使用的前端程序。
OPTIONS
代码语言:javascript复制 --force
强制更新已修改的现有分支,即使这样做会导致提交丢失(因为新提交不包含旧提交)。
代码语言:javascript复制 --quiet
禁用–stats 显示的输出,快速导入通常在成功时保持静默。但是,如果导入流具有旨在显示用户输出的指令(例如progress
指令),则仍将显示相应的消息。
--stats
显示有关快速导入已创建的对象,存储它们的包文件以及在此运行期间快速导入所使用的内存的一些基本统计信息。显示此输出目前是默认值,但可以使用–quiet 禁用。
前端的选项
代码语言:javascript复制 --cat-blob-fd=<fd>
将对get-mark
,cat-blob
和ls
查询的响应写入文件描述符< fd>而不是stdout
。允许最终用户的progress
输出与其他输出分开。
--date-format=<fmt>
指定前端将在author
,committer
和tagger
命令中快速导入的日期类型。有关支持哪些格式及其语法的详细信息,请参阅下面的“日期格式”。
--done
如果流末尾没有done
命令,则终止并出错。此选项可用于检测导致前端在开始编写流之前终止的错误。
标记文件的位置
代码语言:javascript复制 --export-marks=<file>
将内部标记表转储到< file>完成后。标记每行写为:markid SHA-1
。前端可以使用此文件在完成导入后验证导入,或者在增量运行中保存标记表。作为< file>仅在检查点(或完成)处打开和截断,同样的路径也可以安全地给予–import-marks。
--import-marks=<file>
在处理任何输入之前,请加载< file>中指定的标记。输入文件必须存在,必须是可读的,并且必须使用与–export-marks 生成的格式相同的格式。可以提供多个选项来导入多组标记。如果标记定义为不同的值,则最后一个文件获胜。
代码语言:javascript复制 --import-marks-if-exists=<file>
像–import-marks 但不是错误输出,如果文件不存在,则以静默方式跳过该文件。
代码语言:javascript复制 --[no-]relative-marks
指定–relative-marks 后,使用–import-marks =和–export-marks =指定的路径相对于当前存储库中的内部目录。在 git-fast-import 中,这意味着路径相对于.git / info / fast-import 目录。但是,其他进口商可能会使用其他位置。
相对和非相对标记可以通过交织 - (无 - ) - 相对标记与 - (import | export)-marks =选项相结合。
性能和压缩调整
代码语言:javascript复制 --active-branches=<n>
一次保持活动的最大分支数。有关详细信息,请参阅下面的“内存使默认值为 5。
代码语言:javascript复制 --big-file-threshold=<n>
快速导入将尝试创建增量的 blob 的最大大小,以字节为单位表示。默认值为 512 米(512 MiB)。一些进口商可能希望在具有受限内存的系统上降低此值。
代码语言:javascript复制 --depth=<n>
最大增量深度,用于 blob 和树木划分。默认值为 50。
代码语言:javascript复制 --export-pack-edges=<file>
创建包文件后,将一行数据打印到< file>列出 packfile 的文件名以及写入该 packfile 的每个分支上的最后一次提交。导入总对象集超过 4 GiB packfile 限制的项目后,此信息可能很有用,因为这些提交可以在调用 git pack-objects 时用作边缘点。
代码语言:javascript复制 --max-pack-size=<n>
每个输出包文件的最大大小。默认值是无限制的。
代码语言:javascript复制 fastimport.unpackLimit
见 git-config [1]
性能
快速导入的设计允许它以最小的内存使用量和处理时间导入大型项目。假设前端能够跟上快速导入并为其提供恒定的数据流,那么拥有 10 年以上历史且包含 100,000 多个单独提交的项目的导入时间通常只需 1-2 小时即可完成( 〜$ 2,000 USD)硬件。
大多数瓶颈似乎是在外部源数据访问(源无法足够快地提取修订版)或磁盘 IO(快速导入写入速度与磁盘将获取数据一样快)。如果源数据存储在与目标 Git 存储库不同的驱动器上(由于较少的 IO 争用),导入将运行得更快。
发展成本
快速导入的典型前端往往占据大约 200 行 Perl / Python / Ruby 代码。大多数开发人员能够在短短几个小时内创建工作进口商,即使这是他们第一次快速导入,有时甚至是 Git。这是一个理想的情况,因为大多数转换工具都是丢弃的(使用一次,永不回头)。
并行操作
像 git push 或 git fetch 一样,快速导入处理的导入可以安全地与并行git repack -a -d
或git gc
调用或任何其他 Git 操作(包括 )一起运行 git prune ,因为松散的对象永远不会被快速导入使用)。
快速导入不会锁定分支或标记引用它正在主动导入。导入之后,在其 ref 更新阶段,快速导入测试每个现有分支 ref 以验证更新将是快进更新(存储在 ref 中的提交包含在要写入的提交的新历史中)。如果更新不是快进更新,则快速导入将跳过更新该 ref,而是打印警告消息。快速导入将始终尝试更新所有分支引用,并且不会在第一次失败时停止。
可以使用–force 强制分支更新,但建议仅在其他安静的存储库上使用它。初始导入空存储库不需要使用–force。
技术讨论
快速导入跟踪内存中的一组分支。通过在输入流上发送commit
命令,可以在导入过程中的任何时刻创建或修改任何分支。此设计允许前端程序同时处理无限数量的分支,按源数据中可用的顺序生成提交。它还大大简化了前端程序。
fast-import 不使用或更改当前工作目录或其中的任何文件。 (但它会更新当前的 Git 存储库,由GIT_DIR
引用。)因此,导入前端可以将工作目录用于其自身目的,例如从外部源提取文件修订。这种对工作目录的无知也允许快速导入非常快速地运行,因为在分支之间切换时不需要执行任何昂贵的文件更新操作。
输入格式
除了原始文件数据(Git 不解释)之外,快速导入输入格式是基于文本(ASCII)的。这种基于文本的格式简化了前端程序的开发和调试,特别是在使用更高级别的语言(如 Perl,Python 或 Ruby)时。
快速导入对其输入非常严格。我们在下面说 SP,我们的意思是正好是一个空格。同样 LF 意味着一个(并且只有一个)换行和 HT 一个(并且只有一个)水平标签。提供额外的空白字符将导致意外结果,例如名称中带有前导或尾随空格的分支名称或文件名,或者遇到意外输入时提前终止快速导入。
流评论
为了帮助调试前端,快速导入忽略以#
(ASCII 磅/散列)开头直到并包括以LF
结束的行的任何行。注释行可以包含不包含 LF 的任何字节序列,因此可以用于包括可能特定于前端的任何详细调试信息,并且在检查快速导入数据流时非常有用。
日期格式
支持以下日期格式。前端应通过在–date-format =< fmt>中传递格式名称来选择将用于此导入的格式。命令行选项。
代码语言:javascript复制 raw
这是 Git 原生格式,是<time> SP <offutc>
。如果未指定–date-format,它也是快速导入的默认格式。
事件的时间由<time>
指定为自 UNIX 纪元(午夜,1970 年 1 月 1 日,UTC)以来的秒数,并写为 ASCII 十进制整数。
本地偏移由<offutc>
指定为 UTC 的正偏移或负偏移。例如,EST(比 UTC 晚 5 小时)将在<tz>
中用“-0500”表示,而 UTC 是“ 0000”。局部偏移不会影响<time>
;它仅用作帮助格式化例程显示时间戳的建议。
如果源材料中没有本地偏移,请使用“ 0000”或最常见的本地偏移。例如,许多组织都有一个 CVS 存储库,该存储库只能由位于相同位置和时区的用户访问。在这种情况下,可以假设与 UTC 的合理偏移。
与rfc2822
格式不同,此格式非常严格。格式的任何变化都会导致快速导入以拒绝该值。
rfc2822
这是 RFC 2822 描述的标准电子邮件格式。
示例值是“Tue Feb 6 11:22:18 2007 -0500”。 Git 解析器是准确的,但在宽松的一面。它是 git am 在应用从电子邮件收到的补丁时使用的解析器。
某些格式错误的字符串可能被接受为有效日期。在某些情况下,Git 仍然可以从格式错误的字符串中获取正确的日期。还有一些类型的格式错误的字符串,Git 会解析错误,但认为有效。严重错误的字符串将被拒绝。
与上面的raw
格式不同,RFC 2822 日期字符串中包含的时区/ UTC 偏移信息用于在存储之前将日期值调整为 UTC。因此,重要的是这些信息应尽可能准确。
如果源材料使用 RFC 2822 样式日期,前端应该让快速导入处理解析和转换(而不是尝试自己做),因为 Git 解析器已在野外进行了很好的测试。
如果源材料已经使用 UNIX-epoch 格式,前端应该更喜欢raw
格式,可以通过哄骗来提供该格式的日期,或者其格式可以轻松转换为格式,因为解析时没有歧义。
now
始终使用当前时间和时区。必须始终为<when>
提供文字now
。
这是一种玩具形式。此系统的当前时间和时区始终在通过快速导入创建时复制到标识字符串中。无法指定不同的时间或时区。
提供此特定格式是因为它很难实现,并且可能对想要立即创建新提交的进程有用,而无需使用工作目录或 git update-index 。
如果在commit
中使用单独的author
和committer
命令,则时间戳可能不匹配,因为系统时钟将被轮询两次(每个命令一次)。确保作者和提交者身份信息具有相同时间戳的唯一方法是省略author
(从而从committer
复制)或使用now
以外的日期格式。
命令
fast-import 接受几个命令来更新当前存储库并控制当前导入过程。稍后将对每个命令进行更详细的讨论(带有示例)。
代码语言:javascript复制 commit
通过创建新提交并更新分支以指向新创建的提交来创建新分支或更新现有分支。
代码语言:javascript复制 tag
从现有提交或分支创建带注释的标记对象。此命令不支持轻量级标记,因为不建议用于记录有意义的时间点。
代码语言:javascript复制 reset
将现有分支(或新分支)重置为特定修订。必须使用此命令将分支更改为特定修订,而不对其进行提交。
代码语言:javascript复制 blob
将原始文件数据转换为 blob,以备将来在commit
命令中使用。此命令是可选的,不需要执行导入。
checkpoint
强制快速导入以关闭当前 packfile,生成其唯一的 SHA-1 校验和和索引,并启动新的 packfile。此命令是可选的,不需要执行导入。
代码语言:javascript复制 progress
导致快速导入以将整行回显到其自己的标准输出。此命令是可选的,不需要执行导入。
代码语言:javascript复制 done
标记流的结尾。除非使用--done
命令行选项或feature done
命令请求done
功能,否则此命令是可选的。
get-mark
导致快速导入将对应于标记的 SHA-1 打印到使用--cat-blob-fd
设置的文件描述符,或者如果未指定则打印stdout
。
cat-blob
导致快速导入将 cat-file --batch 格式的 blob 打印到使用--cat-blob-fd
或stdout
设置的文件描述符(如果未指定)。
ls
导致快速导入将以 ls-tree 格式描述目录条目的行打印到使用--cat-blob-fd
或stdout
设置的文件描述符(如果未指定)。
feature
启用指定的功能。这要求快速导入支持指定的功能,如果不支持则中止。
代码语言:javascript复制 option
指定 OPTIONS 下列出的任何不会更改流语义以满足前端需求的选项。此命令是可选的,不需要执行导入。
commit
使用新提交创建或更新分支,记录对项目的一个逻辑更改。
代码语言:javascript复制 'commit' SP <ref> LF
mark?
original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF
data
('from' SP <commit-ish> LF)?
('merge' SP <commit-ish> LF)?
(filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)*
LF?
其中<ref>
是要进行提交的分支的名称。通常,分支名称在 Git 中以refs/heads/
为前缀,因此导入 CVS 分支符号RELENG-1_0
将使用refs/heads/RELENG-1_0
作为<ref>
的值。 <ref>
的值必须是 Git 中的有效 refname。由于LF
在 Git refname 中无效,因此此处不支持引用或转义语法。
可以选择出现mark
命令,请求快速导入以保存对新创建的提交的引用,以供将来使用(参见下面的格式)。前端标记它们创建的每个提交是很常见的,从而允许从任何导入的提交创建未来的分支。
committer
后面的data
命令必须提供提交消息(参见下面的data
命令语法)。要导入空提交消息,请使用 0 长度数据。提交消息是自由格式的,不由 Git 解释。目前它们必须以 UTF-8 编码,因为快速导入不允许指定其他编码。
可以包括零个或多个filemodify
,filedelete
,filecopy
,filerename
,filedeleteall
和notemodify
命令以在创建提交之前更新分支的内容。可以按任何顺序提供这些命令。但是,建议filemodify
命令在同一次提交中的所有filemodify
,filecopy
,filerename
和notemodify
命令之前,因为filedeleteall
擦除分支清除(见下文)。
命令后的LF
是可选的(以前是必需的)。
author
如果作者信息可能与提交者信息不同,则可以选择显示author
命令。如果省略author
,则 fast-import 将自动使用提交者作者部分的提交者信息。有关author
中字段的说明,请参见下文,因为它们与committer
相同。
committer
committer
命令指示谁进行了此提交,以及何时进行此提交。
这里<name>
是此人的显示名称(例如“Com M Itter”),<email>
是该人的电子邮件地址(“cm@example.com”)。 LT
和GT
是文字小于( x3c)和大于( x3e)的符号。这些是从行中的其他字段分隔电子邮件地址所必需的。注意<name>
和<email>
是自由形式的,可以包含任何字节序列,LT
,GT
和LF
除外。 <name>
通常是 UTF-8 编码的。
更改时间由<when>
使用–date-format =< fmt>选择的日期格式指定。命令行选项。有关支持的格式集及其语法,请参阅上面的“日期格式”。
from
from
命令用于指定从中初始化此分支的提交。此修订将是新提交的第一个祖先。在此提交时构建的树的状态将从from
提交的状态开始,并由此提交中的内容修改进行更改。
在第一次提交新分支时省略from
命令将导致快速导入以创建没有祖先的提交。这通常仅适用于项目的初始提交。如果前端在创建新分支时从头开始创建所有文件,则可以使用merge
命令代替from
以使用空树启动提交。通常需要在现有分支上省略from
命令,因为该分支上的当前提交被自动假定为新提交的第一个祖先。
由于LF
在 Git refname 或 SHA-1 表达式中无效,因此<commit-ish>
中不支持引用或转义语法。
这里<commit-ish>
是以下任何一种:
- 已存在于 fast-import 的内部分支表中的现有分支的名称。如果快速导入不知道名称,则将其视为 SHA-1 表达式。
- 标记参考
:<idnum>
,其中<idnum>
是标记号。 快速导入使用:
表示标记引用的原因是此字符在 Git 分支名称中不合法。前导:
可以很容易地区分标记 42(:42
)和分支 42(42
或refs/heads/42
),或简化的 SHA-1,它恰好只包含 10 位数字。 必须先声明标记(通过mark
)才能使用它们。 - 完整的 40 字节或缩写提交 SHA-1(十六进制)。
- 任何解析为提交的有效 Git SHA-1 表达式。有关详细信息,请参阅 gitrevisions [7] 中的“指定修订”。
- 特殊的空 SHA-1(40 个零)指定要删除分支。
从当前分支值重新启动增量导入的特殊情况应写为:
代码语言:javascript复制 from refs/heads/branch⁰
⁰
后缀是必需的,因为快速导入不允许分支从自身开始,并且在从输入中读取from
命令之前在内存中创建分支。添加⁰
将强制快速导入通过 Git 的修订解析库而不是其内部分支表来解析提交,从而加载分支的现有值。
merge
包括一个额外的祖先提交。附加的祖先链接不会更改此提交时构建树状态的方式。如果在创建新分支时省略from
命令,则第一个merge
提交将是当前提交的第一个祖先,并且分支将从没有文件开始。快速导入允许每次提交无限数量的merge
命令,从而建立 n 路合并。
这里<commit-ish>
是from
也接受的任何提交规范表达式(见上文)。
filemodify
包含在commit
命令中以添加新文件或更改现有文件的内容。此命令有两种不同的方法来指定文件的内容。
External data format
该文件的数据内容已由先前的blob
命令提供。前端只需要连接它。
'M' SP <mode> SP <dataref> SP <path> LF
这里通常<dataref>
必须是先前blob
命令设置的标记引用(:<idnum>
),或者是现有 Git blob 对象的完整 40 字节 SHA-1。如果<mode>
为040000``,则
<dataref>必须是现有 Git 树对象的完整 40 字节 SHA-1 或使用
–import-marks`设置的标记引用。
Inline data format
尚未提供该文件的数据内容。前端想要将其作为此修改命令的一部分提供。
代码语言:javascript复制 'M' SP <mode> SP 'inline' SP <path> LF
data
有关data
命令的详细说明,请参见下文。
在两种格式中,<mode>
是以八进制指定的文件条目类型。 Git 仅支持以下模式:
-
100644
或644
:普通(不可执行)文件。大多数项目中的大多数文件都使用此模式。如果有疑问,这就是你想要的。 -
100755
或755
:正常但可执行的文件。 -
120000
:符号链接,文件内容将是链接目标。 -
160000
:gitlink,对象的 SHA-1 引用另一个存储库中的提交。 Git 链接只能由 SHA 或提交标记指定。它们用于实现子模块。 -
040000
:一个子目录。子目录只能由 SHA 或通过--import-marks
设置的树标记指定。
在两种格式中,<path>
是要添加的文件的完整路径(如果尚未存在)或已修改(如果已存在)。
<path>
字符串必须使用 UNIX 样式的目录分隔符(正斜杠/
),可以包含LF
以外的任何字节,并且不能以双引号("
)开头。
路径可以使用 C 风格的字符串引用;这在所有情况下都是可接受的,如果文件名以双引号开头或包含LF
,则是强制性的。在 C 风格的引用中,完整的名称应该用双引号括起来,并且任何LF
,反斜杠或双引号字符必须通过在其前面加上反斜杠(例如,"path/withn, \ and " in it"
)进行转义。
<path>
的值必须是规范形式。那不是:
- 包含一个空目录组件(例如
foo//bar
无效), - 以目录分隔符结束(例如
foo/
无效), - 从目录分隔符开始(例如
/foo
无效), - 包含特殊组件
.
或..
(例如foo/./bar
和foo/../bar
无效)。
树的根可以用空字符串表示为<path>
。
建议始终使用 UTF-8 对<path>
进行编码。
filedelete
包含在commit
命令中以删除文件或从分支中递归删除整个目录。如果删除文件或目录使其父目录为空,则父目录也将自动删除。这会将树级联,直到到达第一个非空目录或根目录。
'D' SP <path> LF
这里<path>
是要从分支中删除的文件或子目录的完整路径。有关<path>
的详细说明,请参见上面的filemodify
。
filecopy
递归地将现有文件或子目录复制到分支内的其他位置。现有文件或目录必须存在。如果目标存在,它将完全被从源复制的内容替换。
代码语言:javascript复制 'C' SP <path> SP <path> LF
这里第一个<path>
是源位置,第二个<path>
是目的地。有关<path>
的详细描述,请参见上面的filemodify
。要使用包含 SP 的源路径,必须引用该路径。
filecopy
命令立即生效。将源位置复制到目标后,应用于源位置的任何将来的命令都不会影响副本的目标。
filerename
将现有文件或子目录重命名为分支内的其他位置。现有文件或目录必须存在。如果目标存在,它将被源目录替换。
代码语言:javascript复制 'R' SP <path> SP <path> LF
这里第一个<path>
是源位置,第二个<path>
是目的地。有关<path>
的详细描述,请参见上面的filemodify
。要使用包含 SP 的源路径,必须引用该路径。
filerename
命令立即生效。将源位置重命名为目标后,应用于源位置的任何将来命令都将在其中创建新文件,而不会影响重命名的目标。
请注意,filerename
与filecopy
后跟源位置的filedelete
相同。使用filerename
有一个轻微的性能优势,但优势是如此之小,以至于永远不值得尝试将源材料中的删除/添加对转换为重命名以进行快速导入。提供此filerename
命令只是为了简化已经具有重命名信息的前端,并且不希望将其分解为filecopy
后跟filedelete
。
filedeleteall
包含在commit
命令中,以从分支中删除所有文件(以及所有目录)。此命令重置内部分支结构,使其中没有文件,允许前端随后从头开始添加所有有趣的文件。
'deleteall' LF
如果前端不知道(或不关心)当前在分支上的文件,并且因此无法生成正确的filedelete
命令来更新内容,则此命令非常有用。
发出filedeleteall
后跟所需的filemodify
命令来设置正确的内容将产生与仅发送所需的filemodify
和filedelete
命令相同的结果。然而,filedeleteall
方法可能需要快速导入,以便为每个活动分支使用稍多的内存(即使是大多数大型项目也不到 1 MiB);鼓励这样做的前端只能轻松获取提交的受影响路径。
notemodify
包含在commit
<notes_ref>
命令中,用于添加注释<commit-ish>
的新注释或更改此注释内容。在内部,它类似于<commit-ish>
路径上的 filemodify 100644(可能拆分为子目录)。除了filedeleteall
之外,不建议使用任何其他命令写入<notes_ref>
树以删除此树中的所有现有注释。此命令有两种不同的方法来指定注释的内容。
External data format
该注释的数据内容已由先前的blob
命令提供。前端只需要将它连接到要注释的提交。
'N' SP <dataref> SP <commit-ish> LF
这里<dataref>
可以是先前blob
命令设置的标记引用(:<idnum>
),也可以是现有 Git blob 对象的完整 40 字节 SHA-1。
Inline data format
该笔记的数据内容尚未提供。前端想要将其作为此修改命令的一部分提供。
代码语言:javascript复制 'N' SP 'inline' SP <commit-ish> LF
data
有关data
命令的详细说明,请参见下文。
在两种格式中,<commit-ish>
是from
也接受的任何提交规范表达式(见上文)。
mark
安排快速导入以保存对当前对象的引用,允许前端在未来的某个时间点调用此对象,而不知道它的 SHA-1。这里当前对象是mark
命令出现的对象创建命令。这可以是commit
,tag
和blob
,但commit
是最常用的用法。
'mark' SP ':' <idnum> LF
其中<idnum>
是前端指定给该标记的数字。 <idnum>
的值表示为 ASCII 十进制整数。值 0 保留,不能用作标记。只有大于或等于 1 的值才可用作标记。
自动创建新标记。只需在另一个mark
命令中重复使用相同的<idnum>
,就可以将现有标记移动到另一个对象。
original-oid
提供原始源代码管理系统中对象的名称。快速导入将简单地忽略该指令,但是在进行快速导入之前对进行操作和修改流的过滤进程可能会使用此信息
代码语言:javascript复制 'original-oid' SP <object-identifier> LF
其中<object-identifer>
是任何不包含 LF 的字符串。
tag
创建引用特定提交的带注释标记。要创建轻量级(非注释)标记,请参阅下面的reset
命令。
'tag' SP <name> LF
'from' SP <commit-ish> LF
original-oid?
'tagger' (SP <name>)? SP LT <email> GT SP <when> LF
data
其中<name>
是要创建的标记的名称。
当存储在 Git 中时,标签名称会自动以refs/tags/
为前缀,因此导入 CVS 分支符号RELENG-1_0-FINAL
将仅使用RELENG-1_0-FINAL
作为<name>
,快速导入会将相应的 ref 写为refs/tags/RELENG-1_0-FINAL
。
<name>
的值必须是 Git 中的有效 refname,因此可能包含正斜杠。由于LF
在 Git refname 中无效,因此此处不支持引用或转义语法。
from
命令与commit
命令相同;见上文了解详情。
tagger
命令使用与commit
中committer
相同的格式;再看上面的细节。
tagger
后面的data
命令必须提供带注释的标签消息(参见下面的data
命令语法)。要导入空标记消息,请使用 0 长度数据。标记消息是自由格式的,不由 Git 解释。目前它们必须以 UTF-8 编码,因为快速导入不允许指定其他编码。
不支持在快速导入中导入期间对带注释的标签进行签名。建议不要尝试包含您自己的 PGP / GPG 签名,因为前端不能(轻松)访问通常进入此类签名的完整字节集。如果需要签名,请使用reset
从快速导入中创建轻量级标记,然后使用标准 _git 标记 _ 进程离线创建这些标记的带注释版本。
reset
创建(或重新创建)命名分支,可选择从特定修订开始。 reset 命令允许前端为现有分支发出新的from
命令,或者从现有提交创建新分支而不创建新提交。
'reset' SP <ref> LF
('from' SP <commit-ish> LF)?
LF?
有关<ref>
和<commit-ish>
的详细说明,请参见上文commit
和from
。
命令后的LF
是可选的(以前是必需的)。
reset
命令也可用于创建轻量级(非注释)标记。例如:
reset refs/tags/938
from :938
将创建轻量级标签refs/tags/938
引用任何提交标记:938
引用。
blob
请求将一个文件修订版写入 packfile。修订与任何提交无关;必须通过指定标记引用 blob,在后续commit
命令中形成此连接。
'blob' LF
mark?
original-oid?
data
mark 命令在这里是可选的,因为一些前端选择为它们自己生成 blob 的 Git SHA-1,并直接将其提供给commit
。然而,这通常比它的价值更多,因为标记的存储成本低且易于使用。
data
提供原始数据(用作 blob /文件内容,提交消息或带注释的标记消息)以快速导入。可以使用精确的字节计数提供数据,也可以使用终止线分隔数据。用于生产质量转换的真正前端应始终使用精确的字节数格式,因为它更强大且性能更好。分隔格式主要用于测试快速导入。
出现在data
命令的<raw>
部分中的注释行始终被视为数据主体的一部分,因此永远不会被快速导入忽略。这样可以安全地导入任何行可能以#
开头的文件/消息内容。
Exact byte count format
前端必须指定数据的字节数。
代码语言:javascript复制 'data' SP <count> LF
<raw> LF?
其中<count>
是<raw>
中出现的确切字节数。 <count>
的值表示为 ASCII 十进制整数。 <raw>
两侧的LF
不包含在<count>
中,不会包含在导入的数据中。
<raw>
之后的LF
是可选的(以前是必需的),但建议使用。始终包含它会使调试快速导入流更容易,因为下一个命令总是从下一行的第 0 列开始,即使<raw>
没有以LF
结束。
Delimited format
分隔符字符串用于标记数据的结尾。 fast-import 将通过搜索分隔符来计算长度。此格式主要用于测试,不建议用于实际数据。
代码语言:javascript复制 'data' SP '<<' <delim> LF
<raw> LF
<delim> LF
LF?
其中<delim>
是选定的分隔符字符串。字符串<delim>
不能在<raw>
中单独出现在一行上,否则快速导入会认为数据比实际更早结束。 LF
立即尾随<raw>
是<raw>
的一部分。这是分隔格式的限制之一,不可能提供没有 LF 作为其最后一个字节的数据块。
<delim> LF
之后的LF
是可选的(曾经是必需的)。
checkpoint
强制快速导入以关闭当前的 packfile,启动一个新文件,并保存所有当前的分支引用,标记和标记。
代码语言:javascript复制 'checkpoint' LF
LF?
请注意,当前包文件达到–max-pack-size 或 4 GiB 时,快速导入会自动切换 packfiles,无论哪个限制较小。在自动 packfile 开关期间,快速导入不会更新分支引用,标记或标记。
由于checkpoint
可能需要大量的 CPU 时间和磁盘 IO(要计算整个包 SHA-1 校验和,生成相应的索引文件,并更新 refs),单个checkpoint
可能需要几分钟命令完成。
前端可能会选择在极大且长时间运行的导入期间发出检查点,或者当他们需要允许另一个 Git 进程访问分支时。然而,鉴于可以通过快速导入在大约 3 小时内将 30 GiB Subversion 存储库加载到 Git 中,可能不需要显式检查点。
命令后的LF
是可选的(以前是必需的)。
progress
当从输入流处理命令时,导致快速导入将未修改的整个progress
行打印到其标准输出通道(文件描述符 1)。否则,该命令对当前导入或任何快速导入的内部状态没有影响。
'progress' SP <any> LF
LF?
命令的<any>
部分可以包含不包含LF
的任何字节序列。命令后的LF
是可选的。调用者可能希望通过诸如 sed 之类的工具处理输出以删除行的前导部分,例如:
frontend | git fast-import | sed 's/^progress //'
在checkpoint
之后立即放置progress
命令将在checkpoint
完成时通知读者,并且可以安全地访问快速导入更新的参考。
get-mark
导致快速导入将对应于标记的 SHA-1 打印到 stdout 或先前使用--cat-blob-fd
参数排列的文件描述符。否则该命令对当前导入没有影响;它的目的是检索稍后提交可能要在其提交消息中引用的 SHA-1。
'get-mark' SP ':' <idnum> LF
此命令可以在流中接受注释的任何位置使用。特别是,get-mark
命令可以在提交过程中使用,但不能在data
命令的中间使用。
有关如何安全读取此输出的详细信息,请参阅下面的“对命令的响应”。
cat-blob
导致快速导入将 blob 打印到先前使用--cat-blob-fd
参数排列的文件描述符。否则该命令对当前导入没有影响;其主要目的是检索可能位于快速导入内存但无法从目标存储库访问的 blob。
'cat-blob' SP <dataref> LF
<dataref>
可以是先前设置的标记参考(:<idnum>
),也可以是预先存在或准备写入的 Git blob 的完整 40 字节 SHA-1。
输出使用与git cat-file --batch
相同的格式:
<sha1> SP 'blob' SP <size> LF
<contents> LF
此命令可以在流中接受注释的任何位置使用。特别是,cat-blob
命令可以在提交过程中使用,但不能在data
命令的中间使用。
有关如何安全读取此输出的详细信息,请参阅下面的“对命令的响应”。
ls
在先前使用--cat-blob-fd
参数排列的文件描述符的路径上打印有关对象的信息。这允许从活动提交(使用cat-blob
)打印 blob 或从先前提交中复制 blob 或树以在当前提交中使用(使用filemodify
)。
ls
命令可以在流中接受注释的任何位置使用,包括提交的中间位置。
Reading from the active commit
此表单只能在commit
的中间使用。该路径在 fast-import 的活动提交中命名目录条目。在这种情况下必须引用该路径。
'ls' SP <path> LF
代码语言:javascript复制 Reading from a named tree
<dataref>
可以是标记引用(:<idnum>
)或 Git 标记,提交或树对象的完整 40 字节 SHA-1,预先存在或等待写入。该路径相对于<dataref>
命名的树的顶层。
'ls' SP <dataref> SP <path> LF
有关<path>
的详细说明,请参见上面的filemodify
。
输出使用与git ls-tree <tree> -- <path>
相同的格式:
<mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF
< dataref>表示< path>处的 blob,树或提交对象并且可以在以后的 get-mark , cat-blob , filemodify 或 ls 命令中使用。
如果该路径中没有文件或子树, git fast-import 将改为报告
代码语言:javascript复制missing SP <path> LF
有关如何安全读取此输出的详细信息,请参阅下面的“对命令的响应”。
feature
要求快速导入支持指定的功能,如果不支持,则中止。
代码语言:javascript复制 'feature' SP <feature> ('=' <argument>)? LF
< feature>命令的一部分可能是以下任何一种:
代码语言:javascript复制 date-format
代码语言:javascript复制 export-marks
代码语言:javascript复制 relative-marks
代码语言:javascript复制 no-relative-marks
代码语言:javascript复制 force
好像在命令行上传递了带有前导--
的相应命令行选项(参见上面的 OPTIONS)。
import-marks
代码语言:javascript复制 import-marks-if-exists
像–import-marks 一样,除了两个方面:首先,每个流只允许一个“feature import-marks”或“feature import-marks-if-exists”命令;第二, - import-marks =或–import-marks-if-exists 命令行选项会覆盖流中的任何这些“功能”命令;第三,“功能 import-marks-if-exists”就像相应的命令行选项一样,会以静默方式跳过不存在的文件。
代码语言:javascript复制 get-mark
代码语言:javascript复制 cat-blob
代码语言:javascript复制 ls
要求后端分别支持 get-mark , cat-blob 或 ls 命令。不支持指定命令的快速导入版本将退出并显示一条消息。这样可以使用明确的消息提前导出错误,而不是在检测到不支持的命令之前在导入的早期浪费时间。
代码语言:javascript复制 notes
要求后端支持 commit (N)子命令到 commit 命令。快速导入不支持注释的版本将退出,并显示一条消息。
代码语言:javascript复制 done
如果流没有 _ 完成 _ 命令结束,则输出错误。如果没有此功能,导致前端突然在流中方便的位置结束的错误可能无法检测到。例如,如果导入前端在中间操作中死亡而不在其下级 git 快速导入实例中发出 SIGTERM 或 SIGKILL,则可能发生这种情况。
option
处理指定的选项,以便 git fast-import 以适合前端需要的方式运行。请注意,前端指定的选项会被用户指定用于 git 快速导入的任何选项覆盖。
代码语言:javascript复制 'option' SP <option> LF
命令的<option>
部分可能包含 OPTIONS 部分中列出的任何不改变导入语义的选项,没有前导--
并且以相同的方式处理。
选项命令必须是输入上的第一个命令(不计算功能命令),以便在任何非选项命令出错后给出选项命令。
以下命令行选项更改导入语义,因此不能作为选项传递:
- 日期格式
- 进口标志
- 出口标志
- 猫 BLOB-FD
- 力
done
如果未使用done
功能,则将其视为已读取 EOF。这可以用来告诉快速导入提前完成。
如果正在使用--done
命令行选项或feature done
命令,则done
命令是必需的,并标记流的结束。
对命令的回应
快速导入写入的新对象不能立即使用。大多数快速导入命令在下一个检查点(或完成)之前没有可见效果。前端可以发送命令来填充快速导入的输入管道,而不必担心它们将如何快速生效,从而通过简化调度来提高性能。
但是,对于某些前端,能够在更新时从当前存储库中读回数据非常有用(例如,当源材料根据要应用于先前导入的对象的补丁描述对象时)。这可以通过连接前端和通过双向管道快速导入来实现:
代码语言:javascript复制mkfifo fast-import-output
frontend <fast-import-output |
git fast-import >fast-import-output
以这种方式设置的前端可以使用progress
,get-mark
,ls
和cat-blob
命令从正在进行的导入中读取信息。
为避免死锁,在执行可能阻塞的快速导入写入之前,此类前端必须完全使用progress
,ls
,get-mark
和cat-blob
的任何挂起输出。
崩溃报告
如果快速导入提供无效输入,它将以非零退出状态终止,并在其导入的 Git 存储库的顶层创建崩溃报告。崩溃报告包含内部快速导入状态的快照以及导致崩溃的最新命令。
所有最近的命令(包括流注释,文件更改和进度命令)都显示在崩溃报告中的命令历史记录中,但是从崩溃报告中排除了原始文件数据和提交消息。此排除可以节省报告文件中的空间,并减少快速导入在执行期间必须执行的缓冲量。
编写崩溃报告后,快速导入将关闭当前的包文件并导出标记表。这允许前端开发人员检查存储库状态并从崩溃点继续导入。由于导入未成功完成,因此在崩溃期间不会更新已修改的分支和标记。可以在崩溃报告中找到分支和标记信息,如果需要更新,则必须手动应用。
崩溃示例:
代码语言:javascript复制$ cat >in <<END_OF_INPUT
# my very first test commit
commit refs/heads/master
committer Shawn O. Pearce <spearce> 19283 -0400
# who is that guy anyway?
data <<EOF
this is my commit
EOF
M 644 inline .gitignore
data <<EOF
.gitignore
EOF
M 777 inline bob
END_OF_INPUT
代码语言:javascript复制$ git fast-import <in
fatal: Corrupt mode: M 777 inline bob
fast-import: dumping crash report to .git/fast_import_crash_8434
代码语言:javascript复制$ cat .git/fast_import_crash_8434
fast-import crash report:
fast-import process: 8434
parent process : 1391
at Sat Sep 1 00:58:12 2007
代码语言:javascript复制fatal: Corrupt mode: M 777 inline bob
代码语言:javascript复制Most Recent Commands Before Crash
---------------------------------
# my very first test commit
commit refs/heads/master
committer Shawn O. Pearce <spearce> 19283 -0400
# who is that guy anyway?
data <<EOF
M 644 inline .gitignore
data <<EOF
* M 777 inline bob
代码语言:javascript复制Active Branch LRU
-----------------
active_branches = 1 cur, 5 max
代码语言:javascript复制pos clock name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1) 0 refs/heads/master
代码语言:javascript复制Inactive Branches
-----------------
refs/heads/master:
status : active loaded dirty
tip commit : 0000000000000000000000000000000000000000
old tree : 0000000000000000000000000000000000000000
cur tree : 0000000000000000000000000000000000000000
commit clock: 0
last pack :
代码语言:javascript复制-------------------
END OF CRASH REPORT
技巧和窍门
从快速导入的各种用户收集了以下提示和技巧,并在此处作为建议提供。
每个提交使用一个标记
进行存储库转换时,每次提交使用唯一标记(mark :<n>
)并在命令行上提供–export-marks 选项。 fast-import 将转储一个文件,该文件列出了每个标记和与之对应的 Git 对象 SHA-1。如果前端可以将标记绑定到源存储库,则可以通过将每个 Git 提交与相应的源修订进行比较来轻松验证导入的准确性和完整性。
来自 Perforce 或 Subversion 等系统,这应该非常简单,因为快速导入标记也可以是 Perforce 变更集编号或 Subversion 版本号。
自由地跳过分支机构
在导入过程中,不要试图优化前端以一次粘贴到一个分支。尽管快速导入可能会稍快一些,但它往往会大大增加前端代码的复杂性。
内置于快速导入的分支 LRU 往往表现得非常好,激活非活动分支的成本非常低,以至于在分支之间反弹几乎不会影响导入性能。
处理重命名
导入重命名的文件或目录时,只需删除旧名称并在相应的提交期间修改新名称。 Git 在事后执行重命名检测,而不是在提交期间显式执行。
使用标记修复分支
一些其他 SCM 系统允许用户从多个文件创建标签,这些文件不是来自相同的提交/变更集。或者创建标记,这些标记是存储库中可用文件的子集。
如果不至少进行一次“修复”文件以匹配标记内容的提交,则无法在 Git 中导入这些标记。使用 fast-import 的reset
命令将正常分支空间之外的虚拟分支重置为标记的基本提交,然后提交一个或多个文件修复提交,最后标记虚拟分支。
例如,因为所有正常分支都以refs/heads/
名称存储在标签修复分支TAG_FIXUP
中。这样,导入器使用的 fixup 分支就不可能与从源导入的真实分支发生名称空间冲突(名称TAG_FIXUP
不是refs/heads/TAG_FIXUP
)。
提交修正时,请考虑使用merge
将提交文件修订的提交连接到 fixup 分支。这样做将允许诸如 git blame 之类的工具跟踪真实的提交历史并正确地注释源文件。
快速导入终止后,前端需要执行rm .git/TAG_FIXUP
以删除虚拟分支。
立即导入,稍后重新包装
一旦快速导入完成,Git 存储库就完全有效并可以使用了。通常这只需要非常短的时间,即使对于相当大的项目(100,000 多次提交)也是如此。
但是,重新打包存储库对于改善数据位置和访问性能是必要的。在极大的项目上也可能需要数小时(特别是如果使用-f 和大的–window 参数)。由于重新打包可以安全地与读者和作者一起运行,因此在后台运行重新打包并在完成后完成。没有理由等待探索你的新 Git 项目!
如果您选择等待重新包装,请不要尝试运行基准测试或性能测试,直到重新打包完成。快速导入输出次优的包文件,这些包装文件在实际使用情况下从未见过。
重新包装历史数据
如果您要重新打包非常旧的导入数据(例如,比去年更早),请考虑在运行 git repack 时花费一些额外的 CPU 时间并提供–window = 50(或更高)。这将花费更长的时间,但也会产生更小的 packfile。您只需要花费一次精力,使用您的项目的每个人都将从较小的存储库中受益。
包括一些进度消息
每隔一段时间,您的前端会发出progress
消息以快速导入。消息的内容完全是自由格式的,因此一个建议是每当当前提交日期进入下个月时输出当前月份和年份。了解已处理了多少数据流后,您的用户会感觉更好。
包装优化
打包 blob 时,fast-import 总是试图对写入的最后一个 blob 进行处理。除非前端特别安排,否则这可能不是同一文件的先前版本,因此生成的 delta 不会是最小的。生成的 packfile 将被压缩,但不是最佳的。
有效访问单个文件的所有修订版(例如读取 RCS / CVS,v 文件)的前端可以选择将该文件的所有修订版作为连续blob
命令序列提供。这允许快速导入以对彼此的不同文件修订进行分区,从而节省最终 packfile 中的空间。标记可用于稍后在commit
命令序列期间识别单个文件修订。
快速导入创建的 packfile 不会鼓励良好的磁盘访问模式。这是由于快速导入按照标准输入接收的顺序写入数据引起的,而 Git 通常在 packfiles 中组织数据以使最新(当前提示)数据出现在历史数据之前。 Git 还将提交集中在一起,通过更好的缓存局部性加速修订遍历。
因此,强烈建议用户在快速导入完成后使用git repack -a -d
重新打包存储库,允许 Git 重新组织 packfiles 以便更快地访问数据。如果 blob 增量不是最理想的(参见上文),那么添加-f
选项以强制重新计算所有增量可以显着减少最终的包文件大小(30-50%更小可能非常典型)。
记忆利用
有许多因素会影响快速导入执行导入所需的内存量。与核心 Git 的关键部分一样,快速导入使用自己的内存分配器来分摊与 malloc 相关的任何开销。实际上,由于使用了大块分配,快速导入往往会将任何 malloc 开销分摊到 0。
每个对象
fast-import 为在此执行中编写的每个对象维护一个内存中结构。在 32 位系统上,结构是 32 字节,在 64 位系统上,结构是 40 字节(由于指针大小较大)。在快速导入终止之前,表中的对象不会被释放。在 32 位系统上导入 200 万个对象将需要大约 64 MiB 的内存。
对象表实际上是一个键入对象名称的哈希表(唯一的 SHA-1)。此存储配置允许快速导入以重用现有或已写入的对象,并避免将重复项写入输出包文件。重复的 blob 在导入中非常常见,通常是由于源中的分支合并。
每个标记
标记存储在稀疏数组中,每个标记使用 1 个指针(4 个字节或 8 个字节,具体取决于指针大小)。虽然数组是稀疏的,但仍然强烈建议使用前端在 1 和 n 之间使用标记,其中 n 是此导入所需的标记总数。
每个分支
分支被分类为活动和非活动。两个类的内存使用量明显不同。
非活动分支存储在一个结构中,该结构使用 96 或 120 字节(分别为 32 位或 64 位系统),以及每个分支的分支名称长度(通常小于 200 字节)。快速导入将轻松处理 2 MiB 内存中多达 10,000 个非活动分支。
活动分支与非活动分支具有相同的开销,但也包含最近在该分支上修改的每个树的副本。如果子树include
由于分支变为活动状态而未被修改,则其内容将不会被加载到内存中,但如果子树src
已被提交修改,因为分支变为活动状态,则其内容将被加载到内存中。
由于活动分支存储有关该分支上包含的文件的元数据,因此它们的内存存储大小可以增长到相当大的大小(见下文)。
快速导入基于最近最少使用的简单算法自动将活动分支移动到非活动状态。每个commit
命令都会更新 LRU 链。可以使用–active-branches =在命令行上增加或减少最大活动分支数。
每活动树
树(aka 目录)在其条目所需的内存之上仅使用 12 个字节的内存(请参阅下面的“每个活动文件”)。树的成本实际上是 0,因为它的开销在各个文件条目上摊销。
每个活动文件条目
活动树中的文件(和指向子树的指针)每个条目需要 52 或 64 个字节(32/64 位平台)。为了节省空间,文件和树名称汇集在一个公共字符串表中,允许文件名“Makefile”仅使用 16 个字节(在包括字符串头开销之后),无论它在项目中出现多少次。
活动分支 LRU 与文件名字符串池和延迟加载子树相结合,允许快速导入,在非常有限的内存占用(每个活动分支小于 2.7 MiB)内有效导入具有 2,000 多个分支和 45,114 文件的项目。
SIGNALS
将 SIGUSR1 发送到 git fast-import 进程会提前结束当前的 packfile,模拟checkpoint
命令。不耐烦的操作员可以使用此工具来查看对象并从正在进行的导入中复制,但代价是增加了一些运行时间和更差的压缩。
也可以看看
git-fast-export [1]
GIT
部分 git [1] 套件
git-clean
原文:
git-scm.com/docs/git-clean
名称
git-clean - 从工作树中删除未跟踪的文件
概要
代码语言:javascript复制git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>…
描述
通过从当前目录开始递归删除不受版本控制的文件来清除工作树。
通常,只删除 Git 未知的文件,但如果指定了-x
选项,则也会删除被忽略的文件。例如,这可以用于删除所有构建产品。
如果给出任何可选的<path>...
参数,则只会影响这些路径。
OPTIONS
代码语言:javascript复制 -d
除了未跟踪的文件之外,删除未跟踪的目录。如果未跟踪的目录由不同的 Git 存储库管理,则默认情况下不会删除它。如果您确实要删除此类目录,请使用-f 选项两次。
代码语言:javascript复制 -f
代码语言:javascript复制 --force
如果 Git 配置变量 clean.requireForce 未设置为 false, git clean 将拒绝删除文件或目录,除非给出-f,-n 或-i。除非给出第二个-f,否则 Git 将拒绝使用.git 子目录或文件删除目录。
代码语言:javascript复制 -i
代码语言:javascript复制 --interactive
显示将要执行的操作并以交互方式清理文件。有关详细信息,请参阅“交互模式”
代码语言:javascript复制 -n
代码语言:javascript复制 --dry-run
不要删除任何东西,只显示将要做的事情。
代码语言:javascript复制 -q
代码语言:javascript复制 --quiet
保持安静,仅报告错误,但不报告成功删除的文件。
代码语言:javascript复制 -e <pattern>
代码语言:javascript复制 --exclude=<pattern>
除了在.gitignore(每个目录)和$ GIT_DIR / info / exclude 中找到的那些之外,还要考虑这些模式在有效的忽略规则集中。
代码语言:javascript复制 -x
不要使用从.gitignore(每个目录)和$ GIT_DIR / info / exclude 读取的标准忽略规则,但仍然使用-e
选项给出的忽略规则。这允许删除所有未跟踪的文件,包括构建产品。这可以使用(可能与 git reset 一起使用)来创建一个 pristine 工作目录来测试一个干净的构建。
-X
仅删除 Git 忽略的文件。这可能有助于从头开始重建所有内容,但保留手动创建的文件。
互动模式
当命令进入交互模式时,它显示要清理的文件和目录,并进入其交互式命令循环。
命令循环显示可用的子命令列表,并给出提示“What now>”。通常,当提示以单个 >结束时。 ,您只能选择给定的一个选项并输入 return,如下所示:
代码语言:javascript复制 *** Commands ***
1: clean 2: filter by pattern 3: select by numbers
4: ask each 5: quit 6: help
What now> 1
只要选择是唯一的,您也可以说c
或clean
。
主命令循环有 6 个子命令。
代码语言:javascript复制 clean
开始清理文件和目录,然后退出。
代码语言:javascript复制 filter by pattern
这显示了要删除的文件和目录,并发出“输入忽略模式>>”提示。您可以输入以空格分隔的模式,以排除文件和目录的删除。例如。 “* .c * .h”将从删除中排除以“.c”和“.h”结尾的文件。如果对筛选结果感到满意,请按 ENTER(空)返回主菜单。
代码语言:javascript复制 select by numbers
这显示了要删除的文件和目录,并发出“选择要删除的项目>>”提示。当提示以 double _>>结束时 _ 就像这样,你可以做多个选择,用空格或逗号连接起来。你也可以说范围。例如。 “2-5 7,9”从列表中选择 2,3,4,5,7,9。如果省略范围中的第二个数字,则选择所有剩余项目。例如。 “7-”从列表中选择 7,8,9。你可以说 * 来选择一切。此外,当您对筛选结果感到满意时,请按 ENTER(空)返回主菜单。
代码语言:javascript复制 ask each
这将开始清理,您必须逐个确认才能删除项目。请注意,此操作不如上述两个操作有效。
代码语言:javascript复制 quit
这样可以在不进行清洁的情况下退出。
代码语言:javascript复制 help
显示交互式 git-clean 的简要用法。
也可以看看
gitignore [5]
GIT
部分 git [1] 套件
git-gc
原文:
git-scm.com/docs/git-gc
名称
git-gc - 清理不必要的文件并优化本地存储库
概要
代码语言:javascript复制git gc [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]
描述
在当前存储库中运行许多内务处理任务,例如压缩文件修订版(以减少磁盘空间并提高性能),删除可能从之前调用 git add 创建的无法访问的对象,打包引用,修剪 reflog,rerere 元数据或陈旧的工作树。也可以更新提交图等辅助索引。
建议用户定期在每个存储库中运行此任务,以保持良好的磁盘空间利用率和良好的运行性能。
一些 git 命令可以自动运行 git gc ;有关详细信息,请参见下面的--auto
标志。如果您知道自己在做什么,并且您想要的是永久禁用此行为而无需进一步考虑,只需执行以下操作:
$ git config --global gc.auto 0
OPTIONS
代码语言:javascript复制 --aggressive
通常 git gc 运行速度非常快,同时提供良好的磁盘空间利用率和性能。此选项将导致 git gc 更积极地优化存储库,但代价是花费更多时间。这种优化的效果是持久的,所以这个选项只需要偶尔使用;每几百个变更集左右。
代码语言:javascript复制 --auto
使用此选项, git gc 检查是否需要任何内务处理;如果没有,它退出而不执行任何工作。执行可能会创建许多松散对象的操作后,某些 git 命令会运行git gc --auto
。如果存储库中有太多松散的对象或太多的包,则需要内务处理。
如果松散对象的数量超过gc.auto
配置变量的值,则使用git repack -d -l
将所有松散对象合并为单个包。将gc.auto
的值设置为 0 将禁用松散物体的自动包装。
如果包数超过gc.autoPackLimit
的值,则使用 _ 的-A
选项将现有包(标有.keep
文件或超过gc.bigPackThreshold
限制的包除外)合并为单个包中 git repack_ 。如果估计内存量不足以使git repack
平稳运行并且未设置gc.bigPackThreshold
,则也将排除最大包(这相当于使用--keep-base-pack
运行git gc
)。将gc.autoPackLimit
设置为 0 将禁用包的自动合并。
如果由于许多松散的物体或包装而需要进行保养,则还将执行所有其他内务处理任务(例如,rerere,工作树,reflog …)。
代码语言:javascript复制 --prune=<date>
修剪早于日期的松散对象(默认为 2 周前,可由配置变量gc.pruneExpire
覆盖)。 --prune =所有修剪松散的对象,无论其年龄如何,如果另一个进程同时写入存储库,则会增加损坏的风险;请参阅下面的“注意”。 --prune 默认开启。
--no-prune
不要修剪任何松散的物体。
代码语言:javascript复制 --quiet
取消所有进度报告。
代码语言:javascript复制 --force
即使可能在此存储库上运行另一个git gc
实例,也强制git gc
运行。
--keep-largest-pack
除最大包装外的所有包装和标有.keep
文件的包装都合并为一个包装。使用此选项时,将忽略gc.bigPackThreshold
。
组态
可以设置可选配置变量gc.reflogExpire
以指示每个分支的 reflog 中的历史条目在此存储库中保持可用的时间。该设置表示为时间长度,例如 _90 天 _ 或 _3 个月 _。默认为 _90 天 _。
可以设置可选配置变量gc.reflogExpireUnreachable
以指示不属于当前分支的历史 reflog 条目在此存储库中保持可用的时间长度。这些类型的条目通常是使用git commit --amend
或git rebase
的结果创建的,并且是修改或重组发生之前的提交。由于这些更改不是当前项目的一部分,因此大多数用户希望尽快使其过期。此选项默认为 _30 天 _。
上述两个配置变量可以赋予模式。例如,这仅将非默认到期值设置为远程跟踪分支:
代码语言:javascript复制[gc "refs/remotes/*"]
reflogExpire = never
reflogExpireUnreachable = 3 days
可选配置变量gc.rerereResolved
表示您保留先前解决的冲突合并记录的时间长度。默认为 60 天。
可选配置变量gc.rerereUnresolved
表示保留未解决的冲突合并记录的时间长度。默认为 15 天。
可选配置变量gc.packRefs
确定 git gc 是否运行 git pack-refs 。这可以设置为“notbare”以在所有非裸存储库中启用它,或者可以将其设置为布尔值。默认为 true。
可选配置变量gc.writeCommitGraph
确定 git gc 是否应该运行 git commit-graph write 。这可以设置为布尔值。默认为 false。
可选配置变量gc.aggressiveWindow
控制在指定-aggressive 选项时优化存储库中对象的增量压缩所花费的时间。值越大,优化增量压缩所花费的时间就越多。有关详细信息,请参阅 git-repack [1] 中–window 选项的文档。默认为 250。
类似地,可选配置变量gc.aggressiveDepth
控制 git-repack [1] 中的–depth 选项。默认为 50。
可选配置变量gc.pruneExpire
控制未被引用的松散对象在被修剪之前必须有多长。默认为“2 周前”。
可选配置变量gc.worktreePruneExpire
控制在git worktree prune
删除之前过时工作树的年龄。默认为“3 个月前”。
笔记
git gc 非常努力地不删除存储库中任何位置引用的对象。特别是,它不仅会保留当前分支和标记集引用的对象,还会保留由 git filter-branch 在 refs / original /中保存的索引,远程跟踪分支,引用引用的对象。或者 reflogs(可以引用稍后修改或重绕的分支中的提交)。如果您希望某些对象被删除而它们不是,请检查所有这些位置,并确定在您的情况下删除这些引用是否有意义。
另一方面,当 git gc 与另一个进程同时运行时,存在删除另一个进程正在使用但尚未创建引用的对象的风险。如果其他进程稍后添加对已删除对象的引用,则这可能只会导致其他进程失败或可能损坏存储库。 Git 有两个功能可以显着缓解这个问题:
- 修改时间比
--prune
日期更新的任何对象以及从中可以访问的所有对象。 - 将对象添加到数据库的大多数操作都会更新对象的修改时间(如果已存在),以便应用#1。
但是,这些功能缺乏完整的解决方案,因此同时运行命令的用户必须承受一定的腐败风险(实际上似乎很低),除非他们用 git config gc.auto 关闭自动垃圾收集。 0 。
挂钩
git gc --auto 命令将运行 pre-auto-gc 挂钩。有关更多信息,请参阅 githooks [5] 。
也可以看看
git-prune [1] git-reflog [1] git-repack [1] git-rerere [1]
GIT
部分 git [1] 套件
git-fsck
原文:
git-scm.com/docs/git-fsck
名称
git-fsck - 验证数据库中对象的连通性和有效性
概要
代码语言:javascript复制git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
[--[no-]full] [--strict] [--verbose] [--lost-found]
[--[no-]dangling] [--[no-]progress] [--connectivity-only]
[--[no-]name-objects] [<object>*]
描述
验证数据库中对象的连接性和有效性。
OPTIONS
代码语言:javascript复制 <object>
作为不可达性痕迹的头部对象的对象。
如果没有给出对象, git fsck 默认使用索引文件,refs
命名空间中的所有 SHA-1 引用,以及所有 reflog(除非给出–no-reflogs)作为头。
--unreachable
打印出存在但无法从任何引用节点访问的对象。
代码语言:javascript复制 --[no-]dangling
打印存在但永远不会 _ 直接 _ 使用的对象(默认)。 --no-dangling
可用于从输出中省略此信息。
--root
报告根节点。
代码语言:javascript复制 --tags
报告标签。
代码语言:javascript复制 --cache
将索引中记录的任何对象也视为不可达性跟踪的头节点。
代码语言:javascript复制 --no-reflogs
不要认为仅由 reflog 中的条目引用的提交是可访问的。此选项仅用于搜索曾经在 ref 中的提交,但现在不是,但仍在相应的 reflog 中。
代码语言:javascript复制 --full
不仅检查 GIT_OBJECT_DIRECTORY( GIT_DIR / objects)中的对象,还检查在 GIT_ALTERNATE_OBJECT_DIRECTORIES 或 GIT_DIR / objects / info / alternates 中列出的备用对象池中找到的对象,以及在
代码语言:javascript复制 --connectivity-only
仅检查标记,提交和树对象的连接。通过避免解压缩 blob,这会加速操作,但代价是丢失损坏的对象或其他有问题的问题。
代码语言:javascript复制 --strict
启用更严格的检查,即捕获由 g w 位集记录的文件模式,该模式由旧版本的 Git 创建。现有存储库(包括 Linux 内核,Git 本身和稀疏存储库)具有触发此检查的旧对象,但建议使用此标志检查新项目。
代码语言:javascript复制 --verbose
说实话。
代码语言:javascript复制 --lost-found
将悬空对象写入.git / lost-found / commit /或.git / lost-found / other /,具体取决于类型。如果对象是 blob,则将内容写入文件,而不是其对象名称。
代码语言:javascript复制 --name-objects
当显示可到达对象的名称时,除了 SHA-1 之外还显示描述如何可以到达的名称,与 git-rev-parse [1] 兼容,例如HEAD@{1234567890}~25²:src/
。
--[no-]progress
除非指定了–no-progress 或–verbose,否则默认情况下,当标准错误流附加到终端时,会报告进度状态。 - 即使标准错误流未定向到终端, - progress 也会强制进度状态。
讨论
git-fsck 测试 SHA-1 和一般对象的健全性,它完全跟踪产生的可达性和其他所有内容。它会打印出它找到的任何损坏(丢失或坏的对象),如果使用--unreachable
标志,它还会打印出存在但无法从任何指定的头节点(或默认集)访问的对象,正如刚才提到的)。
您必须在备份或其他存档中找到任何损坏的对象(即,您可以删除它们并与其他某个站点一起执行 rsync ,希望其他人拥有您已损坏的对象)。
如果 core.commitGraph 为 true,则还将使用 git commit-graph verify 检查提交图文件。参见 git-commit-graph [1] 。
提取的诊断
代码语言:javascript复制 expect dangling commits - potential heads - due to lack of head information
您没有指定任何节点作为头,因此无法区分非父级提交和根节点。
代码语言:javascript复制 missing sha1 directory <dir>
缺少包含 sha1 对象的目录。
代码语言:javascript复制 unreachable <type> <object>
< type>对象< object>,实际上并未在任何树或提交的提交中直接或间接引用。这可能意味着您没有指定另一个根节点或树已损坏。如果您没有错过根节点,那么您也可以删除无法访问的节点,因为它们无法使用。
代码语言:javascript复制 missing <type> <object>
< type>对象< object>,被引用但不存在于数据库中。
代码语言:javascript复制 dangling <type> <object>
< type>对象< object>,存在于数据库中但从不直接使用。悬挂提交可以是根节点。
代码语言:javascript复制 hash mismatch <object>
数据库有一个对象,其哈希值与对象数据库值不匹配。这表明存在严重的数据完整性问题。
环境变量
代码语言:javascript复制 GIT_OBJECT_DIRECTORY
用于指定对象数据库的根目录(通常为$ GIT_DIR / objects)
代码语言:javascript复制 GIT_INDEX_FILE
用于指定索引的索引文件
代码语言:javascript复制 GIT_ALTERNATE_OBJECT_DIRECTORIES
用于指定其他对象数据库根(通常未设置)
GIT
部分 git [1] 套件
git-reflog
原文:
git-scm.com/docs/git-reflog
名称
git-reflog - 管理 reflog 信息
概要
代码语言:javascript复制git reflog <subcommand> <options>
描述
该命令采用各种子命令,并根据子命令使用不同的选项:
代码语言:javascript复制git reflog [show] [log-options] [<ref>]
git reflog expire [--expire=<time>] [--expire-unreachable=<time>]
[--rewrite] [--updateref] [--stale-fix]
[--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>…]
git reflog delete [--rewrite] [--updateref]
[--dry-run | -n] [--verbose] ref@{specifier}…
git reflog exists <ref>
引用日志或“reflogs”记录在本地存储库中更新分支和其他引用的提示时。 Reflog 在各种 Git 命令中很有用,用于指定引用的旧值。例如,HEAD@{2}
表示“HEAD 过去两次移动的地方”,master@{one.week.ago}
表示“主要用于指向一周前的本地存储库”,依此类推。有关详细信息,请参阅 gitrevisions [7] 。
此命令管理 reflog 中记录的信息。
“show”子命令(在没有任何子命令的情况下也是默认命令)显示命令行中提供的引用的日志(或默认情况下为HEAD
)。 reflog 包含所有最近的操作,此外HEAD
reflog 记录分支切换。 git reflog show
是git log -g --abbrev-commit --pretty=oneline
的别名;有关详细信息,请参阅 git-log [1] 。
“expire”子命令修剪旧的 reflog 条目。超过expire
时间的条目,或者早于expire-unreachable
时间且当前提示无法访问的条目将从 reflog 中删除。这通常不会被最终用户直接使用 - 相反,请参阅 git-gc [1] 。
“delete”子命令从 reflog 中删除单个条目。其参数必须是 _ 精确 _ 条目(例如“git reflog delete master@{2}
”)。最终用户通常也不直接使用此子命令。
“exists”子命令检查 ref 是否具有 reflog。如果 reflog 存在则退出为零状态,如果不存在则退出为非零状态。
OPTIONS
show
的选项
git reflog show
接受git log
接受的任何选项。
expire
的选项
代码语言:javascript复制 --all
处理所有引用的 reflog。
代码语言:javascript复制 --single-worktree
默认情况下,指定--all
时,将处理来自所有工作树的 reflog。此选项仅将处理限制为来自当前工作树的 reflog。
--expire=<time>
修剪早于指定时间的条目。如果未指定此选项,则到期时间取自配置设置gc.reflogExpire
,后者默认为 90 天。 --expire=all
修剪条目,不论其年龄; --expire=never
关闭可达条目的修剪(但参见--expire-unreachable
)。
--expire-unreachable=<time>
修剪早于<time>
的条目,无法从分支的当前提示访问。如果未指定此选项,则到期时间取自配置设置gc.reflogExpireUnreachable
,后者默认为 30 天。 --expire-unreachable=all
修剪无法访问的条目,无论其年龄如何; --expire-unreachable=never
关闭无法访问的条目的早期修剪(但参见--expire
)。
--updateref
如果前一个顶部条目被修剪,则更新对顶部 reflog 条目的值的引用(即< ref> @ {0})。 (符号引用会忽略此选项。)
代码语言:javascript复制 --rewrite
如果修剪了 reflog 条目的前任,则将其“旧”SHA-1 调整为等于其前面的条目的“新”SHA-1 字段。
代码语言:javascript复制 --stale-fix
修剪任何指向“已损坏的提交”的 reflog 条目。破坏的提交是无法从任何参考提示访问的提交,它直接或间接地引用缺少的提交,树或 blob 对象。
该计算涉及遍历所有可到达对象,即它具有与 git prune 相同的成本。它主要用于修复使用旧版 Git 进行垃圾收集而导致的损坏,这些版本不保护 reflog 所引用的对象。
代码语言:javascript复制 -n
代码语言:javascript复制 --dry-run
不要删除任何条目;只是展示会被修剪的东西。
代码语言:javascript复制 --verbose
在屏幕上打印额外信息。
delete
的选项
git reflog delete
接受选项--updateref
,--rewrite
,-n
,--dry-run
和--verbose
,其含义与expire
使用时的含义相同。
GIT
部分 git [1] 套件
git-filter-branch
原文:
git-scm.com/docs/git-filter-branch
名称
git-filter-branch - 重写分支
概要
代码语言:javascript复制git filter-branch [--setup <command>] [--subdirectory-filter <directory>]
[--env-filter <command>] [--tree-filter <command>]
[--index-filter <command>] [--parent-filter <command>]
[--msg-filter <command>] [--commit-filter <command>]
[--tag-name-filter <command>] [--prune-empty]
[--original <namespace>] [-d <directory>] [-f | --force]
[--state-branch <branch>] [--] [<rev-list options>…]
描述
允许您通过重写< rev-list options>中提到的分支来重写 Git 修订历史记录,在每个修订版上应用自定义过滤器。这些过滤器可以修改每个树(例如,删除文件或对所有文件运行 perl 重写)或有关每个提交的信息。否则,将保留所有信息(包括原始提交时间或合并信息)。
该命令只会重写命令行中提到的 _ 正 _ refs(例如,如果你传递 a…b ,则只会重写 b )。如果您未指定过滤器,则将重新提交提交而不进行任何更改,这通常无效。然而,这在将来用于补偿某些 Git 错误等方面可能是有用的,因此允许这样的使用。
注:该命令用于表示refs/replace/
命名空间中的.git/info/grafts
文件和引用。如果您定义了任何移植物或替换引物,则运行此命令将使它们成为永久性的。
警告!重写的历史将具有所有对象的不同对象名称,并且不会与原始分支会聚。您将无法在原始分支的顶部轻松推送和分发重写的分支。如果您不知道完整的含义,请不要使用此命令,并且无论如何都要避免使用它,如果简单的单个提交就足以解决您的问题。 (有关重写已发布历史记录的详细信息,请参阅 git-rebase [1] 中的“从上游重新恢复”部分。)
始终验证重写版本是否正确:原始引用(如果与重写版本不同)将存储在命名空间 refs / original / 中。
请注意,由于此操作的 I / O 非常昂贵,因此使用-d
选项重定向磁盘上的临时目录可能是个好主意。在 tmpfs 上。据说加速非常明显。
过滤器
过滤器按以下列出的顺序应用。 < command>始终使用 eval 命令在 shell 上下文中评估参数(出于技术原因,提交过滤器有明显的例外)。在此之前,$GIT_COMMIT
环境变量将被设置为包含要重写的提交的 id。此外,GIT_AUTHOR_NAME,GIT_AUTHOR_EMAIL,GIT_AUTHOR_DATE,GIT_COMMITTER_NAME,GIT_COMMITTER_EMAIL 和 GIT_COMMITTER_DATE 取自当前提交并导出到环境中,以便影响由 git-commit-tree 创建的替换提交的作者和提交者身份[ 1]过滤器运行后的。
如果对< command>进行任何评估返回非零退出状态,整个操作将被中止。
map 函数可用于获取“原始 sha1 id”参数,如果已经重写了提交,则输出“重写的 sha1 id”,否则输出“original sha1 id”;如果您的提交过滤器发出多次提交, map 函数可以在单独的行上返回多个 ID。
OPTIONS
代码语言:javascript复制 --setup <command>
这不是为每次提交执行的实际过滤器,而是在循环之前进行一次设置。因此,尚未定义特定于提交的变量。由于技术原因,除了提交过滤器之外,可以在以下过滤器步骤中使用或修改此处定义的函数或变量。
代码语言:javascript复制 --subdirectory-filter <directory>
只查看触及给定子目录的历史记录。结果将包含该目录(并且仅包含该目录)作为其项目根目录。意味着重新映射到祖先。
代码语言:javascript复制 --env-filter <command>
如果您只需要修改将在其中执行提交的环境,则可以使用此过滤器。具体来说,您可能想要重写作者/提交者名称/电子邮件/时间环境变量(有关详细信息,请参阅 git-commit-tree [1] )。
代码语言:javascript复制 --tree-filter <command>
这是用于重写树及其内容的过滤器。参数在 shell 中计算,工作目录设置为签出树的根。然后按原样使用新树(自动添加新文件,自动删除消失文件 - 既没有.gitignore 文件也没有任何其他忽略规则有任何影响!)。
代码语言:javascript复制 --index-filter <command>
这是重写索引的过滤器。它类似于树过滤器,但不检查树,这使得它更快。经常与git rm --cached --ignore-unmatch ...
一起使用,请参见下面的示例。对于毛病例,请参见 git-update-index [1] 。
--parent-filter <command>
这是用于重写提交的父列表的过滤器。它将在 stdin 上接收父字符串,并在 stdout 上输出新的父字符串。父字符串采用 git-commit-tree [1] 中描述的格式:初始提交为空,正常提交为“-p parent”,“ - p parent1 -p parent2 -p parent3” …“用于合并提交。
代码语言:javascript复制 --msg-filter <command>
这是用于重写提交消息的过滤器。参数在 shell 中使用标准输入上的原始提交消息进行评估;其标准输出用作新的提交消息。
代码语言:javascript复制 --commit-filter <command>
这是执行提交的过滤器。如果指定了此过滤器,则将调用它,而不是 git commit-tree 命令,其参数形式为“< TREE_ID> [( - p< PARENT_COMMIT_ID>)…]”和 stdin 上的日志消息。提交标识在 stdout 上是预期的。
作为特殊扩展,提交过滤器可以发出多个提交 ID;在这种情况下,原始提交的重写子项将全部作为父项。
您也可以在此过滤器中使用 _ 地图 _ 便利功能,以及其他便利功能。例如,调用 skip_commit“$ @” 将省略当前提交(但不会更改!如果你想要,请改用 git rebase )。
如果您不希望保持对单个父项的提交并且不对树进行更改,也可以使用git_commit_non_empty_tree "
代码语言:javascript复制 --tag-name-filter <command>
这是用于重写标记名称的过滤器。传递时,将为每个指向重写对象(或指向重写对象的标记对象)的标记 ref 调用它。原始标记名称通过标准输入传递,新标记名称在标准输出上是预期的。
原始标签不会被删除,但可以被覆盖;使用“–tag-name-filter cat”来简单地更新标签。在这种情况下,请务必小心并确保备份旧标签,以防转换发生冲突。
支持几乎正确的标记对象重写。如果标记附加了消息,则将使用相同的消息,作者和时间戳创建新的标记对象。如果标签附有签名,则签名将被删除。根据定义,不可能保留签名。这是“几乎”正确的原因,因为理想情况下,如果标签没有改变(指向同一个对象,具有相同的名称等),它应该保留任何签名。情况并非如此,签名将永远删除,买家要小心。也不支持更改作者或时间戳(或标记消息)。指向其他标记的标记将被重写以指向底层提交。
代码语言:javascript复制 --prune-empty
某些过滤器将生成空提交,使树保持不变。如果 git-filter-branch 只有一个或零个非修剪父项,则该选项指示 git-filter-branch 删除这些提交;因此,合并提交将保持不变。此选项不能与--commit-filter
一起使用,但通过在提交过滤器中使用提供的git_commit_non_empty_tree
功能可以实现相同的效果。
--original <namespace>
使用此选项可设置将存储原始提交的命名空间。默认值为 refs / original 。
代码语言:javascript复制 -d <directory>
使用此选项可设置用于重写的临时目录的路径。应用树过滤器时,该命令需要临时将树检出到某个目录,这可能会在大型项目中占用相当大的空间。默认情况下,它在 .git-rewrite / 目录中执行此操作,但您可以通过此参数覆盖该选项。
代码语言:javascript复制 -f
代码语言:javascript复制 --force
git filter-branch 拒绝以现有的临时目录开始,或者当已经使用 refs / original / 开始 refs 时,除非被强制。
代码语言:javascript复制 --state-branch <branch>
此选项将导致在启动时从命名分支加载从旧对象到新对象的映射,并在退出时将其保存为该分支的新提交,从而实现大树的增量。如果 < branch> 不存在它将被创建。
代码语言:javascript复制 <rev-list options>…
git rev-list 的参数。这些选项包含的所有正面参考都被重写。您也可以指定--all
等选项,但必须使用--
将它们与 git filter-branch 选项分开。意味着重新映射到祖先。
重新映射到祖先
通过使用 git-rev-list [1] 参数,例如路径限制器,您可以限制被重写的修订集。但是,命令行上的正数引用是有区别的:我们不会让它们被这些限制器排除在外。为此,它们被重写为指向最近的未被排除的祖先。
退出状态
成功时,退出状态为0
。如果过滤器找不到任何要重写的提交,则退出状态为2
。在任何其他错误上,退出状态可以是任何其他非零值。
例子
假设您要从所有提交中删除文件(包含机密信息或侵犯版权):
代码语言:javascript复制git filter-branch --tree-filter 'rm filename' HEAD
但是,如果某个提交的树中没有该文件,则该树和提交的简单rm filename
将失败。因此,您可能希望使用rm -f filename
作为脚本。
将--index-filter
与 git rm 一起使用会产生明显更快的版本。与使用rm filename
一样,如果提交树中没有该文件,git rm --cached filename
将失败。如果你想“完全忘记”一个文件,它在输入历史记录时无关紧要,所以我们也添加了--ignore-unmatch
:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
现在,您将在 HEAD 中保存重写的历史记录。
要重写存储库,使其看起来好像foodir/
是其项目根目录,并丢弃所有其他历史记录:
git filter-branch --subdirectory-filter foodir -- --all
因此,您可以将库子目录转换为自己的存储库。注意--
将 filter-branch 选项与修订选项分开,--all
重写所有分支和标记。
要将提交(通常位于另一个历史记录的顶端)设置为当前初始提交的父级,以便将其他历史记录粘贴到当前历史记录之后:
代码语言:javascript复制git filter-branch --parent-filter 'sed "s/^$/-p <graft-id>/"' HEAD
(如果父字符串为空 - 在我们处理初始提交时发生 - 将 graftcommit 添加为父级)。请注意,这假设具有单个根的历史记录(即,没有共同祖先发生的合并)。如果不是这种情况,请使用:
代码语言:javascript复制git filter-branch --parent-filter
'test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>" || cat' HEAD
甚至更简单:
代码语言:javascript复制git replace --graft $commit-id $graft-id
git filter-branch $graft-id..HEAD
删除历史记录中“Darl McBribe”撰写的提交:
代码语言:javascript复制git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
then
skip_commit "$@";
else
git commit-tree "$@";
fi' HEAD
函数 skip_commit 定义如下:
代码语言:javascript复制skip_commit()
{
shift;
while [ -n "$1" ];
do
shift;
map "$1";
shift;
done;
}
移位魔法首先抛弃树 id 然后抛出-p 参数。请注意,此句柄正确合并!如果 Darl 在 P1 和 P2 之间提交了合并,它将被正确传播,并且合并的所有子节点将成为与 P1,P2 作为其父节点而不是合并提交的合并提交。
注提交引入的更改以及未被后续提交还原的更改仍将在重写的分支中。如果你想将 _ 更改 _ 和提交一起丢弃,你应该使用 git rebase 的交互模式。
您可以使用--msg-filter
重写提交日志消息。例如, git svn 创建的存储库中的 git svn-id 字符串可以通过以下方式删除:
git filter-branch --msg-filter '
sed -e "/^git-svn-id:/d"
'
如果你需要将 Acked-by 行添加到最后 10 个提交(其中没有一个是合并),请使用以下命令:
代码语言:javascript复制git filter-branch --msg-filter '
cat &&
echo "Acked-by: Bugs Bunny <bunny@bugzilla.org>"
' HEAD~10..HEAD
--env-filter
选项可用于修改提交者和/或作者身份。例如,如果您发现由于配置错误的 user.email 导致您的提交具有错误的标识,则可以在发布项目之前进行更正,如下所示:
git filter-branch --env-filter '
if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
then
GIT_AUTHOR_EMAIL=john@example.com
fi
if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
then
GIT_COMMITTER_EMAIL=john@example.com
fi
' -- --all
要将重写限制为仅部分历史记录,请指定除新分支名称之外的修订范围。新分支名称将指向此范围的 git rev-list 将打印的最高版本。
考虑这段历史:
代码语言:javascript复制 D--E--F--G--H
/ /
A--B-----C
要仅重写提交 D,E,F,G,H,但仅保留 A,B 和 C,请使用:
代码语言:javascript复制git filter-branch ... C..H
要重写提交 E,F,G,H,请使用以下方法之一:
代码语言:javascript复制git filter-branch ... C..H --not D
git filter-branch ... D..H --not C
要将整个树移动到子目录中,或从中删除它:
代码语言:javascript复制git filter-branch --index-filter
'git ls-files -s | sed "s-t"*-&newsubdir/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
收回存折的清单
git-filter-branch 可用于删除文件的子集,通常使用--index-filter
和--subdirectory-filter
的某种组合。人们期望生成的存储库小于原始存储库,但是你需要更多的步骤来实际使它变小,因为 Git 努力不会丢失你的对象,直到你告诉它。首先要确保:
- 如果 blob 在其生命周期内被移动,那么您确实删除了文件名的所有变体。
git log --name-only --follow --all -- filename
可以帮助您找到重命名。 - 你真的过滤了所有的 refs:在调用 git-filter-branch 时使用
--tag-name-filter cat -- --all
。
然后有两种方法可以获得更小的存储库。更安全的方法是克隆,保持原始原封不动。
- 用
git clone file:///path/to/repo
克隆它。克隆将没有删除的对象。参见 git-clone [1] 。 (请注意,使用普通路径进行克隆只会将所有内容硬链接!)
如果你真的不想克隆它,无论出于何种原因,请检查以下几点(按此顺序)。这是一种非常具有破坏性的方法,因此会备份或者返回克隆它。你被警告了。
- 删除 git-filter-branch 备份的原始引用:说
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
。 - 使用
git reflog expire --expire=now --all
使所有 reflogs 到期。 - 垃圾收集所有未引用的对象
git gc --prune=now
(或者如果你的 git-gc 不够新,不支持--prune
的参数,请改用git repack -ad; git prune
)。
笔记
git-filter-branch 允许您对 Git 历史记录进行复杂的 shell 脚本重写,但如果您只是 _ 删除不需要的数据 _(如大文件或密码),则可能不需要这种灵活性。对于那些操作,您可能需要考虑 BFG Repo-Cleaner ,一种基于 JVM 的 git-filter-branch 替代方案,对于这些用例通常至少快 10-50 倍,并且具有完全不同的特性:
- 一旦,任何特定版本的文件都会被准确清除 _。与 git-filter-branch 不同,BFG 不会根据历史记录中提交的位置或时间以不同方式处理文件。这个约束给出了 BFG 的核心性能优势,并且非常适合清理坏数据的任务 - 你不关心哪里有坏数据,你只是想让它 _ 消失 。
- 默认情况下,BFG 充分利用多核机器,并行清理提交文件树。 git-filter-branch 按顺序清除提交(即以单线程方式),尽管可以在针对每个提交执行的脚本中编写包含其自身并行性的过滤器。
- 命令选项比 git-filter 分支更具限制性,专门用于删除不需要的数据的任务 - 例如:
--strip-blobs-bigger-than 1M
。
GIT
部分 git [1] 套件
git-instaweb
原文:
git-scm.com/docs/git-instaweb
名称
git-instaweb - 立即在 gitweb 中浏览您的工作存储库
概要
代码语言:javascript复制git instaweb [--local] [--httpd=<httpd>] [--port=<port>]
[--browser=<browser>]
git instaweb [--start] [--stop] [--restart]
描述
设置gitweb
的简单脚本和用于浏览本地存储库的 Web 服务器。
OPTIONS
代码语言:javascript复制 -l
代码语言:javascript复制 --local
仅将 Web 服务器绑定到本地 IP(127.0.0.1)。
代码语言:javascript复制 -d
代码语言:javascript复制 --httpd
将执行的 HTTP 守护程序命令行。这里可以指定命令行选项,配置文件将添加到命令行的末尾。目前支持 apache2,lighttpd,mongoose,plackup,python 和 webrick。 (默认值:lighttpd)
代码语言:javascript复制 -m
代码语言:javascript复制 --module-path
模块路径(仅当 httpd 是 Apache 时才需要)。 (默认值:/ usr / lib / apache2 / modules)
代码语言:javascript复制 -p
代码语言:javascript复制 --port
要将 httpd 绑定到的端口号。 (默认值:1234)
代码语言:javascript复制 -b
代码语言:javascript复制 --browser
应该用于查看 gitweb 页面的 Web 浏览器。这将被传递到 _git web {litdd}浏览 _ 帮助程序脚本以及 gitweb 实例的 URL。有关详细信息,请参阅 git-web {litdd}浏览[1] 。如果脚本失败,则 URL 将打印到 stdout。
代码语言:javascript复制 start
代码语言:javascript复制 --start
启动 httpd 实例并退出。根据需要重新生成配置文件以生成新实例。
代码语言:javascript复制 stop
代码语言:javascript复制 --stop
停止 httpd 实例并退出。这不会生成任何用于生成新实例的配置文件,也不会关闭浏览器。
代码语言:javascript复制 restart
代码语言:javascript复制 --restart
重新启动 httpd 实例并退出。根据需要重新生成配置文件以生成新实例。
组态
您可以在.git / config 中指定配置
代码语言:javascript复制[instaweb]
local = true
httpd = apache2 -f
port = 4321
browser = konqueror
modulePath = /usr/lib/apache2/modules
如果未设置配置变量instaweb.browser
,则在定义时将使用web.browser
。有关详细信息,请参阅 git-web {litdd}浏览[1] 。
也可以看看
gitweb [1]
GIT
部分 git [1] 套件
git-archive
原文:
git-scm.com/docs/git-archive
名称
git-archive - 从命名树创建文件存档
概要
代码语言:javascript复制git archive [--format=<fmt>] [--list] [--prefix=<prefix>/] [<extra>]
[-o <file> | --output=<file>] [--worktree-attributes]
[--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish>
[<path>…]
描述
创建包含指定树的树结构的指定格式的存档,并将其写入标准输出。如果<前缀>指定它被添加到存档中的文件名前面。
git archive 在给定树 ID 时与给定提交 ID 或标记 ID 时的行为不同。在第一种情况下,当前时间用作存档中每个文件的修改时间。在后一种情况下,使用引用的提交对象中记录的提交时间。另外,如果使用 tar 格式,则提交 ID 存储在全局扩展 pax 头中;它可以使用 git get-tar-commit-id 提取。在 ZIP 文件中,它存储为文件注释。
OPTIONS
代码语言:javascript复制 --format=<fmt>
生成的存档的格式: tar 或 zip 。如果未给出此选项,并且指定了输出文件,则尽可能从文件名推断格式(例如,写入“foo.zip”使输出为 zip 格式)。否则输出格式为tar
。
-l
代码语言:javascript复制 --list
显示所有可用格式。
代码语言:javascript复制 -v
代码语言:javascript复制 --verbose
向 stderr 报告进度。
代码语言:javascript复制 --prefix=<prefix>/
将<前缀> /前置到存档中的每个文件名。
代码语言:javascript复制 -o <file>
代码语言:javascript复制 --output=<file>
将存档写入< file>而不是 stdout。
代码语言:javascript复制 --worktree-attributes
在工作树中查找.gitattributes 文件中的属性(参见 ATTRIBUTES )。
代码语言:javascript复制 <extra>
这可以是归档后端理解的任何选项。见下一节。
代码语言:javascript复制 --remote=<repo>
而不是从本地存储库创建 tar 存档,从远程存储库中检索 tar 存档。请注意,远程存储库可能会限制<tree-ish>
中允许哪些 sha1 表达式。有关详细信息,请参阅 git-upload-archive [1] 。
--exec=<git-upload-archive>
与–remote 一起使用以指定远程端的 git-upload-archive 的路径。
代码语言:javascript复制 <tree-ish>
树或承诺为其生成存档。
代码语言:javascript复制 <path>
如果没有可选的路径参数,则当前工作目录的所有文件和子目录都将包含在存档中。如果指定了一个或多个路径,则仅包括这些路径。
备用额外选项
压缩
代码语言:javascript复制 -0
存储文件而不是缩小文件。
代码语言:javascript复制 -9
最高和最慢的压缩级别。您可以指定 1 到 9 之间的任意数字来调整压缩速度和比率。
组态
代码语言:javascript复制 tar.umask
此变量可用于限制 tar 存档条目的权限位。默认值为 0002,关闭世界写入位。特殊值“user”表示将使用归档用户的 umask。有关详细信息,请参阅 umask(2)。如果使用--remote
,则只有远程存储库的配置生效。
tar.<format>.command
此变量指定一个 shell 命令,通过该命令管道git archive
生成的 tar 输出。该命令是使用 shell 在其标准输入上生成的 tar 文件执行的,并应在其标准输出上生成最终输出。任何压缩级选项都将传递给命令(例如,“ - 9”)。如果没有给出其他格式,则与<format>
具有相同扩展名的输出文件将使用此格式。
“tar.gz”和“tgz”格式是自动定义的,默认为gzip -cn
。您可以使用自定义命令覆盖它们。
tar.<format>.remote
如果为 true,则启用<format>
以供远程客户端通过 git-upload-archive [1] 使用。对于用户定义的格式,默认为 false,但对于“tar.gz”和“tgz”格式,则为 true。
ATTRIBUTES
代码语言:javascript复制 export-ignore
具有 export-ignore 属性的文件和目录不会添加到存档文件中。有关详细信息,请参阅 gitattributes [5] 。
代码语言:javascript复制 export-subst
如果为文件设置了 export-subst 属性,那么在将此文件添加到存档时,Git 将展开多个占位符。有关详细信息,请参阅 gitattributes [5] 。
请注意,默认情况下,属性取自正在归档的树中的.gitattributes
文件。如果您想调整事后生成输出的方式(例如,您在.gitattributes
中未添加适当的 export-ignore 而提交),请根据需要调整签出的.gitattributes
文件并使用--worktree-attributes
选项。或者,您可以在归档$GIT_DIR/info/attributes
文件中的任何树时保留应该应用的必要属性。
例子
代码语言:javascript复制 git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)
创建一个 tar 存档,其中包含当前分支上最新提交的内容,并将其解压缩到/var/tmp/junk
目录中。
git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz
为 v1.4.0 版本创建压缩的 tarball。
代码语言:javascript复制 git archive --format=tar.gz --prefix=git-1.4.0/ v1.4.0 >git-1.4.0.tar.gz
与上面相同,但使用内置的 tar.gz 处理。
代码语言:javascript复制 git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
与上面相同,但是从输出文件中推断出格式。
代码语言:javascript复制 git archive --format=tar --prefix=git-1.4.0/ v1.4.0^{tree} | gzip >git-1.4.0.tar.gz
为 v1.4.0 发行版创建压缩的 tarball,但没有全局扩展的 pax 标头。
代码语言:javascript复制 git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs.zip
将当前头文档/目录中的所有内容放入 git-1.4.0-docs.zip ,前缀为 git-docs / 。
代码语言:javascript复制 git archive -o latest.zip HEAD
创建一个 Zip 存档,其中包含当前分支上最新提交的内容。请注意,输出格式是由输出文件的扩展名推断的。
代码语言:javascript复制 git config tar.tar.xz.command "xz -c"
配置“tar.xz”格式以生成 LZMA 压缩的 tarfiles。您可以使用它指定--format=tar.xz
,或创建类似-o foo.tar.xz
的输出文件。
也可以看看
gitattributes [5]
GIT
部分 git [1] 套件
git-bundle
原文:
git-scm.com/docs/git-bundle
名称
git-bundle - 通过归档移动对象和引用
概要
代码语言:javascript复制git bundle create <file> <git-rev-list-args>
git bundle verify <file>
git bundle list-heads <file> [<refname>…]
git bundle unbundle <file> [<refname>…]
描述
某些工作流程要求在一台计算机上的一个或多个开发分支在另一台计算机上复制,但这两台计算机无法直接连接,因此无法使用交互式 Git 协议(git,ssh,http)。此命令支持 git fetch 和 git pull 通过在原始机器的存档中打包对象和引用来操作,然后使用 git fetch 将它们导入另一个存储库通过某种方式(例如,通过 sneakernet)移动存档后,HTG5]和 git pull 。由于存储库之间不存在直接连接,因此用户必须为目标存储库保存的包指定基础:包假定基础中的所有对象都已存在于目标存储库中。
OPTIONS
代码语言:javascript复制 create <file>
用于创建名为 _ 文件 _ 的包。这需要 git-rev-list-args 参数来定义包内容。
代码语言:javascript复制 verify <file>
用于检查捆绑包文件是否有效,并将干净地应用于当前存储库。这包括检查 bundle 格式本身以及检查先决条件提交是否存在并在当前存储库中完全链接。 git bundle 打印缺失提交列表(如果有),并以非零状态退出。
代码语言:javascript复制 list-heads <file>
列出捆绑中定义的引用。如果后跟一个引用列表,则只打印出与给定引用匹配的引用。
代码语言:javascript复制 unbundle <file>
将包中的对象传递给 git index-pack 以存储在存储库中,然后打印所有已定义引用的名称。如果给出了引用列表,则仅打印与列表中的引用匹配的引用。这个命令实际上是管道,只能由 git fetch 调用。
代码语言:javascript复制 <git-rev-list-args>
git rev-parse 和 git rev-list (包含命名 ref,参见下面的 SPECIFYING REFERENCES)可接受的参数列表,用于指定特定对象和对传输的引用。例如,master~10..master
导致当前主引用与自其第 10 个祖先提交以来添加的所有对象一起打包。可以打包的引用和对象的数量没有明确的限制。
[<refname>…]
用于限制报告为可用的引用的引用列表。这主要用于 git fetch ,它希望只接收那些被请求的引用,而不一定是包中的所有东西(在这种情况下, git bundle 就像 git fetch-pack )。
指定参考
git bundle 只会打包由 git show-ref 显示的引用:这包括头部,标签和远程头部。诸如master~1
之类的参考文献无法打包,但非常适合定义基础。可以打包多个参考,并且可以指定多个参考。包装的对象是未包含在给定碱基的联合中的对象。每个基础可以明确指定(例如^master~10
),或隐式指定(例如master~10..master
,--since=10.days.ago master
)。
目的地使用的基础非常重要。可以谨慎行事,导致捆绑文件包含目标中已有的对象,因为在目的地解包时会忽略这些对象。
例子
假设您要将历史记录从计算机 A 上的存储库 R1 传输到计算机 B 上的另一个存储库 R2。无论出于何种原因,不允许 A 和 B 之间的直接连接,但我们可以通过某种机制将数据从 A 移动到 B. ,电子邮件等)。我们希望通过在 R1 中的分支主机上进行的开发来更新 R2。
要引导该进程,您可以先创建一个没有任何基础的包。您可以使用标记记住上次处理的提交,以便以后使用增量包更新其他存储库:
代码语言:javascript复制machineA$ cd R1
machineA$ git bundle create file.bundle master
machineA$ git tag -f lastR2bundle master
然后将 file.bundle 传输到目标机器 B.由于此捆绑包不需要提取任何现有对象,因此可以通过克隆从机器 B 上创建新的存储库:
代码语言:javascript复制machineB$ git clone -b master /home/me/tmp/file.bundle R2
这将在结果存储库中定义一个名为“origin”的远程,它允许您从包中获取和提取。 R2 中的$ GIT_DIR / config 文件将具有如下条目:
代码语言:javascript复制[remote "origin"]
url = /home/me/tmp/file.bundle
fetch = refs/heads/*:refs/remotes/origin/*
要更新生成的 mine.git 存储库,可以在使用增量更新替换存储在/home/me/tmp/file.bundle 中的软件包之后进行提取或提取。
在原始存储库中进行更多工作之后,您可以创建增量包以更新其他存储库:
代码语言:javascript复制machineA$ cd R1
machineA$ git bundle create file.bundle lastR2bundle..master
machineA$ git tag -f lastR2bundle master
然后将捆绑包转移到另一台机器上以替换/home/me/tmp/file.bundle,并从中拉出。
代码语言:javascript复制machineB$ cd R2
machineB$ git pull
如果您知道预期的收件人存储库应该具有必要的对象的提交,您可以使用该知识来指定基础,给出一个截止点来限制生成的包中的修订和对象。前面的示例使用 lastR2bundle 标记用于此目的,但您可以使用您将为 git-log [1] 命令提供的任何其他选项。以下是更多示例:
您可以使用两者中都存在的标记:
代码语言:javascript复制$ git bundle create mybundle v1.0.0..master
您可以根据时间使用基础:
代码语言:javascript复制$ git bundle create mybundle --since=10.days master
您可以使用提交次数:
代码语言:javascript复制$ git bundle create mybundle -10 master
您可以运行git-bundle verify
以查看是否可以从使用基础创建的包中提取:
$ git bundle verify mybundle
这将列出您必须具有的提交以从包中提取,如果您没有它们将会出错。
从收件人存储库的角度来看,捆绑包就像它从中取出或取出的常规存储库。例如,您可以在获取时映射引用:
代码语言:javascript复制$ git fetch mybundle master:localRef
您还可以查看它提供的参考资料:
代码语言:javascript复制$ git ls-remote mybundle
GIT
部分 git [1] 套件