## Name

git-checkout - 切换分支或恢复工作树文件

## 概要

    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|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>…

    git checkout [<tree-ish>] [--] <pathspec>…

    git checkout (-p|--patch) [<tree-ish>] [--] [<paths>…]

## 描述

更新工作树中的文件以匹配索引或指定树中的版本。如果没有给出路径，`git checkout`也将更新`HEAD`以将指定的分支设置为当前分支。

git checkout <branch>

要准备在<branch>上工作，通过更新工作树中的索引和文件并将HEAD指向分支来切换到它。对工作树中的文件进行本地修改保留，以便它们可以被提交给<分支>。

如果找不到<branch>，但确实在一个远程（具有匹配的名称称为<remote>）中存在跟踪分支，则视为等同于

    $ 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>; 否则，它被重置。这是事务性的等价物

    $ git branch -f <branch> [<start point>]$ git checkout <branch>

也就是说，除非“git checkout”成功，否则该分支不会被重置/创建。

git checkout --detach <branch> git checkout --detach <commit>

准备工作在<commit>之上，通过分离HEAD（参见“DETACHED HEAD”部分），并更新工作树中的索引和文件。保留对工作树中文件的本地修改，以使生成的工作树成为提交时记录的状态和本地修改。

当<commit>参数是分支名称时，该`--detach`选项可用于在分支尖端分离HEAD（`git checkout <branch>`将检出该分支而不分离HEAD）。

省略<分支>在当前分支的顶端分离HEAD。

git checkout <tree-ish> <pathspec>…

通过替换索引或<tree-ish>中的内容（通常是提交）覆盖工作树中的路径。当给出<tree-ish>时，匹配<pathspec>的路径将在索引和工作树中更新。

由于先前的合并失败，索引可能包含未合并的条目。默认情况下，如果您试图从索引中检出这样的条目，则检出操作将失败并且不会检出任何内容。使用`-f`将忽略这些未合并的条目。通过使用`--ours`或，可以从索引中检出合并的特定方的内容`--theirs`。使用时`-m`，可以放弃对工作树文件所做的更改，以重新创建原始冲突的合并结果。

git checkout (-p|--patch) <tree-ish> <pathspec>…

这与上面描述的“从索引或树状结构检查工作树的路径”类似，但可以使用交互式界面来显示“diff”输出并选择要在哪个区块中使用的区块结果。请参阅下面的`--patch`选项说明。

## 选项

-q --quiet

安静，抑制反馈信息。

--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

创建新分支时，设置“上游”配置。有关详细信息，请参阅git-branch [1]中的“--track”。

如果没有`-b`给出选项，则通过查看为相应的远程配置的refspec的本地部分，然后剥离最初的部分直到“*”，新分支的名称将从远程跟踪分支派生。这将告诉我们在分支“origin / hack”（或“远程/源/黑客”，甚至“refs / remotes / origin / hack”）时使用“hack”作为本地分支。如果给定名称没有斜线，或者上述猜测结果为空名称，则猜测会中止。`-b`在这种情况下，你可以明确地给出一个名字。

--no-track

即使branch.autoSetupMerge配置变量为true，也不要设置“上游”配置。

-l

创建新分支的reflog; 有关详细信息，请参阅git-branch [1]。

--detach

而不是检查一个分支来处理它，检查提交检查和可废弃的实验。当<commit>不是分支名称时，这是“git checkout <commit>”的默认行为。有关详细信息，请参阅下面的“分离头部”一节。

--orphan <new_branch>

