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

Bas*_*hur 16 git git-checkout

Git 2.23 引入了一个新命令git switch-阅读文档后,似乎几乎git checkout <branchname>可以与某人解释差异或用例一样?

引入了两个新命令“ git switch”和“ git restore”,以拆分“检出分支以改进其历史记录”和“检出索引之外的路径和/或树状结构以推进当前的操作” “ git checkout”命令中删除“历史记录”。

M. *_*tin 261

switch命令确实与 执行相同的操作checkout,但仅适用于切换分支的用法。它无法恢复使用 完成的工作树文件 \xe2\x80\x94 restore,另一个命令是从checkout.

\n

分裂checkout命令总结如下:

\n
    \n
  • switch\xe2\x80\x94\xc2\xa0切换到指定分支
  • \n
  • restore\xe2\x80\x94\xc2\xa0从另一个分支或源恢复文件
  • \n
\n

详细解释

\n

正如您在引用的 2.23.0 发行说明部分中所指出的,引入了switch和命令来将命令拆分为两个单独的部分:restorecheckout

\n
    \n
  • “检查一个分支机构,致力于推进其历史”
  • \n
  • “检查索引和/或树形结构之外的路径,以推进当前历史记录”
  • \n
\n

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

\n

这种双重目的可以从文档checkout中的摘要描述中看出:

\n
\n

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

\n
\n

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

\n
\n

“git checkout”做太多事情是许多用户感到困惑的根源(有时它甚至会咬住老朋友)。为了解决这个问题,该命令将被分成两个新命令:switch 和 Restore。好的\n旧“git checkout”命令仍然存在,直到所有(或大多数\n用户)都厌倦了它。

\n
\n

由此可见,引入新命令是为了通过使用两个集中命令而不是一个多用途命令来减少混乱。

\n

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

\n
\n

该命令是实验性的。行为可能会改变。

\n
\n

命令比较

