Git 2.23 介绍一个新的命令 git switch——在阅读了文档之后,它似乎与 git checkout <branchname>非常相似,有人能解释一下其中的区别或用例吗?
git switch
git checkout <branchname>
引入了两个新命令“ git switch”和“ git 恢复” 将“检查一个分支机构以推进其历史进程”和“检查一个分支机构以推进其历史进程”分开 ”检查索引外的路径和/或要处理的树形路径 推进单个“ git checkout”的当前历史 指挥官。
git checkout有点像瑞士军刀,它有几个不相关的用途。
git checkout
如果您修改了一个文件,但还没有执行更改,那么git checkout <filename>将反转修改…一种快速而简单的方法取消对文件的更改。你仍然在同一个分支。
git checkout <filename>
git checkout <branchname>(正如你所注意到的)切换分支。
两个完全不同的目的,如果文件名和分支名称相似,可能会导致混淆。
把它作为两个命令就更清楚了。
好吧,根据你链接到的文档,它的唯一目的是拆分和澄清git checkout的两种不同用法:
git restore
git checkout -- <path_to_file>
人们对使用git checkout的不同方式感到困惑,正如你可以从Stackoverflow上关于git checkout的许多问题中看到的那样。Git开发人员似乎已经考虑到了这一点。
switch有一些限制:目前你可以将从任何提交切换到<branch name>,但是不可能将从 <branch name>切换到状态为分离的头的特定提交。因此您需要使用git checkout 5efb(其中5efb是任意提交的哈希引用的示例)
switch
<branch name>
git checkout 5efb
这里是一个从git手册 - man git-switch的摘录。
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> 描述 切换到指定分支。工作树和索引是 已更新以匹配分支。所有新提交将被添加到 < p >选择# EYZ2, 自动从同名的远程分支(见--guess), 或者使用--detach从任何分支分离工作树, 切换分支不需要干净的索引和工作树 (即与HEAD相比没有区别)。操作被终止 但如果操作导致局部改动丢失,则除非 . --discard-changes或--merge 这个命令是实验性的。行为可能会改变。
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>
切换到指定分支。工作树和索引是 已更新以匹配分支。所有新提交将被添加到
--guess
--detach
HEAD
--discard-changes
--merge
这个命令是实验性的。行为可能会改变。
switch命令确实做了与checkout相同的事情,但仅适用于那些切换分支的使用。特别是,与checkout不同,它不能恢复工作树文件——而是使用与switch一起引入的restore命令来完成。
checkout
restore
正如你在2.23.0发布说明中提到的,引入switch和restore命令是为了将checkout命令分成两个单独的部分:
换句话说,checkout做了两件不同的事情,这个版本将每一件不同的事情分割成自己的重点命令。
checkout的双重目的可以在文档的摘要描述中看到:
git-checkout -切换分支或恢复工作树文件
添加了switch命令的提交在其提交消息中解释了新命令的基本原理:
< p >“git checkout"做太多事情会让很多人感到困惑 用户(有时甚至是老用户)。为了补救, 命令将拆分为两个新的命令:switch和restore。良好的 旧的“git checkout”;命令仍然在这里,直到所有(或大部分)
由此可以明显看出,引入新命令是为了减少混淆,因为有两个集中的命令,而不是一个多用途命令。
请注意,截至2021年12月,新命令仍被列为实验性(switch, restore):
我还没有在任何地方找到这些命令的完整比较。通过阅读文档,我认为这应该是一个相当完整的比较:
git status
git switch <start-point>
git switch --orphan <new-branch>
从这个比较中可以看出,通过将旧的命令名(checkout)替换为新命令名(switch, restore),可以将一些先前的用法转换为新命令,而其他用法则需要进行额外的调整。值得注意的变化包括:
-b
-B
-c
-C
--create
--force-create
-d
-s
--source
--force
当使用checkout和--force时,你可以在合并过程中切换分支。你不能用switch这样做。
细节:
其他答案已经涵盖了将checkout分为switch和restore背后的动机,以及语法使用差异存在的事实。(例如,你可以将checkout与提交或远程跟踪分支一起使用,如origin/main,但对于switch,你还必须显式地指定--detach选项。)然而,我也发现了至少一个重要的功能区别。
origin/main
git switch -f等于记录:
git switch -f
即使索引或工作树与HEAD不同,也要继续。索引和工作树都被恢复以匹配交换目标。如果指定了--recurse-submodules,子模块内容也会恢复到与切换目标匹配。这用于丢弃局部更改。
--recurse-submodules
类似地,git checkout -f就是记录(强调最后一句):
git checkout -f
在切换分支时,即使索引或工作树与HEAD不同,即使存在未跟踪的文件,也要继续执行。这用于丢弃本地更改和任何碍事的未跟踪文件或目录。 当从索引中检出路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。
在切换分支时,即使索引或工作树与HEAD不同,即使存在未跟踪的文件,也要继续执行。这用于丢弃本地更改和任何碍事的未跟踪文件或目录。
当从索引中检出路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。
它似乎像最后一句一样适用于checkout的另一个含义,即restore命令等价。然而,当您试图在合并过程中切换分支时,git checkout -f将会成功,即使您当时有未解决的冲突。如果你正在合并(即使没有冲突),git switch -f根本不起作用,因为你得到这个错误消息:
致命:合并时不能切换分支
注意:这个差异是使用Git 2.37.1版本测试的