创建一个`orphan`名为<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>`只会更新$ GIT_DIR / info / sparse-checkout中由<路径>和稀疏模式匹配的条目。此选项会忽略稀疏模式并添加<paths>中的任何文件。

-m --merge

在切换分支时，如果对当前分支与切换到的分支之间的一个或多个文件进行本地修改，则该命令将拒绝切换分支以便在上下文中保留修改。但是，使用此选项，当前分支，工作树内容和新分支之间的三向合并已完成，并且您将位于新分支上。

当合并冲突发生时，冲突路径的索引条目未被合并，您需要解决冲突并标记已解析的路径`git add`（或`git rm`合并是否应导致删除路径）。

当从索引检出路径时，使用此选项可以在指定的路径中重新创建冲突的合并。

--conflict=<style>

与上面的--merge选项相同，但改变了冲突的区块显示方式，覆盖merge.conflictStyle配置变量。可能的值是“合并”（默认）和“diff3”（除了“合并”样式显示的内容，显示原始内容）。

-p --patch

在<tree-ish>（或索引，如果未指定）和工作树之间的区别中交互地选择hunk。然后将选定的区块反向应用于工作树（并且如果指定了<tree-ish>，则索引）。

这意味着您可以使用`git checkout -p`有选择地放弃当前工作树中的编辑。请参阅git-add [1]的“交互模式”部分了解如何操作该`--patch`模式。

--ignore-other-worktrees

`git checkout`当被通缉的裁判已经被另一个工作树签出时拒绝。这个选项使它无论如何检查裁判。换句话说，裁判可以由多个工作树持有。

--no-recurse-submodules

使用-- recurse 子模块将根据超级项目中记录的提交更新所有已初始化的子模块的内容。如果覆盖子模块中的本地修改，则除非`-f`使用，否则检出将失败。如果没有使用（或--no-recurse-submodules），则子模块的工作树将不会更新。

<branch>

分行结账; 如果它引用了一个分支（即，前缀为“refs / heads /”的名称是一个有效的 ref），那么该分支将被签出。否则，如果它指向一个有效的提交，那么您的 HEAD 变为“分离”，并且您不再在任何分支上（详情见下文）。

作为特例，第`"@{-N}"`N 个分支/提交的语法检出分支（而不是分离）。你也可以指定`-`哪一个是同义词`"@{-1}"`。

作为更进一步的特例，如果只有一个合并基础，则可以将其`"A...B"`用作合并基础的快捷方式。你可以在大多数的一个离开了和，在这种情况下默认为`ABABHEAD`。

<new_branch>

新分支的名称。

<start_point>

要开始新分支的提交的名称; 有关详细信息，请参阅git-branch [1]。默认为HEAD。

<tree-ish>

要检出的树（当有路径时）。如果未指定，则会使用索引。

## 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`，因此间接地指的是commit `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')

能够检出不在任何命名分支顶端的提交，或者甚至创建未由命名分支引用的新提交，有时很有用。让我们看看 checkout 提交时会发生什么`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')

请注意，无论我们使用哪个 checkout 命令，HEAD 现在都直接引用commit `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 操作。但是，让我们看看当我们结账主人时会发生什么：

    $ 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   (1)$ git branch foo        (2)$ git tag foo           (3)

1. 创建一个新的分支`foo`，引用 commit `f`，然后更新 HEAD 以引用分支`foo`。换句话说，在这个命令之后，我们将不再处于分离的 HEAD 状态。

1. 类似地创建了一个新的分支`foo`，它引用了 commit `f`，但是将 HEAD 分开。

1. 创建一个新的标签`foo`，它引用 commit `f`，使 HEAD 脱离。如果我们已经离开 commit `f`，那么我们必须首先恢复它的对象名（通常使用 git reflog），然后我们可以创建一个对它的引用。例如，要查看 HEAD 引用的最后两个提交，我们可以使用以下任一命令：$ git reflog -2 HEAD＃或$ git log -g -2 HEADArgument 消歧当只有一个参数给出而且它不是`--`（例如“git checkout abc”），当参数是有效的`<tree-ish>`（例如分支“abc”存在）和有效的`<pathspec>`（例如文件或名称为“abc”的目录）时，Git 通常会要求您歧义。因为检查分支是非常常见的操作，但是，“git checkout abc”`<tree-ish>`在这种情况下。使用`git checkout -- <pathspec>`如果要检出这些路径出 index.Examples 的

1. 以下序列检出`master`分支，将其恢复`Makefile`为两个修订版，错误地删除hello.c，并从索引中取回它。

$ git checkout master（1）$ git checkout master〜2 Makefile（2）$ rm -f hello.c $ git checkout hello.c（3）

    1.  switch branch2.  take a file out of another commit

    3.  restore hello.c from the index If you want to check out all C source files out of the index, you can say

       $ git checkout -- '*.c' Note the quotes around *.c. The file hello.c will also be checked out, even though it is no longer in the working tree, because the file globbing is used to match entries in the index (not in the working tree by the shell).

     If you have an unfortunate branch that is named hello.c, this step would be confused as an instruction to switch to that branch. You should instead write:

       $ git checkout -- hello.cAfter working in the wrong branch, switching to the correct branch would be done using:

$ git checkout mytopic

但是，您在本地修改的文件中，您的“错误”分支和正确的“mytopic”分支可能有所不同，在这种情况下，上述结帐将失败，如下所示：

$ git checkout mytopic错误：您对'frotz'进行了本地更改; 不切换分支。

您可以将该`-m`标志赋予该命令，该命令将尝试三路合并：

$ git checkout -m mytopic Auto-merging frotz

在这种三路合并之后，本地修改被`not`注册在您的索引文件中，因此`git diff`会显示自从新分支的提示以来所做的更改。

1. 在使用该`-m`选项切换分支期间发生合并冲突时，您会看到如下所示的内容：

$ git checkout -m mytopic自动合并frotz错误：在frotz致命合并冲突：合并程序失败

此时，`git diff`如前面的示例所示，显示合并的干净合并以及冲突文件中的更改。编辑并解决冲突并`git add`像往常一样将其标记为已解决：

$ edit frotz $ git add frotz