设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.42.1 → 2.50.1 无变化
-
2.42.0
2023-08-21
- 2.39.4 → 2.41.3 无更改
-
2.39.3
2023-04-17
- 2.39.1 → 2.39.2 无更改
-
2.39.0
2022-12-12
- 2.37.3 → 2.38.5 无更改
-
2.37.2
2022-08-11
- 2.33.1 → 2.37.1 无更改
-
2.33.0
2021-08-16
- 2.29.1 → 2.32.7 无更改
-
2.29.0
2020-10-19
- 2.27.1 → 2.28.1 无变更
-
2.27.0
2020-06-01
- 2.23.1 → 2.26.3 无更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 无更改
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 无更改
-
2.20.0
2018-12-09
- 2.19.1 → 2.19.6 无更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 无更改
-
2.18.0
2018-06-21
- 2.17.0 → 2.17.6 无更改
-
2.16.6
2019-12-06
- 2.14.6 → 2.15.4 无变更
-
2.13.7
2018-05-22
- 2.12.5 无更改
-
2.11.4
2017-09-22
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.7.6 无更改
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
- 2.2.3 → 2.4.12 无更改
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
描述
许多 Git 命令都接受修订版本参数作为参数。根据命令的不同,它们可以表示特定的提交,或者对于遍历修订图的命令(例如 git-log[1]),它们表示从该提交可到达的所有提交。对于遍历修订图的命令,也可以显式指定一个修订版本范围。
此外,一些 Git 命令(例如 git-show[1] 和 git-push[1])也可以接受表示除提交以外的其他对象的修订版本参数,例如 blob(“文件”)或 tree(“文件目录”)。
指定修订版本
修订版本参数 <rev> 通常(但不总是)命名一个提交对象。它使用所谓的“扩展 SHA-1”语法。以下是表示对象名称的各种方式。列表中靠近末尾的那些方式命名了提交中包含的 tree 和 blob。
注意
|
本文档展示了 Git 所见的“原始”语法。shell 和其他 UI 可能需要额外的引用来保护特殊字符并避免单词拆分。 |
- <sha1>,例如 dae86e1950b1277e545cee180551750029cfe735、dae86e
-
完整的 SHA-1 对象名称(40字节十六进制字符串),或在仓库中唯一的前导子字符串。例如,如果仓库中没有其他对象名称以 `dae86e` 开头,那么 `dae86e1950b1277e545cee180551750029cfe735` 和 `dae86e` 都指向相同的提交对象。
- <describeOutput>,例如 v1.7.4.2-679-g3bee7fb
-
git
describe
的输出;即最近的标签,后面可选地跟一个短划线和提交数量,再跟一个短划线、一个 g 和一个缩写对象名称。 - <refname>,例如 master、heads/master、refs/heads/master
-
一个符号引用名称。例如,master 通常指 refs/heads/master 所引用的提交对象。如果你碰巧同时有 heads/master 和 tags/master,你可以明确地写 heads/master 来告诉 Git 你指的是哪一个。当存在歧义时,<refname> 会通过以下规则中的第一个匹配项进行消除歧义:
-
如果 $GIT_DIR/<refname> 存在,这就是你所指的(这通常只对
HEAD
、FETCH_HEAD
、ORIG_HEAD
、MERGE_HEAD
、REBASE_HEAD
、REVERT_HEAD
、CHERRY_PICK_HEAD
、BISECT_HEAD
和AUTO_MERGE
有用); -
否则,如果 refs/<refname> 存在;
-
否则,如果 refs/tags/<refname> 存在;
-
否则,如果 refs/heads/<refname> 存在;
-
否则,如果 refs/remotes/<refname> 存在;
-
否则,如果 refs/remotes/<refname>/HEAD 存在。
HEAD
-
命名了你在工作树中基于其进行更改的提交。
FETCH_HEAD
-
记录了你上次调用
git
fetch
从远程仓库拉取的(fetched)分支。 ORIG_HEAD
-
由大幅度移动 `HEAD` 的命令(
git
am
、git
merge
、git
rebase
、git
reset
)创建,用于记录操作前HEAD
的位置,以便你可以轻松地将分支的尖端(tip)恢复到运行这些命令之前的状态。 MERGE_HEAD
-
当你运行
git
merge
时,记录了你正在合并到你的分支中的提交。 REBASE_HEAD
-
在 rebase 过程中,记录了当前操作停止时的提交,原因可能是冲突或交互式 rebase 中的
edit
命令。 REVERT_HEAD
-
当你运行
git
revert
时,记录了你正在还原的提交。 CHERRY_PICK_HEAD
-
当你运行
git
cherry-pick
时,记录了你正在 cherry-pick 的提交。 BISECT_HEAD
-
当你运行
git
bisect
--no-checkout
时,记录了当前要测试的提交。 AUTO_MERGE
-
记录了一个 tree 对象,该对象对应于当合并操作导致冲突时,ort 合并策略写入工作树的状态。
请注意,上述任何 refs/* 情况都可以来自
$GIT_DIR/refs
目录或$GIT_DIR/packed-refs
文件。虽然引用名称编码未指定,但首选 UTF-8,因为一些输出处理可能会假定引用名称为 UTF-8。 -
- @
-
@ 仅是
HEAD
的快捷方式。 - [<refname>]@{<date>},例如 master@{yesterday}、HEAD@{5 minutes ago}
-
引用后跟带有日期规范(例如 {yesterday}、{1 month 2 weeks 3 days 1 hour 1 second ago} 或 {1979-02-26 18:30:00})的花括号后缀 @,指定了引用在过去某个时间点的值。此后缀只能紧跟在引用名称之后使用,并且该引用必须具有现有的日志($GIT_DIR/logs/<ref>)。请注意,这会查找你的本地引用在给定时间的状态;例如,你本地 master 分支上周有什么。如果你想查看在特定时间段内进行的提交,请参阅
--since
和--until
。 - <refname>@{<n>},例如 master@{1}
-
引用后跟带有序数规范(例如 {1}、{15})的花括号后缀 @,指定了该引用的第 n 个先前值。例如,master@{1} 是 master 的紧邻先前值,而 master@{5} 是 master 的第 5 个先前值。此后缀只能紧跟在引用名称之后使用,并且该引用必须具有现有的日志($GIT_DIR/logs/<refname>)。
- @{<n>},例如 @{1}
-
你可以使用带有空引用部分的 @ 结构来获取当前分支的 reflog 条目。例如,如果你在分支 blabla 上,那么 @{1} 与 blabla@{1} 含义相同。
- @{-<n>},例如 @{-1}
-
构造 @{-<n>} 表示当前分支/提交之前检出的第 <n> 个分支/提交。
- [<branchname>]@{upstream},例如 master@{upstream}、@{u}
-
分支 B 可以设置为基于远程 R(通过
branch.
<name>.remote
配置)上的分支 X(通过branch.
<name>.merge
配置)进行构建。B@{u}
指的是从远程 R 获取的分支 X 的远程跟踪分支,通常位于refs/remotes/R/X
。 - [<branchname>]@{push},例如 master@{push}、@{push}
-
后缀 @{push} 报告了如果
git
push
被运行而branchname
被检出时(如果未指定分支名称则为当前的HEAD
),“我们将推送到的”分支。与 @{upstream} 类似,我们报告了远程上与该分支对应的远程跟踪分支。以下是一个更清晰的例子:
$ git config push.default current $ git config remote.pushdefault myfork $ git switch -c mybranch origin/master $ git rev-parse --symbolic-full-name @{upstream} refs/remotes/origin/master $ git rev-parse --symbolic-full-name @{push} refs/remotes/myfork/mybranch
请注意,在示例中我们设置了一个三角形工作流,即从一个位置拉取(pull)并推送到另一个位置。在非三角形工作流中,@{push} 与 @{upstream} 相同,因此没有必要使用它。
该后缀在大小写方面均可接受,并且无论大小写如何,含义都相同。
- <rev>^[<n>],例如 HEAD^、v1.5.1^0
-
修订版本参数后的后缀 ^ 表示该提交对象的第一个父级。^<n> 表示第 <n> 个父级(即 <rev>^ 等同于 <rev>^1)。作为一条特殊规则,<rev>^0 表示提交本身,并且当 <rev> 是引用提交对象的标签对象的名称时使用。
- <rev>~[<n>],例如 HEAD~、master~3
-
修订版本参数后的后缀 ~ 表示该提交对象的第一个父级。修订版本参数后的后缀 ~<n> 表示指定提交对象的第 <n> 代祖先提交对象,只跟随第一个父级。即 <rev>~3 等同于 <rev>^^^,后者又等同于 <rev>^1^1^1。有关此形式用法的说明,请参见下文。
- <rev>^{<type>},例如 v0.99.8^{commit}
-
后缀 ^ 后跟一对花括号中包含的对象类型名称,表示递归地解引用 <rev> 处的对象,直到找到类型为 <type> 的对象,或者该对象无法再被解引用为止(在这种情况下,将报错)。例如,如果 <rev> 是一个 commit-ish,<rev>^{commit} 描述了相应的提交对象。类似地,如果 <rev> 是一个 tree-ish,<rev>^{tree} 描述了相应的 tree 对象。<rev>^0 是 <rev>^{commit} 的简写。
<rev>^{object} 可用于确保 <rev> 命名了一个存在的对象,而无需 <rev> 是一个标签,也无需解引用 <rev>;因为标签本身就是一个对象,它甚至无需解引用就能得到一个对象。
<rev>^{tag} 可用于确保 <rev> 识别一个现有的标签对象。
- <rev>^{},例如 v0.99.8^{}
-
后缀 ^ 后跟一对空花括号,表示该对象可能是一个标签,并递归解引用该标签,直到找到一个非标签对象。
- <rev>^{/<text>},例如 HEAD^{/fix nasty bug}
-
修订版本参数后的后缀 ^,后跟一对包含以斜杠开头的文本的花括号,其含义与下面 :/fix nasty bug 语法相同,不同之处在于它返回的是在 ^ 之前从 <rev> 可达到的最新匹配提交。
- :/<text>,例如 :/fix nasty bug
-
冒号后跟斜杠,再后跟文本,命名一个提交,其提交消息与指定的正则表达式匹配。此名称返回从任何引用(包括 HEAD)可到达的最新匹配提交。正则表达式可以匹配提交消息的任何部分。要匹配以某个字符串开头的消息,可以使用例如 :/^foo。特殊序列 :/! 保留用于匹配内容的修饰符。:/!-foo 执行否定匹配,而 :/!!foo 匹配字面字符 !,后跟 foo。任何其他以 :/! 开头的序列目前都保留。根据给定的文本,shell 的单词拆分规则可能需要额外的引用。
- <rev>:<path>,例如 HEAD:README、master:./README
-
后缀 : 后跟路径,命名了冒号前部分所命名的 tree-ish 对象中给定路径处的 blob 或 tree。以 ./ 或 ../ 开头的路径是相对于当前工作目录的。给定的路径将被转换为相对于工作树的根目录。这在从具有与工作树相同树结构的提交或树中引用 blob 或 tree 时最有用。
- :[<n>:]<path>,例如 :0:README、:README
-
冒号,可选地后跟一个阶段编号(0到3)和一个冒号,再后跟路径,命名了索引中给定路径处的 blob 对象。缺失阶段编号(及其后的冒号)表示阶段 0 条目。在合并期间,阶段 1 是共同祖先,阶段 2 是目标分支的版本(通常是当前分支),阶段 3 是正在合并的分支的版本。
以下是 Jon Loeliger 的一个图示。提交节点 B 和 C 都是提交节点 A 的父级。父级提交按从左到右的顺序排列。
G H I J \ / \ / D E F \ | / \ \ | / | \|/ | B C \ / \ / A
A = = A^0 B = A^ = A^1 = A~1 C = = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^2 F = B^3 = A^^3 G = A^^^ = A^1^1^1 = A~3 H = D^2 = B^^2 = A^^^2 = A~2^2 I = F^ = B^3^ = A^^3^ J = F^2 = B^3^2 = A^^3^2
指定范围
历史遍历命令(例如 git
log
)对一组提交进行操作,而不仅仅是单个提交。
对于这些命令,使用前一节中描述的符号指定单个修订版本,意味着从给定提交可到达的提交集合。
指定多个修订版本意味着从任何给定提交可到达的提交集合。
提交的可达集合是提交本身及其祖先链中的提交。
有几种表示一组相互关联的提交(称为“修订版本范围”)的符号,如下所示。
点式范围表示法
在这两种简写表示法中,你可以省略一端,使其默认为 HEAD。例如,origin.. 是 origin..HEAD 的简写,它表示“自从我从 origin 分支分叉以来我做了什么?”。类似地,..origin 是 HEAD..origin 的简写,它表示“自从我从他们那里分叉以来 origin 做了什么?”。请注意,.. 将表示 HEAD..HEAD,这是一个既可从 HEAD 到达又不可从 HEAD 到达的空范围。
专门设计用于接受两个不同范围的命令(例如“`git range-diff R1 R2`”用于比较两个范围)确实存在,但它们是例外。除非另有说明,所有对一组提交进行操作的“git”命令都在单个修订版本范围内工作。换句话说,将两个“两点范围表示法”并排书写,例如
$ git log A..B C..D
对于大多数命令,**不会**指定两个修订版本范围。相反,它会命名一个单一的连接提交集合,即那些可以从 B 或 D 到达但不能同时从 A 或 C 到达的提交。在像这样的线性历史中
---A---B---o---o---C---D
因为 A 和 B 可以从 C 到达,所以这两个点式范围指定的修订版本范围是单个提交 D。
其他 <rev>^ 父级简写表示法
存在另外三种简写形式,特别适用于合并提交,用于命名由一个提交及其父级提交组成的集合。
r1^@ 表示法意味着 r1 的所有父级。
r1^! 表示法包括提交 r1 但排除其所有父级。就其本身而言,此表示法表示单个提交 r1。
<rev>^-[<n>] 表示法包括 <rev> 但排除第 <n> 个父级(即 <rev>^<n>..<rev> 的简写),如果未给出 <n>,则 <n> = 1。这通常对于合并提交很有用,你可以只传递 <commit>^- 来获取在合并提交 <commit> 中合并的所有分支提交(包括 <commit> 本身)。
尽管 <rev>^<n> 是关于指定单个提交父级,但这三种表示法也考虑其父级。例如,你可以说 HEAD^2^@,但你不能说 HEAD^@^2。
修订版本范围总结
- <rev>
-
包括从 <rev> 可到达的提交(即 <rev> 及其祖先)。
- ^<rev>
-
排除从 <rev> 可到达的提交(即 <rev> 及其祖先)。
- <rev1>..<rev2>
-
包括从 <rev2> 可到达但排除从 <rev1> 可到达的提交。当 <rev1> 或 <rev2> 被省略时,它默认为
HEAD
。 - <rev1>...<rev2>
-
包括从 <rev1> 或 <rev2> 之一可到达但排除从两者都可到达的提交。当 <rev1> 或 <rev2> 被省略时,它默认为
HEAD
。 - <rev>^@,例如 HEAD^@
-
后缀 ^ 后跟一个“@”符号,与列出 <rev> 的所有父级相同(意思是,包括从其父级可到达的所有内容,但不包括提交本身)。
- <rev>^!,例如 HEAD^!
-
后缀 ^ 后跟一个感叹号,与给出提交 <rev> 及其所有父级(以 ^ 为前缀以排除它们及其祖先)相同。
- <rev>^-<n>,例如 HEAD^-、HEAD^-2
-
等同于 <rev>^<n>..<rev>,如果未给出 <n>,则 <n> = 1。
以下是一些使用上面 Loeliger 图示的例子,其中表示法的每个展开和选择步骤都详细阐述:
Args Expanded arguments Selected commits D G H D D F G H I J D F ^G D H D ^D B E I J F B ^D B C E I J F B C C I J F C B..C = ^B C C B...C = B ^F C G H D E B C B^- = B^..B = ^B^1 B E I J F B C^@ = C^1 = F I J F B^@ = B^1 B^2 B^3 = D E F D G H E F I J C^! = C ^C^@ = C ^C^1 = C ^F C B^! = B ^B^@ = B ^B^1 ^B^2 ^B^3 = B ^D ^E ^F B F^! D = F ^I ^J D G H D F