Git 2.23引入了一个新的命令Git开关——在阅读了文档之后,它看起来和Git checkout <branchname>几乎一样,有人能解释一下区别或用例吗?

引入了两个新命令“git switch”和“git restore” 分裂“检出分支以推进其历史”和 “检查出索引的路径和/或一个树状的工作 从单个“git签出”中推进当前历史记录 命令。


当前回答

switch命令确实做了与签出相同的事情,但只针对那些切换分支的使用。特别是,与签出不同,它不能恢复工作树文件-而是使用与switch一起引入的restore命令来完成。

详细解释

正如您在2.23.0发布说明中提到的,引入switch和restore命令是为了将checkout命令分割为两个独立的部分:

“签出分支以改进其历史” “检查出索引和/或树状的路径,以推进当前历史”

换句话说,签出做了两件不同的事情,这个版本将这些不同的事情分开到它自己的集中命令中。

检出的双重目的可以在文档中的摘要描述中看到:

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

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

“git checkout”做太多事情是许多人困惑的来源 用户(有时甚至是老用户)。为了补救, 命令将拆分为两个新的命令:switch和restore。良好的 旧的“git checkout”命令仍然在这里,直到所有(或大部分) 用户)对此感到厌倦。

由此可以明显看出,引入新命令是为了减少混淆,因为有两个集中的命令,而不是一个多用途命令。

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

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

命令比较

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

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)替换为新命令名(switch、restore),一些先前的用法可以转换为新命令,而其他用法则需要进行额外的调整。值得注意的变化包括:

The -b/-B options for creating a new branch before switching are renamed to -c/-C. They also have long option variants (--create/--force-create), whereas previously they only had the single letter option versions. --detach (or -d) is now always required when switching to a detached head, where it was previously optional for commits but required for branches. The source tree for restoring is now given by the -s (or --source) option, rather than being an inline argument. Switching using --force now fails if there are unmerged entries, rather than ignoring them. --force has also been renamed to --discard-changes, with --force being kept as an alias.

其他回答

Git签出有点像瑞士军刀,它有几个不相关的用途。

如果你修改了一个文件,但还没有执行修改,那么git checkout <filename>将撤销修改…一种快速而简单的方法取消对文件的更改。你仍然在同一个分支。

Git checkout <branchname>(如您所注意到的)切换分支。

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

把它作为两个命令就更清楚了。

好吧,根据你链接到的文档,它的唯一目的是拆分和澄清git签出的两种不同用法:

Git开关现在可以用来改变分支,就像Git checkout <branchname>那样 Git恢复可以用于将文件重置为某些修订,如Git checkout——<path_to_file>所做的那样

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

switch有一些限制:目前你可以从任何提交切换到<分支名称>,但是不可能从<分支名称>切换到一个状态为分离HEAD的特定提交。所以你需要使用git签出5efb(其中5efb是任意提交哈希引用的一个例子)

switch命令确实做了与签出相同的事情,但只针对那些切换分支的使用。特别是,与签出不同,它不能恢复工作树文件-而是使用与switch一起引入的restore命令来完成。

详细解释

正如您在2.23.0发布说明中提到的,引入switch和restore命令是为了将checkout命令分割为两个独立的部分:

“签出分支以改进其历史” “检查出索引和/或树状的路径,以推进当前历史”

换句话说,签出做了两件不同的事情,这个版本将这些不同的事情分开到它自己的集中命令中。

检出的双重目的可以在文档中的摘要描述中看到:

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

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

“git checkout”做太多事情是许多人困惑的来源 用户(有时甚至是老用户)。为了补救, 命令将拆分为两个新的命令:switch和restore。良好的 旧的“git checkout”命令仍然在这里,直到所有(或大部分) 用户)对此感到厌倦。

由此可以明显看出,引入新命令是为了减少混淆,因为有两个集中的命令,而不是一个多用途命令。

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

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

命令比较

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

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)替换为新命令名(switch、restore),一些先前的用法可以转换为新命令,而其他用法则需要进行额外的调整。值得注意的变化包括:

The -b/-B options for creating a new branch before switching are renamed to -c/-C. They also have long option variants (--create/--force-create), whereas previously they only had the single letter option versions. --detach (or -d) is now always required when switching to a detached head, where it was previously optional for commits but required for branches. The source tree for restoring is now given by the -s (or --source) option, rather than being an inline argument. Switching using --force now fails if there are unmerged entries, rather than ignoring them. --force has also been renamed to --discard-changes, with --force being kept as an alias.

以下是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.