简体   繁体   English

git开关和git结帐有什么区别<branch></branch>

[英]What's the difference between git switch and git checkout <branch>

Git 2.23 introduces a new command git switch -- after reading the docs, it seems pretty much the same as git checkout <branchname> can someone explain the difference or use case? Git 2.23 引入了一个新命令git switch - 阅读文档后,它似乎与git checkout <branchname>可以解释一下区别吗?

Two new commands "git switch" and "git restore" are introduced to split "checking out a branch to work on advancing its history" and "checking out paths out of the index and/or a tree-ish to work on advancing the current history" out of the single "git checkout" command.引入了两个新命令“git switch”和“git restore”来拆分“签出分支以推进其历史”和“签出索引和/或树状路径以推进当前历史”从单个“git checkout”命令中提取出来。

Well, according to the documentation you link to, its sole purpose is to split and clarify the two different uses of git checkout :好吧,根据您链接到的文档,其唯一目的是拆分和阐明git checkout的两种不同用途:

  • git switch can now be used to change branches, as git checkout <branchname> does git switch现在可以用于更改分支,就像git checkout <branchname>一样
  • git restore can be used to reset files to certain revisions, as git checkout --<path_to_file> does git restore可用于将文件重置为某些版本,就像git checkout --<path_to_file>一样

People are confused by these different ways to use git checkout , as you can see from the many questions regarding git checkout here on Stackoverflow.人们对这些使用git checkout的不同方式感到困惑,正如您可以从 Stackoverflow 上有关git checkout的许多问题中看到的那样。 Git developers seem to have taken this into account. Git 开发人员似乎已经考虑到了这一点。

git checkout is a bit of a swiss army knife in that has several unrelated uses. git checkout有点像瑞士军刀,有几个不相关的用途。

If you modify a file but haven't staged the change, then git checkout <filename> will reverse the modifications... a quick and easy way to cancel changes to a file.如果您修改了文件但没有暂存更改,那么git checkout <filename>将撤消修改...取消对文件的更改的快速简便的方法。 You remain in the same branch.你留在同一个分支。

git checkout <branchname> (as you noted) switches branches. git checkout <branchname> (如您所述)切换分支。

Two completely different purposes, which could lead to confusion if a file name and a branch name are similar.两个完全不同的目的,如果文件名和分支名相似,可能会导致混淆。

Having it as two commands is clearer.将它作为两个命令更清楚。

As you noted in the 2.23.0 release notes section you quoted, the switch and restore commands were introduced to split the checkout command into two separate pieces:正如您在引用的 2.23.0 发行说明部分中所述,引入了switchrestore命令以将checkout命令拆分为两个单独的部分:

  • "checking out a branch to work on advancing its history" “检查一个分支以推进其历史”
  • "checking out paths out of the index and/or a tree-ish to work on advancing the current history" “从索引中检查路径和/或树状结构以推进当前历史”

In other words, checkout was doing two different things, and this release splits each of those different things into its own focused command.换句话说, checkout是在做两件不同的事情,而这个版本将这些不同的事情中的每一个都分解成自己的重点命令。

This dual purpose of checkout can be seen in its summary description in the documentation : checkout的双重目的可以在文档中的摘要描述中看到:

git-checkout - Switch branches or restore working tree files git-checkout - 切换分支或恢复工作树文件

The commit message for the commit that added the switch command explains the rationale:添加了switch命令的提交的提交消息解释了原因:

"git checkout" doing too many things is a source of confusion for many users (and it even bites old timers sometimes). “git checkout”做太多事情是许多用户困惑的根源(有时它甚至会咬旧计时器)。 To remedy that, the command will be split into two new ones: switch and restore.为了解决这个问题,该命令将分为两个新命令:切换和恢复。 The good old "git checkout" command is still here and will be until all (or most of users) are sick of it.旧的“git checkout”命令仍然存在,直到所有(或大多数用户)都厌倦了它。

From this, it's clear that the new commands were introduced to reduce confusion by having two focused commands, rather than one multi-purpose command.由此可见,引入新命令是为了通过两个集中命令而不是一个多用途命令来减少混乱。

Note that as of December 2021, the new commands are still listed as experimental ( switch , restore ):请注意,截至 2021 年 12 月,新命令仍列为实验性命令( switchrestore ):

THIS COMMAND IS EXPERIMENTAL.此命令是实验性的。 THE BEHAVIOR MAY CHANGE.行为可能会改变。

Command comparison命令比较

I have not found a full comparison of the commands anywhere.我还没有在任何地方找到命令的完整比较。 From reading through the documentation, I think this should be a fairly complete comparison:通过阅读文档,我认为这应该是一个相当完整的比较:

previous command上一个命令 new command新命令
git checkout <branch> git switch <branch>
git checkout N/A (use git status )不适用(使用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 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>… 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>…]

As shown in this comparison, some prior usages can be simply converted to the new commands by replacing the old command name ( checkout ) to the new one ( switch , restore ), whereas others require additional adjustment.如该比较所示,通过将旧命令名称 ( checkout ) 替换为新命令名称 ( switchrestore ),可以将一些先前的用法简单地转换为新命令,而其他用法则需要额外调整。 Notable changes include:显着的变化包括:

  • The -b / -B options for creating a new branch before switching are renamed to -c / -C切换前创建新分支的-b / -B选项重命名为-c / -C
  • --detach is now always required when switching to a detached head, where it was previously optional for commits but required for branches --detach现在在切换到分离的头部时总是需要的,以前它对于提交是可选的,但对于分支是必需的
  • The source tree for restoring is now given by the -s option, rather than being an inline argument用于恢复的源树现在由-s选项给出,而不是作为内联参数

