设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.44.1 → 2.47.0 无变更
- 2.44.0 02/23/24
- 2.43.2 → 2.43.5 无变更
- 2.43.1 02/09/24
- 2.43.0 11/20/23
- 2.41.1 → 2.42.3 无变更
- 2.41.0 06/01/23
- 2.40.1 → 2.40.3 无变更
- 2.40.0 03/12/23
- 2.39.4 → 2.39.5 无变更
- 2.39.3 04/17/23
- 2.38.1 → 2.39.2 无变更
- 2.38.0 10/02/22
- 2.35.1 → 2.37.7 无变更
- 2.35.0 01/24/22
- 2.34.1 → 2.34.8 无变更
- 2.34.0 11/15/21
- 2.30.1 → 2.33.8 无变更
- 2.30.0 12/27/20
- 2.29.1 → 2.29.3 无变更
- 2.29.0 10/19/20
- 2.27.1 → 2.28.1 无变更
- 2.27.0 06/01/20
- 2.25.1 → 2.26.3 无变更
- 2.25.0 01/13/20
- 2.23.1 → 2.24.4 无变更
- 2.23.0 08/16/19
- 2.22.1 → 2.22.5 无变更
- 2.22.0 06/07/19
- 2.21.1 → 2.21.4 无变更
- 2.21.0 02/24/19
- 2.19.3 → 2.20.5 无变更
- 2.19.2 11/21/18
- 2.19.1 无变更
- 2.19.0 09/10/18
- 2.17.0 → 2.18.5 无变更
- 2.16.6 12/06/19
- 2.15.4 无变更
- 2.14.6 12/06/19
- 2.13.7 05/22/18
- 2.11.4 → 2.12.5 无变更
- 2.10.5 09/22/17
- 2.9.5 07/30/17
- 2.8.6 无变更
- 2.7.6 07/30/17
- 2.6.7 无变更
- 2.5.6 05/05/17
- 2.4.12 05/05/17
- 2.1.4 → 2.3.10 无变更
- 2.0.5 12/17/14
概要
git checkout [-q] [-f] [-m] [<branch>] git checkout [-q] [-f] [-m] --detach [<branch>] git checkout [-q] [-f] [-m] [--detach] <commit> git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new-branch>] [<start-point>] git checkout [-f] <tree-ish> [--] <pathspec>… git checkout [-f] <tree-ish> --pathspec-from-file=<file> [--pathspec-file-nul] git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>… git checkout [-f|--ours|--theirs|-m|--conflict=<style>] --pathspec-from-file=<file> [--pathspec-file-nul] git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>…]
描述
更新工作树中的文件以匹配索引或指定树中的版本。如果没有给出路径规范,git checkout 也会更新 HEAD
以将指定分支设置为当前分支。
- git checkout [<branch>]
-
要准备在
<branch>
上工作,通过更新索引和工作树中的文件,并将HEAD
指向该分支,切换到该分支。工作树中文件的本地修改将保留,以便可以将它们提交到<branch>
。如果
<branch>
未找到,但只有一个远程分支(称为<remote>
)存在完全匹配的名称并且未指定--no-guess
,则视为等效于$ git checkout -b <branch> --track <remote>/<branch>
你可以省略
<branch>
,在这种情况下,命令退化为“签出当前分支”,这是一个带有一些昂贵副作用的“空操作”,仅显示当前分支的跟踪信息(如果存在)。 - git checkout -b|-B <new-branch> [<start-point>]
-
指定
-b
会导致创建一个新分支,就像调用 git-branch[1] 并将其签出一样。在这种情况下,可以使用--track
或--no-track
选项,这些选项将传递给 git branch。为了方便起见,--track
在没有-b
的情况下表示创建分支;请参阅下面对--track
的描述。如果给出
-B
,则在<new-branch>
不存在的情况下创建<new-branch>
;否则,将重置它。这与以下操作等效:$ git branch -f <branch> [<start-point>] $ git checkout <branch>
也就是说,除非“git checkout”成功,否则分支不会被重置/创建(例如,当分支在另一个工作树中使用时,不仅当前分支保持不变,而且分支也不会被重置到起点)。
- git checkout --detach [<branch>]
- git checkout [--detach] <commit>
-
通过在
<commit>
上分离HEAD
(参见“分离的 HEAD”部分)以及更新索引和工作树中的文件,准备在<commit>
之上工作。工作树中文件的本地修改将保留,因此生成的工作树将是提交中记录的状态加上本地修改。当
<commit>
参数是分支名称时,可以使用--detach
选项在分支的末端分离HEAD
(git checkout <branch>
会签出该分支,但不会分离HEAD
)。省略
<branch>
会在当前分支的末端分离HEAD
。 - git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>…
- git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]
-
覆盖与路径规范匹配的文件的内容。当
<tree-ish>
(通常是提交)未给出时,用索引中的内容覆盖工作树。当给出<tree-ish>
时,用<tree-ish>
的内容覆盖索引和工作树。索引可能包含由于先前合并失败而导致的未合并条目。默认情况下,如果你尝试从索引中签出这样的条目,签出操作将失败,并且不会签出任何内容。使用
-f
将忽略这些未合并的条目。可以使用--ours
或--theirs
从索引中签出合并特定侧面的内容。使用-m
,可以丢弃对工作树文件的更改,以重新创建原始冲突的合并结果。 - git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>…]
-
这类似于前面的模式,但允许你使用交互式界面来显示“diff”输出并选择在结果中使用哪些块。请参阅下面的
--patch
选项说明。
选项
- -q
- --quiet
-
安静,抑制反馈消息。
- --progress
- --no-progress
-
当它附加到终端时,进度状态默认情况下会报告到标准错误流中,除非指定了
--quiet
。此标志即使未附加到终端,也会启用进度报告,无论是否指定了--quiet
。 - -f
- --force
-
在切换分支时,即使索引或工作树与
HEAD
不同,即使有未跟踪的文件存在,也会继续执行。这用于丢弃本地更改以及任何存在的未跟踪文件或目录。在从索引中签出路径时,不要在未合并的条目上失败;相反,将忽略未合并的条目。
- --ours
- --theirs
-
在从索引中签出路径时,签出阶段 #2 (ours) 或 #3 (theirs) 用于未合并的路径。
请注意,在
git rebase
和git pull --rebase
期间,ours 和 theirs 可能会出现颠倒;--ours
提供正在变基到的分支的版本,而--theirs
提供正在变基的包含你工作的分支的版本。这是因为
rebase
用于在将远程视为共享规范历史记录的工作流中,并将你在变基的分支上完成的工作视为要集成的第三方工作,并且在变基过程中你暂时扮演规范历史记录维护者的角色。作为规范历史记录的维护者,你需要将远程的历史记录视为ours
(即“我们共享的规范历史记录”),而将你在你的分支上所做的更改视为theirs
(即“一位贡献者在它之上的工作”)。 - -b <new-branch>
-
创建一个名为
<new-branch>
的新分支,从<start-point>
开始,然后签出生成的分支;有关详细信息,请参见 git-branch[1]。 - -B <new-branch>
-
创建分支
<new-branch>
,从<start-point>
开始;如果该分支已存在,则将其重置为<start-point>
。然后检出结果分支。这等同于运行带有“-f”的“git branch”命令,然后检出该分支;有关详细信息,请参见git-branch[1]。 - -t
- --track[=(direct|inherit)]
-
创建新分支时,设置“上游”配置。有关详细信息,请参见git-branch[1] 中的“--track”。
如果没有给出
-b
选项,则新分支的名称将从远程跟踪分支中推断出来,方法是查看为相应远程配置的 refspec 的本地部分,然后剥离从“*”开始的初始部分。这将告诉我们,当从origin/hack
(或remotes/origin/hack
,甚至refs/remotes/origin/hack
)分支时,使用hack
作为本地分支。如果给定的名称没有斜杠,或者上述猜测导致空名称,则猜测将中止。在这种情况下,您可以使用-b
显式给出名称。 - --no-track
-
即使
branch.autoSetupMerge
配置变量为 true,也不设置“上游”配置。 - --guess
- --no-guess
-
如果找不到
<branch>
,但在一个远程(称为<remote>
)中存在一个具有匹配名称的跟踪分支,则视为等同于$ git checkout -b <branch> --track <remote>/<branch>
如果该分支存在于多个远程中,并且其中一个由
checkout.defaultRemote
配置变量命名,即使<branch>
在所有远程中不唯一,我们也会为了消除歧义而使用该远程。将其设置为例如checkout.defaultRemote=origin
,以始终从那里检出远程分支,如果<branch>
是模棱两可的,但在origin远程上存在。另请参见git-config[1] 中的checkout.defaultRemote
。--guess
是默认行为。使用--no-guess
禁用它。默认行为可以通过
checkout.guess
配置变量设置。 - -l
-
创建新分支的 reflog;有关详细信息,请参见git-branch[1]。
- -d
- --detach
-
不要检出分支以进行操作,而是检出提交以进行检查和可丢弃的实验。这是
git checkout <commit>
的默认行为,其中<commit>
不是分支名称。有关详细信息,请参见下面的“DETACHED HEAD”部分。 - --orphan <new-branch>
-
创建一个新的未出生分支,名为
<new-branch>
,从<start-point>
开始,并切换到该分支。在此新分支上进行的第一个提交将没有父级,它将成为与所有其他分支和提交完全断开连接的新历史记录的根。索引和工作树会像您之前运行
git checkout <start-point>
一样进行调整。这允许您通过轻松运行git commit -a
来创建根提交,从而启动一个新的历史记录,该历史记录记录了与<start-point>
类似的一组路径。当您想要发布提交的树而不公开其完整历史记录时,这很有用。您可能希望这样做来发布一个项目的开源分支,该分支的当前树是“干净的”,但其完整历史记录包含专有或其他受限制的代码片段。
如果您想要启动一个断开连接的历史记录,该历史记录记录了与
<start-point>
的路径完全不同的路径集,那么您应该在创建孤儿分支后立即清除索引和工作树,方法是从工作树的顶层运行git rm -rf .
。之后,您将准备好准备新的文件,通过从其他地方复制它们、提取 tarball 等来重新填充工作树。 - --ignore-skip-worktree-bits
-
在稀疏检出模式下,
git checkout -- <paths>
仅更新与<paths>
和$GIT_DIR/info/sparse-checkout
中的稀疏模式匹配的条目。此选项忽略稀疏模式,并添加<paths>
中的任何文件。 - -m
- --merge
-
切换分支时,如果您对一个或多个文件进行了本地修改,而这些修改在当前分支和要切换到的分支之间存在差异,则该命令会拒绝切换分支以保留修改的上下文。但是,使用此选项,将对当前分支、工作树内容和新分支进行三方合并,您将处于新分支上。
当发生合并冲突时,冲突路径的索引条目将保持未合并状态,您需要解决冲突并使用
git add
(或git rm
,如果合并应该导致路径删除)标记已解决的路径。当从索引中检出路径时,此选项允许您在指定的路径中重新创建冲突的合并。从树状对象中检出路径时,不能使用此选项。
使用
--merge
切换分支时,暂存的更改可能会丢失。 - --conflict=<style>
-
与上面的
--merge
选项相同,但更改了冲突块的呈现方式,覆盖了merge.conflictStyle
配置变量。可能的值为“merge”(默认)、“diff3”和“zdiff3”。 - -p
- --patch
-
交互式地选择
<tree-ish>
(或未指定时的索引)和工作树之间的差异中的块。然后,所选块将以相反顺序应用于工作树(如果指定了<tree-ish>
,则应用于索引)。这意味着您可以使用
git checkout -p
有选择地丢弃当前工作树中的编辑。有关如何操作--patch
模式,请参见git-add[1] 的“交互模式”部分。请注意,此选项默认使用无覆盖模式(另请参见
--overlay
),目前不支持覆盖模式。 - --ignore-other-worktrees
-
当其他工作树已检出所需的 ref 时,
git checkout
会拒绝。此选项使其无论如何检出 ref。换句话说,ref 可以被多个工作树持有。 - --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
-
在默认的覆盖模式下,
git checkout
永远不会从索引或工作树中删除文件。当指定--no-overlay
时,将删除出现在索引和工作树中,但在<tree-ish>
中不存在的文件,以使它们与<tree-ish>
完全匹配。 - --pathspec-from-file=<file>
-
路径规格在
<file>
中传递,而不是在命令行参数中传递。如果<file>
恰好是-
,则使用标准输入。路径规格元素以 LF 或 CR/LF 分隔。路径规格元素可以像为配置变量core.quotePath
解释的那样进行引用(参见git-config[1])。另请参见--pathspec-file-nul
和全局--literal-pathspecs
。 - --pathspec-file-nul
-
仅对
--pathspec-from-file
有意义。路径规格元素以 NUL 字符分隔,所有其他字符都按字面意思解释(包括换行符和引号)。 - <branch>
-
要检出的分支;如果它引用一个分支(即,一个名称,当加上“refs/heads/”后,它是一个有效的 ref),则检出该分支。否则,如果它引用一个有效的提交,则您的
HEAD
将变为“分离”状态,并且您不再处于任何分支上(有关详细信息,请参见下文)。您可以使用
@{-N}
语法引用使用“git checkout”操作检出的第 N 个最后分支/提交。您也可以指定-
,它与@{-1}
同义。作为特殊情况,您可以使用
A...B
作为A
和B
的合并基的快捷方式,如果只有一个合并基。您可以最多省略A
和B
中的一个,在这种情况下,它默认为HEAD
。 - <new-branch>
-
新分支的名称。
- <start-point>
-
要从其中开始新分支的提交的名称;有关详细信息,请参见git-branch[1]。默认为
HEAD
。作为特殊情况,您可以使用
"A...B"
作为A
和B
的合并基的快捷方式,如果只有一个合并基。您可以最多省略A
和B
中的一个,在这种情况下,它默认为HEAD
。 - <tree-ish>
-
要从中检出的树(当给出路径时)。如果未指定,将使用索引。
作为特殊情况,您可以使用
"A...B"
作为A
和B
的合并基的快捷方式,如果只有一个合并基。您可以最多省略A
和B
中的一个,在这种情况下,它默认为HEAD
。 - --
-
不要将任何更多参数解释为选项。
- <pathspec>…
-
限制操作受影响的路径。
有关更多详细信息,请参见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
。这被称为处于分离的 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
。换句话说,在此命令之后,我们不再处于分离的HEAD
状态。 -
同样创建一个新的分支
foo
,它引用提交f
,但保持HEAD
分离。 -
创建一个新的标签
foo
,它引用提交f
,保持HEAD
分离。
如果我们已经从提交 f
离开,那么我们必须首先恢复它的对象名称(通常通过使用 git reflog
),然后我们可以为它创建一个引用。例如,要查看 HEAD
引用的最后两个提交,我们可以使用以下任一命令。
$ git reflog -2 HEAD # or $ git log -g -2 HEAD
参数歧义
当只给出单个参数且不是 --
(例如 git checkout abc
),并且当参数同时是有效的 <tree-ish>
(例如存在一个名为 abc
的分支)和有效的 <pathspec>
(例如存在一个名为 "abc" 的文件或目录)时,Git 通常会要求你进行消除歧义。然而,由于签出分支是一个非常常见的操作,因此 git checkout abc
在这种情况下会将 "abc" 作为 <tree-ish>
。如果你想要从索引中签出这些路径,请使用 git checkout -- <pathspec>
。
示例
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
也会被签出,即使它不再工作树中,因为文件通配符用于匹配索引中的条目(而不是 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
-
当你运行
git checkout <something>
或git switch <something>
并且只有一个远程时,它可能会隐式地回退到签出和跟踪例如origin/<something>
。一旦你有多个具有<something>
引用的远程,这就不再起作用。此设置允许设置首选远程的名称,该远程在消除歧义时应始终获胜。典型的用例是将其设置为origin
。目前,当
git checkout <something>
或git switch <something>
会签出另一个远程上的<something>
分支时,git-switch[1] 和 git-checkout[1] 会使用此设置,当git worktree add
指向远程分支时,git-worktree[1] 会使用此设置。此设置将来可能会用于其他类似签出的命令或功能。 - checkout.guess
-
为
git checkout
和git switch
中的--guess
或--no-guess
选项提供默认值。参见 git-switch[1] 和 git-checkout[1]。 - checkout.workers
-
更新工作树时要使用的并行工作程序数量。默认值为一个,即顺序执行。如果设置为小于一个的值,Git 将使用与可用逻辑核心数量相同的工作程序。此设置和
checkout.thresholdForParallelism
会影响执行签出的所有命令。例如,签出、克隆、重置、稀疏签出等。注意:并行签出通常为位于 SSD 上或通过 NFS 的存储库提供更好的性能。对于位于旋转磁盘上和/或核心数量很少的机器上的存储库,默认的顺序签出通常表现得更好。存储库的大小和压缩级别也可能会影响并行版本执行的效率。
- checkout.thresholdForParallelism
-
当使用少量文件运行并行签出时,子进程生成和进程间通信的成本可能会超过并行化带来的收益。此设置允许你定义尝试并行签出的最小文件数量。默认值为 100。
GIT
是 git[1] 套件的一部分