设置和配置
获取和创建项目
基本快照
分支与合并
共享和更新项目
检查和比较
打补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
-
2.53.0
2026-02-02
-
2.52.0
2025-11-17
- 2.51.1 → 2.51.2 无更改
-
2.51.0
2025-08-18
- 2.50.1 无更改
-
2.50.0
2025-06-16
- 2.47.2 → 2.49.1 无变更
-
2.47.1
2024-11-25
- 2.44.1 → 2.47.0 无变更
-
2.44.0
2024-02-23
- 2.43.2 → 2.43.7 无变更
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.41.1 → 2.42.4 无更改
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 无更改
-
2.40.0
2023-03-12
- 2.39.4 → 2.39.5 无更改
-
2.39.3
2023-04-17
- 2.38.1 → 2.39.2 无更改
-
2.38.0
2022-10-02
- 2.35.1 → 2.37.7 无更改
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 无更改
-
2.34.0
2021-11-15
- 2.30.1 → 2.33.8 无变更
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 无更改
-
2.29.0
2020-10-19
- 2.27.1 → 2.28.1 无变更
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 无更改
-
2.25.0
2020-01-13
- 2.23.1 → 2.24.4 无更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 无更改
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 无更改
-
2.21.0
2019-02-24
- 2.19.3 → 2.20.5 无更改
-
2.19.2
2018-11-21
- 2.19.1 无更改
-
2.19.0
2018-09-10
- 2.17.0 → 2.18.5 无更改
-
2.16.6
2019-12-06
- 2.15.4 无更改
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
- 2.11.4 → 2.12.5 无变更
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.8.6 无更改
-
2.7.6
2017-07-30
- 2.6.7 无更改
-
2.5.6
2017-05-05
-
2.4.12
2017-05-05
- 2.1.4 → 2.3.10 无更改
-
2.0.5
2014-12-17
概要
gitcheckout[-q] [-f] [-m] [<branch>]gitcheckout[-q] [-f] [-m]--detach[<branch>]gitcheckout[-q] [-f] [-m] [--detach] <commit>gitcheckout[-q] [-f] [-m] [[-b|-B|--orphan] <new-branch>] [<start-point>]gitcheckout<tree-ish> [--] <pathspec>…gitcheckout<tree-ish>--pathspec-from-file=<file> [--pathspec-file-nul]gitcheckout[-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>…gitcheckout[-f|--ours|--theirs|-m|--conflict=<style>]--pathspec-from-file=<file> [--pathspec-file-nul]gitcheckout(-p|--patch) [<tree-ish>] [--] [<pathspec>…]
描述
git checkout 有两种主要模式
-
切换分支,使用
gitcheckout<分支> -
恢复文件的不同版本,例如使用
gitcheckout<提交> <文件名> 或gitcheckout<文件名>
关于 Git 如何决定执行哪种操作,请参阅下文的“参数消歧”。
gitcheckout[<分支>]-
切换到 <分支>。这会将当前分支设置为 <分支> 并更新工作目录中的文件。如果 <分支> 与当前提交内容不同的任何文件存在未提交的更改,检出将失败。否则,未提交的更改将被保留。
如果找不到 <分支>,但在恰好一个远程库(称为 <远程库>)中存在名称匹配的跟踪分支,且未指定
--no-guess,则视为等同于:$ git checkout -b <branch> --track <remote>/<branch>
运行不指定分支的
gitcheckout除了打印当前分支的跟踪信息外,没有任何效果。 gitcheckout-b<新分支> [<起始点>]-
创建一个名为 <新分支> 的新分支,从 <起始点>(默认为当前提交)开始,并检出该新分支。可以使用
--track或--no-track选项来设置分支的上游跟踪信息。如果检出 <新分支> 出错(例如检出 <起始点> 提交会覆盖未提交的更改),操作将失败。
gitcheckout-B<分支> [<起始点>]-
与
-b相同,区别在于如果分支已存在,它会将 <分支> 重置到起始点,而不是报错失败。 gitcheckout--detach[<分支>]gitcheckout[--detach] <提交>-
与
gitcheckout<分支> 相同,但它不将HEAD指向分支,而是将HEAD指向提交 ID。更多信息请参阅下文的“分离头指针”部分。省略 <分支> 会在当前分支的末梢分离
HEAD。 gitcheckout<树对象> [--] <路径规范>...gitcheckout<树对象>--pathspec-from-file=<文件> [--pathspec-file-nul]-
将指定的文件和/或目录替换为给定提交或树对象中的版本,并将其添加到索引(也称为“暂存区”)。
例如,
gitcheckoutmainfile.txt将用main分支中的版本替换file.txt。 gitcheckout[-f|--ours|--theirs|-m|--conflict=<样式>] [--] <路径规范>...gitcheckout[-f|--ours|--theirs|-m|--conflict=<样式>]--pathspec-from-file=<文件> [--pathspec-file-nul]-
用索引中的版本替换指定的文件和/或目录。
例如,如果您检出一个提交,编辑了
file.txt,然后觉得这些修改是个错误,gitcheckoutfile.txt将丢弃对file.txt的任何未暂存更改。如果文件存在合并冲突且您尚未运行
gitaddfile.txt(或等效操作)将其标记为已解决,则此操作将失败。您可以使用-f来忽略未合并文件而不是报错,使用--ours或--theirs将其替换为合并中特定一方的版本,或使用-m将其替换为原始冲突合并结果。 gitcheckout(-p|--patch) [<树对象>] [--] [<路径规范>...]-
这与前两种模式类似,但允许您使用交互式界面查看“diff”输出并选择要在结果中使用的区块(hunks)。请参阅下文关于
--patch选项的描述。
选项
-q--quiet-
安静模式,抑制反馈消息。
--progress--no-progress-
默认情况下,如果进度状态流被连接到终端,则进度状态会显示在标准错误流上,除非指定了
--quiet。此标志即使未连接到终端也会启用进度报告,无论--quiet如何。 -f--force-
切换分支时,即使索引或工作区与
HEAD不同,甚至存在阻碍操作的未跟踪文件,也要继续进行。这用于丢弃本地修改以及任何碍事的未跟踪文件或目录。从索引检出路径时,不要因未合并的条目而失败;相反,未合并的条目会被忽略。
--ours--theirs-
从索引检出路径时,针对未合并的路径检出暂存区 #2 (
ours) 或 #3 (theirs)。请注意,在
gitrebase和gitpull--rebase期间,ours和theirs可能会出现反转;--ours提供更改被变基到的分支版本,而--theirs提供您正在变基的工作分支版本。这是因为
rebase用于将远程历史视为共享规范历史的工作流中,并将您变基的分支上的工作视为待集成的第三方工作,而在变基期间您临时承担了规范历史维护者的角色。作为规范历史维护者,您需要将远程历史视为ours(即“我们共享的规范历史”),而将您在侧边分支上的工作视为theirs(即“某个贡献者在其上的工作”)。 -b<新分支>-
创建一个名为 <新分支> 的新分支,从 <起始点> 开始,并检出结果分支;详情请参阅 git-branch[1]。
-B<新分支>-
与
-b相同,区别在于如果分支已存在,它会将 <分支> 重置到起始点,而不是报错失败。 -t--track[=(direct|inherit)]-
创建新分支时,设置“上游”配置。详情请参阅 git-branch[1] 中的
--track。为了方便,不带 -b 的 --track 暗含创建分支的操作。如果未给出
-b选项,新分支的名称将通过查看相应远程库配置的引用规范的本地部分,并剥离直到 “*” 的初始部分,从而从远程跟踪分支派生。这将告诉我们在从origin/hack(或remotes/origin/hack,甚至是refs/remotes/origin/hack)分叉时使用hack作为本地分支。如果给定名称没有斜杠,或者上述猜测导致名称为空,则放弃猜测。在这种情况下,您可以使用-b显式指定名称。 --no-track-
即使
branch.autoSetupMerge配置变量为 true,也不设置“上游”配置。 --guess--no-guess-
如果找不到 <分支>,但在恰好一个远程库(称为 <远程库>)中存在名称匹配的跟踪分支,则视为等同于:
$ git checkout -b <branch> --track <remote>/<branch>
如果该分支存在于多个远程库中,且其中一个被
checkout.defaultRemote配置变量命名,我们将使用该远程库进行消歧,即使 <分支> 在所有远程库中并不唯一。例如设置为checkout.defaultRemote=origin,以便在 <分支> 模棱两可但在 origin 远程库上存在时,总是从那里检出远程分支。另请参阅 git-config[1] 中的checkout.defaultRemote。--guess是默认行为。使用--no-guess禁用它。默认行为可以通过
checkout.guess配置变量进行设置。 -l-
创建新分支的引用日志 (reflog);详情请参阅 git-branch[1]。
-d--detach-
与其检出一个分支来在其上工作,不如检出一个提交用于检查和可丢弃的实验。这是当 <提交> 不是分支名称时
gitcheckout<提交> 的默认行为。详情请参阅下文的“分离头指针”部分。 --orphan<新分支>-
创建一个新的“孤儿”分支(未出生的分支),命名为 <新分支>,从 <起始点> 开始并切换到该分支。在这个新分支上进行的第一次提交将没有父提交,它将成为一个全新的历史记录的根,与所有其他分支和提交完全断开。
索引和工作区的调整就像您之前运行了
gitcheckout<起始点> 一样。这允许您通过简单地运行gitcommit-a来进行根提交,从而开始一个记录与 <起始点> 类似路径集的新历史。当您想要发布某个提交中的树而不暴露其完整历史记录时,这很有用。您可能希望这样做来发布一个项目的开源分支,该项目的当前树是“干净”的,但其完整历史记录包含专有或受限的代码段。
如果您想开始一段断开的历史记录,其中记录的路径集与 <起始点> 完全不同,那么您应该在创建孤儿分支后立即通过在工作区顶层运行
gitrm-rf.来清除索引和工作区。之后,您就可以准备新文件,通过从别处复制、提取压缩包等方式重新填充工作区。 --ignore-skip-worktree-bits-
在稀疏检出模式下,
gitcheckout--<路径>... 只会更新与 <路径> 和$GIT_DIR/info/sparse-checkout中的稀疏模式相匹配的条目。此选项忽略稀疏模式并重新添加 <路径>... 中的任何文件。 -m--merge-
切换分支时,如果您对一个或多个文件进行了本地修改,且这些文件在当前分支和目标分支之间存在差异,为了在上下文中保留您的修改,该命令会拒绝切换分支。但是,使用此选项后,会执行当前分支、工作区内容和新分支之间的三方合并,然后您将处于新分支上。
当发生合并冲突时,冲突路径的索引条目将保持未合并状态,您需要解决冲突并使用
gitadd(如果合并结果应该是删除该路径,则使用gitrm)标记已解决的路径。从索引检出路径时,此选项允许您在指定路径中重新创建冲突合并。此选项不能在从树对象检出路径时使用。
使用
--merge切换分支时,暂存的更改可能会丢失。 --conflict=<样式>-
与上面的
--merge选项相同,但会更改冲突块的呈现方式,覆盖merge.conflictStyle配置变量。可能的值包括merge(默认)、diff3和zdiff3。 -p--patch-
在 <树对象>(如果未指定则为索引)与工作区之间的差异中交互式地选择区块。选定的区块随后会反向应用到工作区(如果指定了 <树对象>,则也应用到索引)。
这意味着您可以使用
gitcheckout-p有选择地丢弃当前工作区中的编辑。请参阅 git-add[1] 的“交互模式”部分,了解如何操作--patch模式。请注意,此选项默认使用非覆盖模式(另请参阅
--overlay),且目前不支持覆盖模式。 -U<n>--unified=<n>-
生成具有 <n> 行上下文的 diff。如果配置选项未设置,则默认为
diff.context或 3。 --inter-hunk-context=<n>-
在差异块之间显示上下文,最多达指定行数 <number>,从而合并彼此接近的块。默认为
diff.interHunkContext,如果未设置配置选项则为 0。 --ignore-other-worktrees-
当目标分支已被检出或正由另一个工作区使用时,
gitcheckout会拒绝操作。此选项使其无论如何都会检出该分支。换句话说,该分支可以被多个工作区同时使用。 --overwrite-ignore--no-overwrite-ignore-
切换分支时静默覆盖被忽略的文件。这是默认行为。使用
--no-overwrite-ignore在新分支包含被忽略的文件时中止操作。 --recurse-submodules--no-recurse-submodules-
使用
--recurse-submodules将根据主项目记录的提交更新所有活动子模块的内容。如果子模块中的本地修改会被覆盖,除非使用-f,否则检出将失败。如果不使用任何选项(或使用--no-recurse-submodules),子模块工作树将不会更新。就像 git-submodule[1] 一样,这会分离子模块的HEAD。 --overlay--no-overlay-
在默认的覆盖(overlay)模式下,
gitcheckout永远不会从索引或工作树中删除文件。当指定--no-overlay时,出现在索引和工作树中但不在 <树对象> 中的文件将被删除,以使它们与 <树对象> 完全匹配。 --pathspec-from-file=<文件>-
Pathspec 从 <file> 而不是命令行参数传递。如果 <file> 是
-,则使用标准输入。Pathspec 元素由 LF 或 CR/LF 分隔。Pathspec 元素可以按core.quotePath配置变量的解释进行引用(参见 git-config[1])。另请参见--pathspec-file-nul和全局--literal-pathspecs。 --pathspec-file-nul-
仅在与
--pathspec-from-file一起使用时有意义。路径规范元素由 NUL 字符分隔,所有其他字符都被视为字面值(包括换行符和引号)。 - <分支>
-
要检出的分支;如果它指的是一个分支(即一个在前面加上 "refs/heads/" 后是有效引用的名称),则检出该分支。否则,如果它指向一个有效的提交,您的
HEAD将变为“分离”状态,您不再处于任何分支上(详见下文)。您可以使用
@{-N}语法来引用使用 "git checkout" 操作检出的倒数第 N 个分支/提交。您也可以指定-,它与@{-1}同义。作为特殊情况,如果 <rev-a> 和 <rev-b> 恰好有一个合并基点,您可以使用 <rev-a>
...<rev-b> 作为该合并基点的快捷方式。您最多可以省略 <rev-a> 和 <rev-b> 中的一个,在这种情况下,默认值为HEAD。 - <新分支>
-
新分支的名称。
- <起始点>
-
启动新分支的提交名称;详情请参阅 git-branch[1]。默认为
HEAD。作为特殊情况,如果 <rev-a> 和 <rev-b> 恰好有一个合并基点,您可以使用 <rev-a>
...<rev-b> 作为该合并基点的快捷方式。您最多可以省略 <rev-a> 和 <rev-b> 中的一个,在这种情况下,默认值为HEAD。 - <树对象>
-
从中检出的树(当给出路径时)。如果未指定,将使用索引。
作为特殊情况,如果 <rev-a> 和 <rev-b> 恰好有一个合并基点,您可以使用 <rev-a>
...<rev-b> 作为该合并基点的快捷方式。您最多可以省略 <rev-a> 和 <rev-b> 中的一个,在这种情况下,默认值为HEAD。 ---
不再将任何后续参数解释为选项。
- <路径规范>...
-
限制受操作影响的路径。
有关更多详细信息,请参阅 gitglossary[7] 中的 pathspec 条目。
分离头指针 (DETACHED HEAD)
HEAD 通常指向一个具名分支(例如 master)。同时,每个分支指向一个特定的提交。让我们看一个拥有三个提交的仓库,其中一个带有标签,且检出了 master 分支
HEAD (refers to branch 'master')
|
v
a---b---c branch 'master' (refers to commit 'c')
^
|
tag 'v2.0' (refers to commit 'b')
在此状态下创建提交时,分支会更新以指向新提交。具体来说,git commit 会创建一个新提交 d,其父提交是 c,然后更新 master 分支以指向新提交 d。HEAD 仍然指向 master 分支,因此现在间接地指向了提交 d
$ edit; git add; git commit
HEAD (refers to branch 'master')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
有时,能够检出一个不在任何具名分支末梢的提交,甚至创建一个不被具名分支引用的新提交,是很有用的。让我们看看检出提交 b 时会发生什么(这里展示了两种可行的方法)
$ git checkout v2.0 # or
$ git checkout master^^
HEAD (refers to commit 'b')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
请注意,无论我们使用哪种检出命令,HEAD 现在都直接指向提交 b。这被称为处于分离头指针(detached HEAD)状态。它仅仅意味着 HEAD 指向一个特定的提交,而不是指向一个具名分支。让我们看看当我们创建一个提交时会发生什么
$ edit; git add; git commit
HEAD (refers to commit 'e')
|
v
e
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
现在有了一个新提交 e,但它仅被 HEAD 引用。当然,我们可以在这种状态下再添加一个提交
$ edit; git add; git commit
HEAD (refers to commit 'f')
|
v
e---f
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
事实上,我们可以执行所有正常的 Git 操作。但是,让我们看看当我们随后检出 master 时会发生什么
$ git checkout master
HEAD (refers to branch 'master')
e---f |
/ v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
重要的是要意识到,此时没有任何东西指向提交 f。最终,提交 f(以及延伸出的提交 e)将被常规的 Git 垃圾回收过程删除,除非我们在那之前创建一个引用。如果我们还没有离开提交 f,以下任何操作都会为它创建一个引用
$ git checkout -b foo # or "git switch -c foo" (1) $ git branch foo (2) $ git tag foo (3)
-
创建一个新分支
foo,它指向提交f,然后更新HEAD以指向分支foo。换句话说,执行此命令后我们将不再处于分离头指针状态。 -
同样创建一个新分支
foo指向提交f,但保持HEAD处于分离状态。 -
创建一个新标签
foo指向提交f,保持HEAD处于分离状态。
如果我们已经离开了提交 f,那么我们必须首先恢复它的对象名称(通常通过使用 git reflog),然后我们可以为它创建一个引用。例如,要查看 HEAD 指向的最后两个提交,我们可以使用以下任一命令
$ git reflog -2 HEAD # or $ git log -g -2 HEAD
参数消歧
当您运行 git checkout <内容> 时,Git 会尝试猜测 <内容> 是意指一个分支、一个提交,还是一组文件,然后要么切换到该分支或提交,要么恢复指定的文件。
如果有任何歧义,Git 会将 <内容> 视为分支或提交,但您可以使用双破折号 -- 来强制 Git 将参数视为文件和/或目录列表,如下所示
git checkout -- file.txt
示例
1. 路径
以下序列检出 master 分支,将 Makefile 还原到两个版本前,误删了 hello.c,并从索引中将其找回。
$ git checkout master (1) $ git checkout master~2 Makefile (2) $ rm -f hello.c $ git checkout hello.c (3)
-
切换分支
-
从另一个提交中取出一个文件
-
从索引恢复
hello.c
如果您想从索引中检出 *所有* C 源文件,您可以输入
$ git checkout -- '*.c'
注意 *.c 周围的引号。文件 hello.c 也会被检出,即使它不再处于工作树中,因为文件通配符(globbing)是用于匹配索引中的条目(而不是由 shell 在工作树中匹配)。
如果您不幸有一个名为 hello.c 的分支,这一步会被误认为切换到该分支。您应该改写为
$ git checkout -- hello.c
2. 合并
在错误的分支工作后,切换到正确的分支应该使用
$ git checkout mytopic
然而,您的“错误”分支和正确的 mytopic 分支可能在您本地修改的文件上存在差异,在这种情况下,上述检出会像这样失败
$ git checkout mytopic error: You have local changes to 'frotz'; not switching branches.
您可以给命令加上 -m 标志,这将尝试进行三方合并
$ git checkout -m mytopic Auto-merging frotz
在这次三方合并之后,本地修改 *不会* 注册在您的索引文件中,因此 git diff 会向您展示自新分支末梢以来您所做的更改。
配置
本节中以下所有内容均从 git-config[1] 文档中选择性地包含。内容与彼处相同:
checkout.defaultRemote-
当您运行
gitcheckout<something> 或gitswitch<something> 且只有一个远程时,它可能会隐式地回退到签出和跟踪 e.g.origin/<something>。一旦您有多个具有 *<something>* 引用的远程,这种情况就会停止工作。此设置允许设置一个首选远程的名称,该名称在歧义化时应始终优先。典型用例是将其设置为origin。目前,它由 git-switch[1] 和 git-checkout[1] 使用,当
gitcheckout<something> 或gitswitch<something> 会签出另一个远程上的 *<something>* 分支时,以及由 git-worktree[1] 使用,当gitworktreeadd指的是远程分支时。此设置将来可能会用于其他类似 checkout 的命令或功能。 checkout.guess-
为
git和checkoutgit命令中的switch--guess或--no-guess选项提供默认值。参见 git-switch[1] 和 git-checkout[1]。 checkout.workers-
更新工作树时使用的并行工作进程数量。默认为一个,即顺序执行。如果设置为小于一的值,Git 将使用与可用逻辑核心数相同的数量的工作进程。此设置和
checkout.thresholdForParallelism会影响所有执行 checkout 的命令。例如:checkout、clone、reset、sparse-checkout 等。注意并行 checkout 通常可以提高位于 SSD 或 NFS 上的存储库的性能。对于旋转硬盘和/或核心数较少的机器上的存储库,默认的顺序 checkout 通常性能更好。存储库的大小和压缩级别也可能影响并行版本的性能。 checkout.thresholdForParallelism-
当使用少量文件进行并行 checkout 时,子进程生成和进程间通信的成本可能会超过并行化的收益。此设置允许您定义应尝试并行 checkout 的最小文件数。默认值为 100。