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

6gpjuf90  于 2022-11-20  发布在  Git
关注(0)|答案(6)|浏览(408)

Git 2.23 introduces一个新的命令git switch--阅读文档后,它看起来和git checkout <branchname>差不多,有人能解释一下两者的区别或用例吗?
引入了两个新命令“git switch”和“git restore”,将“ checkout 分支以推进其历史记录”和“ checkout 索引和/或树的路径以推进当前历史记录”从单个“git checkout”命令中分离出来。

7jmck4yq

7jmck4yq1#

根据您链接到的文档,它的唯一目的是拆分和澄清git checkout的两种不同用法:

  • git switch现在可用于更改分支,就像git checkout <branchname>一样
  • git restore可用于将文件重置为某些修订版,就像git checkout -- <path_to_file>一样

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

ndh0cuux

ndh0cuux2#

git checkout有点像瑞士军刀,有几个不相关的用途。
如果你修改了一个文件但还没有暂存更改,那么git checkout <filename>将撤销修改...一个快速简单的方法来取消对文件的更改。
git checkout <branchname>(如您所述)切换分支。
两种完全不同的用途,如果文件名和分支名称相似,可能会导致混淆。
将其作为两个命令更清楚。

nvbavucw

nvbavucw3#

switch命令确实和checkout做同样的事情,但只适用于那些切换分支的用法。特别是,与checkout不同的是,它不能恢复工作树文件--这是使用与switch一起引入的restore命令来完成的。

详细说明

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

  • “检查一个分支,以推进其历史”
  • “从索引和/或树型目录中检出路径,以推进当前历史记录”

换句话说,checkout做两件不同的事情,而这个版本将每件不同的事情都拆分成了它自己的集中命令。
checkout的这种双重用途可以在documentation中的摘要描述中看到:
git-checkout -切换分支或恢复工作树文件
添加了switch命令的commit在其提交消息中解释了新命令的基本原理:
“git checkout”做太多的事情会让很多用户感到困惑(有时候它甚至会咬老用户)。为了解决这个问题,这个命令将被拆分成两个新的命令:切换和恢复。“git checkout”命令仍然在这里,直到所有(或大多数用户)都厌倦了它。
由此可见,引入新命令的目的是通过使用两个集中的命令而不是一个多用途命令来减少混乱。
请注意,截至2021年12月,新命令仍被列为实验性命令(switchrestore):
此命令是实验性的。行为可能会改变。

命令比较

我还没有在任何地方找到命令的完整比较。从阅读文档来看,我认为这应该是一个相当完整的比较:
| 前一个命令|新命令|
| - -|- -|
| git checkout <branch>| git switch <branch>|
| x1米15英寸|不适用(使用git status)|
| git checkout -b <new_branch> [<start_point>]| git switch -c <new-branch> [<start-point>]|
| x1米19英寸1x| x1米20英寸|
| git checkout --orphan <new_branch>| git switch --orphan <new-branch>|
| git checkout --orphan <new_branch> <start_point>|不适用(使用git switch <start-point>,然后使用git switch --orphan <new-branch>)|
| git checkout [--detach] <commit>个|git switch --detach <commit>|
| x1米28英寸1x| git switch --detach [<branch>]|
| x1米30英寸|git restore [--] <pathspec>…|
| x1米32英寸|git restore --pathspec-from-file=<file>|
| x1米34英寸|x1米35英寸|
| x1米36英寸|x1米37英寸|
| x1米38英寸|x1米39英寸|
如该比较中所示,通过将旧命令名(checkout)替换为新命令名(switchrestore),可以将一些以前的用法转换为新命令,而其他用法则需要进行额外的调整。

  • 用于在切换前创建新分支的-b/-B选项被重命名为-c/-C。它们也有长选项变体(--create/--force-create),而以前它们只有单字母选项版本。
  • --detach(或-d)现在在切换到分离头时总是需要的,以前它对于提交是可选的,但对于分支是必需的。
  • 用于还原的源树现在由-s(或--source)选项提供,而不是作为内联参数。
nimxete2

nimxete24#

switch有一些限制:现在你可以从任何提交切换到<branch name>,但是不能从<branch name>切换到一个状态为 detached HEAD 的提交,所以你需要使用git checkout 5efb(这里5efb是一个任意提交的哈希引用)

8xiog9wr

8xiog9wr5#

**tl;dr:**将checkout--force一起使用时,您可以在合并过程中切换分支。但不能使用switch
详细数据:

其他答案已经涵盖了将checkout拆分为switchrestore背后的动机,以及存在句法用法差异的事实。(例如,您可以直接将checkout与提交或远程跟踪分支(如origin/main)一起使用,但对于switch,您还必须显式指定--detach选项。)但是,我也发现了至少一个显著的 * 功能 * 差异。
git switch -f的记录如下:
即使索引或工作树与HEAD不同也继续。索引和工作树都被恢复以匹配切换目标。如果指定了--recurse-submodules,子模块内容也被恢复以匹配切换目标。这用于丢弃本地更改。
同样,git checkout -f也是这样记录的(强调最后一句):
当切换分支时,即使索引或工作树不同于HEAD,即使有未被跟踪的文件阻挡,也要继续。这用于丢弃本地更改和任何阻挡的未被跟踪的文件或目录。

从索引中 checkout 路径时,不要在未合并的条目上失败;而是忽略未合并的条目。

最后一句话似乎适用于checkout的另一种含义,即restore命令的等价物。但是,当您正在进行合并时尝试切换分支时,git checkout -f会成功,即使此时有未解决的冲突。如果当前正在合并(即使没有冲突),git switch -f根本不起作用,因为您会收到以下错误消息:
致命错误:合并时无法切换分支
注:使用Git 2.37.1版测试了此差异

lyfkaqu1

lyfkaqu16#

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

概要

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>

描述

切换到指定的分支。工作树和索引会更新以匹配该分支。所有新提交都将被添加到该分支的顶端。
可选地,**可以使用-c-C**从同名的远程分支自动创建新分支(参见--guess),或者使用--detach从任何分支分离工作树,沿着进行切换。
切换分支不需要干净的索引和工作树(即与HEAD相比没有区别)。然而,如果操作导致本地更改丢失,则该操作将被中止,除非--discard-changes--merge另有说明。
此命令是实验性的。行为可能会改变。

相关问题