\n

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

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
上一个命令新命令
git checkout <branch>git switch <branch>
git checkout不适用(使用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>不适用(git switch <start-point>然后使用git switch --orphan <new-branch>
git checkout [--detach] <commit>git switch --detach <commit>
git checkout --detach [<branch>]git switch --detach [<branch>]
git checkout [--] <pathspec>\xe2\x80\xa6git restore [--] <pathspec>\xe2\x80\xa6
git checkout --pathspec-from-file=<file>git restore --pathspec-from-file=<file>
git checkout <tree-ish> [--] <pathspec>\xe2\x80\xa6git restore -s <tree> [--] <pathspec>\xe2\x80\xa6
git checkout <tree-ish> --pathspec-from-file=<file>git restore -s <tree> --pathspec-from-file=<file>
git checkout -p [<tree-ish>] [--] [<pathspec>\xe2\x80\xa6]git restore -p [-s <tree>] [--] [<pathspec>\xe2\x80\xa6]
\n

通过比较可以看出,一些先前的用法只需将旧命令名称 ( ) 替换为新命令名称( , ) 即可转换为checkout新命令,而其他用法则需要额外调整。值得注意的变化包括:switchrestore

\n
    \n
  • 用于在切换之前创建新分支的-b/选项已重命名为/ 。与以前不同,它们还有长选项变体 ( / )。-B-c-C--create--force-create
  • \n
  • --detach(或-d) 现在在切换到分离头时始终需要,以前对于提交来说它是可选的,但对于分支来说是必需的。
  • \n
  • -s用于恢复的源树现在由(或) 选项给出--source,而不是作为内联参数。
  • \n
  • 如果存在未合并的条目, 则使用--force(或) 切换现在会失败,而不是忽略它们。也已重命名为,并保留为别名。-f--force--discard-changes--force
  • \n
\n


kow*_*sky 16

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

  • git switch现在可以用来改变分支机构,git checkout <branchname>
  • git restore可用于重置文件到某些修改,如git checkout --<path_to_file>

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

  • 这似乎是一个很好的改变。开个分支?`git checkout` 切换分支?`git checkout` 获取文件的某个版本?`git checkout` 删除对一个文件的更改?`git checkout` 老实说,我想知道有多少正常的 git 工作流程可以通过“git checkout”的各种标志来完成。 (75认同)
  • 有用的提示:对于那些习惯使用 `git checkout -b &lt;branch name&gt;` 的人,您可以使用 `git switch -c &lt;branch name&gt;` 来获得相同的效果 (20认同)
  • @Mike我理解你关于操作与命令的观点,但这个讨论是关于命令的。除非我们使用超低级 API,否则我们无法直接访问“操作”。我们只能访问命令。这是一种不必要的迂腐区分。 (14认同)
  • @Mike,在你说结帐产生分支之后,你怎么能说结帐不产生分支呢?“-b”标志的内部工作原理并不重要。它仍然形成一个分支。 (12认同)
  • 那么现在的想法是“git checkout”在技术上不再需要任何东西了吗?或者它是否仍在用于某些事情,例如检查不是分支头的提交(移动到“分离头”模式)? (10认同)
  • @CaptainMan,`checkout` **操作**不会创建分支,它只能切换到已经存在的分支。“checkout”**命令**的“-b”选项在实际执行签出之前在内部执行“git分支”。这就像“git pull”是“git fetch”+“git merge”的快捷方式一样。 (7认同)
  • @forresthopkinsa,不存在“拉动操作”这样的东西。`git pull` 正是 `git fetch` 后跟 `git merge` 的快捷方式(或者 `git rebase`,如果您传递了 `--rebase` 选项,或者如果您的默认集成策略是 rebase 而不是合并)。除了调用这两个操作之外,“pull”没有做任何其他事情。查看文档,您会发现“pull”的所有选项都是“fetch”或“merge”的选项。事实上,我已经很多年没有使用过“git pull”了。我总是先执行“git fetch”,然后查看更改的历史记录,然后执行“git merge”。 (5认同)
  • @CaptainMan,创建一个新分支是通过“git分支”完成的。然而,它仅“创建”分支,而不会切换到它(另一个特殊的设计决策)。如果你想继续在新分支工作,你需要“签出”它。有一个选项“checkout -b &lt;branch name&gt;”,它是“gitbranch”+“git checkout”的快捷方式。尽管如此,“签出”操作在技术上并不会创建新分支。 (4认同)
  • 你已经非常接近理解我的实际观点了:如果我说“pull”,我的意思是“fetch+merge”;如果我说“结帐”,我会将分支创建包含在其功能列表中。 (4认同)
  • Git 中有如此多的命令和标志,并且它们添加了更多的方法来做同样的事情。 (3认同)
  • 我完全明白为什么要引入这个,“git-checkout”有点臃肿并且语义上被破坏了。但如果 `man git-switch` 能更明确地说明为什么他们引入这个 ie 来分解 `git-checkout` 功能,那确实会有帮助。 (3认同)
  • `git-checkout` 的作用实际上是检查一个哈希对象:commit(提交对象)、tag(引用提交对象)、branch(也引用提交对象)、file(blob 对象)等。确实令人困惑,除非你了解 Git 的一些内部原理。 (3认同)
  • @Mike我完全同意你的观点,但是由于很多人不明白这些观点,所以 git 开发人员创建了新的命令“switch”和“restore”来适应大众;)说实话,这是一件好事,甚至如果这对高级 git 用户来说毫无意义甚至烦人 (2认同)

Ste*_*zyn 11

git checkout 有点像瑞士军刀,它有几种无关的用途。

如果您修改文件但还没有上演更改,git checkout <filename>则将撤消修改...一种取消文件更改的快捷简便的方法。您保留在同一分支中。

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

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

将其作为两个命令更为清晰。

  • 如果您想检出文件而不是分支,则必须用“--”将其与选项分开。这是许多 Git 和其他 Unix 命令的常见习惯用法。 (9认同)
  • @bjhend 和 SteveTurczyn,`git checkout &lt;filename&gt;` 经常工作,但是 `git checkout -- &lt;filename&gt;` 更好,因为 `--` 清楚地向 `git` 解析器表明选项被传递给 ` git checkout` 已结束,文件或目录路径列表已开始。这可能很重要,例如,如果您的文件名以破折号开头,例如“-myfile”。在这种情况下,执行“git checkout -- -myfile”应该可以工作,而如果没有前面的“--”,“-myfile”将看起来像传递给“git checkout”的混乱选项。 (6认同)

daG*_*aGo 7

switch有一些限制:目前您可以任何提交切换到<branch name>. 但是,不可能 <branch name>状态为detached HEAD的特定提交切换。

所以你需要使用git checkout 5efb(其中 5efb 是对任意提交的哈希引用的示例)

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