switch has some limitations: at the moment you can switch from any commit to <branch name> , however it's impossible to switch from <branch name> to a particular commit with a status of detached HEAD . switch有一些限制:目前您可以任何提交切换到<branch name> ,但是不可能<branch name>切换到状态为detached HEAD的特定提交。 So you need to use git checkout 5efb (where 5efb is an example of a hash reference to arbitrary commit)因此,您需要使用git checkout 5efb (其中 5efb 是对任意提交的哈希引用的示例)

here is an extract from the git manual — man git-switch .这是 git 手册的摘录——man 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.可选地,可以使用-c-C自动从同名的远程分支创建一个新分支(参见--guess ),或者使用--detach将工作树从任何分支中分离,并进行切换。

Switching branches does not require a clean index and working tree (ie no differences compared to HEAD ).切换分支不需要干净的索引和工作树(即与HEAD相比没有区别)。 The operation is aborted however if the operation leads to loss of local changes, unless told otherwise with --discard-changes or --merge .但是,如果操作导致本地更改丢失,则操作将中止,除非使用--discard-changes--merge另有说明。

THIS COMMAND IS EXPERIMENTAL.此命令是实验性的。 THE BEHAVIOR MAY CHANGE.行为可能会改变。

tl;dr: When using checkout with --force , you can switch branches while in the middle of a merge. tl;dr:当使用checkout--force时,您可以在合并过程中切换分支。 You can't do this with switch .你不能用switch做到这一点。

Details:细节:

The other answers have already covered the motivation behind splitting checkout into switch and restore , as well as the fact that syntactic usage differences exist.其他答案已经涵盖了将checkout拆分为switchrestore的动机,以及存在语法使用差异的事实。 (For example you can use checkout with a commit or a remote tracking branch such as origin/main directly, but with switch you must also explicitly specify the --detach option.) However, I have found at least one significant functionality difference too. (例如,您可以直接将checkout与 commit 或远程跟踪分支(如origin/main )一起使用,但使用switch ,您还必须明确指定--detach选项。)但是,我也发现了至少一个显着的功能差异。

git switch -f is documented as such: git switch -f 记录如下:

Proceed even if the index or the working tree differs from HEAD .即使索引或工作树与HEAD不同,也要继续。 Both the index and working tree are restored to match the switching target.恢复索引和工作树以匹配切换目标。 If --recurse-submodules is specified, submodule content is also restored to match the switching target.如果指定了--recurse-submodules ,则子模块内容也会恢复以匹配切换目标。 This is used to throw away local changes.这用于丢弃本地更改。

And similarly, git checkout -f is documented as such (emphasis on the last sentence):同样, git checkout -f记录为这样(强调最后一句话):

When switching branches, proceed even if the index or the working tree differs from HEAD , and even if there are untracked files in the way.切换分支时,即使索引或工作树与HEAD不同,即使途中有未跟踪的文件,也要继续。 This is used to throw away local changes and any untracked files or directories that are in the way.这用于丢弃本地更改和任何未跟踪的文件或目录。

When checking out paths from the index, do not fail upon unmerged entries;从索引中检出路径时,不要在未合并的条目上失败; instead, unmerged entries are ignored.相反,未合并的条目将被忽略。

It seems like the last sentence applies to the other meaning of checkout , ie the restore command equivalent.似乎最后一句话适用于checkout的其他含义,即等效的restore命令。 However, when attempting to switch branches while you are currently sitting in the middle of a merge, git checkout -f will succeed, even if you have unresolved conflicts at that moment.但是,当您当前正处于合并中间时尝试切换分支时, git checkout -f将成功,即使您当时有未解决的冲突。 git switch -f does not work at all if you are currently merging (even without conflicts), as you get this error message:如果您当前正在合并(即使没有冲突), git switch -f根本不起作用,因为您收到以下错误消息:

fatal: cannot switch branch while merging致命:合并时无法切换分支

Note: this difference was tested using Git version 2.37.1注意:此差异是使用 Git 版本 2.37.1 测试的

You get different effect.你会得到不同的效果。 When you checkout you get the files of the branch you checkout.当你结帐时,你会得到你结帐的分支的文件。 If you switch the branch changes but the files don't change.如果您切换分支更改但文件没有更改。 If you commit then the commit goes to that branch.如果您提交,则提交将转到该分支。 If you are editing but you checkout then the files are reset to the file state of the checkout potentially losing work or getting a desired reversion.如果您正在编辑但签出,则文件将重置为签出的文件状态,可能会丢失工作或获得所需的还原。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 git checkout和有什么不一样 <remote> / <branch> vs git checkout <branch> ? - What's the difference between git checkout <remote>/<branch> vs git checkout <branch>? Git命令:git checkout -b和有什么不一样 <branch><remote branch> 和git分支 <branch><remote branch> ? - Git command: what is the difference between git checkout -b <branch> <remote branch> and git branch <branch> <remote branch>? “git branch”和“git checkout -b”有什么区别? - What is the difference between "git branch" and "git checkout -b"? git 分支和 git checkout -b 有什么区别? - What is the difference between git branch and git checkout -b? git checkout remotes/origin/branch 和 git checkout branch 有什么区别? - What is difference between git checkout remotes/origin/branch and git checkout branch? git reset 文件和 git checkout 文件有什么区别? - What's the difference between git reset file and git checkout file? “git reset”和“git checkout”有什么区别? - What's the difference between "git reset" and "git checkout"? 是什么导致git checkout不起作用(并且不能切换到分支) - What causes git checkout to not work (and not switch to branch) git 命令 - checkout 和 switch 之间的区别 - difference between git command - checkout and switch 在git中跟踪分支和上游分支有什么区别? - What's the difference between tracking branch and upstream branch in git?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM