ChatGPT解决这个技术问题 Extra ChatGPT

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

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

引入了两个新命令“git switch”和“git restore”来拆分“签出分支以推进其历史”和“签出索引和/或树状路径以推进当前历史”从单个“git checkout”命令中提取出来。

InfoQ 上有一篇关于这个主题的好文章:infoq.com/news/2019/08/git-2-23-switch-restore
Git 团队是否计划弃用 git checkout?使用它时我没有看到弃用警告。但是有了 git switchgit restore,我现在认为不需要 checkout。然而,如果它没有被弃用,Git 团队只会让事情变得更加混乱,而不是更少。有人知道git checkout的计划吗?如果它仍然有用例,有人可以添加或编辑答案以详细说明其用例。
@MikeWilliamson 我不这么认为,您仍然需要git checkout <commit>
@BastianVenthur 是的,谢谢!不幸的是,这意味着 checkout 将仅仅因为它在少数情况下使用的“极端情况”而存在。这会延长混乱的时间。但我想我们只需要互相帮助就可以了。 :)
@BastianVenthur 你可以git switch --detach <commit>

I
IMSoP

好吧,根据您链接到的文档,其唯一目的是拆分和阐明 git checkout 的两种不同用途:

git switch 现在可以用于更改分支,就像 git checkout 一样

git restore 可用于将文件重置为某些版本,就像 git checkout -- 一样

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


这似乎是一个很好的改变。做一个分支? git checkout 切换分支? git checkout 获取某个版本的文件? git checkout 删除对一个文件的更改? git checkout 老实说,我想知道使用 git checkout 的各种标志可以完成多少正常的 git 工作流程。
那么现在的想法是,在技术上不再需要 git checkout 了吗?或者它是否仍在用于某些事情,例如检查不是分支头的提交(移动到“分离头”模式)?
@Mike在你说结帐制造分支之后,你怎么能说结帐不制造分支? -b 标志的内部工作方式无关紧要。它仍然是一个分支。
@Mike我理解你关于操作与命令的观点,但这个讨论是关于命令的。除非我们使用超低级 API,否则我们无法直接访问“操作”。我们只能访问命令。这是一个不必要的迂腐区分。
有用的提示:对于那些习惯于 git checkout -b <branch name> 的人,您可以使用 git switch -c <branch name> 来获得相同的效果
S
SteveTurczyn

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

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

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

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

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


正如您提到的,具有相同名称的分支和文件令人困惑。我假设分支优先于文件,因为这通常更可取?或者它是如何工作的?
@AgentM 是的,这是正确的。如果分支和文件具有相同的名称,则执行 git checkout <name> 会优先选择分支而不是文件。
如果您想签出文件而不是分支,则必须用 -- 将其与选项分开。这是许多 Git 和其他 Unix 命令的常见习语。
@bjhend 和 SteveTurczyn,git checkout <filename> 经常工作,但 git checkout -- <filename> 更好,因为 -- 清楚地向 git 解析器表明传递给 git checkout 的选项已经结束,并且文件列表或目录路径已经开始。这可能很重要,例如,如果您的文件名以破折号开头,例如 -myfile。在这种情况下,执行 git checkout -- -myfile 应该可以工作,而没有前面的 ---myfile 看起来就像传递给 git checkout 的混乱选项。
M
M. Justin

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 git switch git checkout N/A (使用 git status) git checkout -b [] git switch -c [] git checkout -B [] git switch -C [] git checkout --orphan git switch --orphan git checkout --orphan N/A (使用 git switch 然后 git switch --orphan ) git checkout [--detach] git switch --detach git checkout --detach [] git switch --detach [] git checkout [--] … git restore [--] … git checkout --pathspec-from-file = git restore --pathspec-from-file= git checkout [--] ... git restore -s [--] ... git checkout < tree-ish> --pathspec-from-file= git restore -s --pathspec-from-file= git checkout -p [] [--] [< pathspec>…] git restore -p [-s ] [--] [ <路径规范>…]

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

切换前创建新分支的 -b/-B 选项重命名为 -c/-C

--detach 现在在切换到分离的头部时总是需要的,以前它对于提交是可选的,但对于分支是必需的

用于恢复的源树现在由 -s 选项给出,而不是作为内联参数


d
daGo

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


我认为这实际上是一个功能,而不是一个错误(限制)。 switch 是为更改分支而创建的,当您这样做时,您确实希望成为该分支的 HEAD。 checkout 是一种更通用的操作,它使您的工作副本与历史记录中的任何给定状态保持一致(= 提交)。由于任何分支名称都是该分支的 HEAD 提交的别名,因此签出分支在技术上与签出任何其他提交没有什么不同。
使用 -d,您可以:git switch -d 6c13
M
Maëlan

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

概要 git switch [] [--no-guess] git switch [] --detach [] git switch [] (-c|-C) < new-branch> [] git switch [] --orphan 描述切换到指定分支。更新工作树和索引以匹配分支。所有新的提交都会被添加到这个分支的顶端。可选地,可以使用 -c、-C 从同名的远程分支自动创建一个新分支(参见 --guess),或者使用 --detach 将工作树从任何分支中分离,并进行切换。切换分支不需要干净的索引和工作树(即与 HEAD 相比没有差异)。但是,如果操作导致本地更改丢失,则操作将中止,除非使用 --discard-changes 或 --merge 另有说明。此命令是实验性的。行为可能会改变。


k
kd4ttc

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


这是不准确的。