git switch 和 git checkout <branch> 有什么区别

What's the difference between git switch and git checkout <branch>

Git 2.23 introduces 一个新命令 git switch -- 阅读文档后,它似乎与 git checkout <branchname> 几乎相同有人可以解释差异或使用案例?

Two new commands "git switch" and "git restore" are introduced to split "checking out a branch to work on advancing its history" and "checking out paths out of the index and/or a tree-ish to work on advancing the current history" out of the single "git checkout" command.

git checkout 有点像瑞士军刀,因为它有几个不相关的用途。

如果您修改文件但没有暂存更改,那么 git checkout <filename> 将撤消修改...这是一种取消对文件更改的快速简便的方法。你留在同一个分支。

git checkout <branchname>(如您所述)切换分支。

两个完全不同的用途,如果文件名和分支名相似,可能会导致混淆。

将它作为两个命令更清楚。

好吧,根据您 link 的文档,其唯一目的是拆分和阐明 git checkout:

的两种不同用途
  • git switch 现在可用于更改分支,就像 git checkout <branchname> 所做的那样
  • git restore 可用于将文件重置为某些修订版,就像 git checkout -- <path_to_file> 所做的那样

人们对 git checkout 的这些不同使用方式感到困惑,您可以从 Whosebug 上有关 git checkout 的许多问题中看出这一点。 Git 开发人员似乎已经考虑到了这一点。

switch 有一些限制:目前您可以将 切换到 <branch name>,但是无法切换 <branch name> 到状态为 detached HEAD 的特定提交。所以你需要使用 git checkout 5efb (其中 5efb 是对任意提交的哈希引用的示例)

你会得到不同的效果。当你结账时,你会得到你结账的分支的文件。如果您切换分支更改但文件没有更改。如果您提交,则提交将转到该分支。如果您正在编辑但结帐,则文件将重置为结帐时的文件状态,可能会丢失工作或获得所需的恢复。

这里是 git 手册的摘录—man git-switch

Synopsis

git switch [<options>] [--no-guess] <branch>
git switch [<options>] --detach [<start-point>]
git switch [<options>] (-c|-C) <new-branch> [<start-point>]
git switch [<options>] --orphan <new-branch>

Description

Switch to a specified branch. The working tree and the index are updated to match the branch. All new commits will be added to the tip of this branch.

Optionally a new branch could be created with either -c, -C, automatically from a remote branch of same name (see --guess), or detach the working tree from any branch with --detach, along with switching.

Switching branches does not require a clean index and working tree (i.e. no differences compared to HEAD). The operation is aborted however if the operation leads to loss of local changes, unless told otherwise with --discard-changes or --merge.

THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

switch 命令确实与 checkout 做同样的事情,但仅适用于切换分支的那些用法。特别是,与 checkout 不同,它无法恢复工作树文件——而是使用与 switch.

一起引入的 restore 命令来完成

正如您在引用的 2.23.0 发行说明部分中所述,引入了 switchrestore 命令以将 checkout 命令拆分为两个单独的部分:

  • “检查一个分支以推进其历史”
  • “从索引中检出路径 and/or 树状结构以推进当前历史”

换句话说,checkout 做了两件不同的事情,这个版本将这些不同的事情分成了各自的重点命令。

checkout 的双重用途可以在 documentation 的摘要描述中看到:

git-checkout - Switch branches or restore working tree files

添加 switch 命令的 commit 在其提交消息中解释了新命令的基本原理:

"git checkout" doing too many things is a source of confusion for many users (and it even bites old timers sometimes). To remedy that, the command will be split into two new ones: switch and restore. The good old "git checkout" command is still here and will be until all (or most of users) are sick of it.

由此可见,引入新命令是为了减少混淆,因为它有两个重点命令,而不是一个多用途命令。

请注意,截至 2021 年 12 月,新命令仍列为实验性命令 (switch, restore):

THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

命令比较

我没有在任何地方找到命令的完整比较。通过阅读文档,我认为这应该是一个相当完整的比较:

previous command new command
git checkout <branch> git switch <branch>
git checkout N/A (use git status)
git checkout -b <new_branch> [<start_point>] git switch -c <new-branch> [<start-point>]
git checkout -B <new_branch> [<start_point>] git switch -C <new-branch> [<start-point>]
git checkout --orphan <new_branch> git switch --orphan <new-branch>
git checkout --orphan <new_branch> <start_point> N/A (use git switch <start-point> then git switch --orphan <new-branch>)
git checkout [--detach] <commit> git switch --detach <commit>
git checkout --detach [<branch>] git switch --detach [<branch>]
git checkout [--] <pathspec>… git restore [--] <pathspec>…
git checkout --pathspec-from-file=<file> git restore --pathspec-from-file=<file>
git checkout <tree-ish> [--] <pathspec>… git restore -s <tree> [--] <pathspec>…
git checkout <tree-ish> --pathspec-from-file=<file> git restore -s <tree> --pathspec-from-file=<file>
git checkout -p [<tree-ish>] [--] [<pathspec>…] git restore -p [-s <tree>] [--] [<pathspec>…]

如本比较所示,通过将旧命令名称 (checkout) 替换为新命令名称 (switchrestore,可以将一些先前的用法转换为新命令), 而其他的则需要额外的调整。显着变化包括:

  • 切换前创建新分支的-b/-B选项重命名为-c/-C
  • --detach 现在在切换到分离头时总是需要的,以前它对于提交是可选的但对于分支是必需的
  • 用于恢复的源代码树现在由 -s 选项给出,而不是内联参数