'git checkout' docs claim working tree将更改;为什么编辑没有被丢弃?

bq9c1y66  于 9个月前  发布在  Git
关注(0)|答案(3)|浏览(124)

我刚接触Git,还在尝试了解分支的工作方式。根据文档,git checkout
更新工作树中的文件以匹配索引或指定树中的版本。如果>没有给出路径,git checkout也会更新HEAD以将指定的分支设置为>当前分支。
据我所知,我工作的目录中的文件(我在其中执行git init的文件)应该根据我所在的分支而改变。我很困惑,因为当我在分支之间切换时不会发生这种情况。我切换分支之前正在进行的编辑存在于我切换到的分支中。我做错了什么吗?或者git checkout不这样工作,我只是误解了文件。

a14dhokn

a14dhokn1#

Git 2.23也承认了这一点。
Git 2.23(2019年第三季度)将用两个新命令替换git checkout

请参见commit 97ed685commit d16dc42commit bcba406(2019年6月20日),commit 4e43b7fcommit 1235875commit 80f537fcommit fc991b4commit 75f4c7ccommit 4df3ec6commit 2f0896ecommit a5e5f39commit 3a733cecommit e3ddd3bcommit 183fb44commit 4058199commit a6cfb9bcommit be8ed50commit c9c935fcommit 46e91b6(2019年4月25日)和commit 328c6cb(2019年3月29日)的最后一次给药。
(由Junio C Hamano -- gitster --合并至commit f496b06,2019年7月9日)

checkout:将其一部分拆分为新命令“switch

git checkout“执行的操作太多,会给许多用户带来困惑(有时甚至会让老用户感到困惑)。

为了解决这个问题,这个命令将被拆分成两个新的命令:switch和restore。好的旧命令“git checkout“仍然存在,直到所有(或大多数用户)厌倦它。
还有:

switch:如果某些操作正在进行,则拒绝

除非你知道自己在做什么,否则换到另一个分支去做某件事,然后又换回来可能会让你感到困惑。更糟糕的是,你甚至可能忘记自己正在做某件事。当你意识到自己已经做了大量的工作时,再回去会变得更难。
考虑了一个新选项--ignore-in-progress,但由于不清楚会发生什么,因此放弃了该选项。
有时候你可以换掉,安全地回来,继续手术,有时候不行。
git-checkout的行为是自动清除合并/还原/cherry-pick,这使得它更令人困惑。
See this discussion的一个或多个。
我们可能会在将来重新考虑并添加此选项。
但现在要谨慎行事,不要允许它(你甚至不能跳过--force的检查)。
建议用户自己取消操作(希望他们考虑到后果,而不是盲目地键入命令),或者创建一个单独的工作树,而不是切换。
第三个选项是很好的老“git checkout“,但它没有提到。
请参阅git switch man page

说明

切换到指定的分支。
更新工作树和索引以匹配分支。
所有新提交都将添加到此分支的尖端。
或者,可以使用-c-C从同名的远程分支自动创建新分支(请参见--guess),或者使用--detach从任何分支中分离工作树,沿着进行切换。
切换分支不需要干净的索引和工作树(即,与HEAD相比没有差异)。
但是,如果操作导致本地更改丢失,则会中止该操作,除非--discard-changes--merge另有说明。

示例

下面的命令切换到“main“分支:

$ git switch main

字符串
在错误的分支中工作后,切换到正确的分支将使用以下命令完成:

$ git switch mytopic


但是,在您本地修改的文件中,“错误”分支和正确的“mytopic“分支可能不同,在这种情况下,上述开关将失败,如下所示:

$ git switch mytopic
error: You have local changes to 'frotz'; not switching branches.


您可以为命令给予-m标志,该命令将尝试三向合并:

$ git switch -m mytopic
Auto-merging frotz


在这个三向合并之后,本地修改 * 没有 * 注册在索引文件中,因此git diff将显示自新分支的尖端以来所做的更改。
要在切换到mytopic(即“main“分支)之前切换回上一个分支,请执行以下操作:

$ git switch -


您可以从任何提交中生成一个新分支。
例如,切换到“HEAD~3“并创建分支“fixup“:

$ git switch -c fixup HEAD~3
Switched to a new branch 'fixup'


如果要从同名的远程分支启动新分支,请执行以下操作:

$ git switch new-topic
Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin'
Switched to a new branch 'new-topic'


要 checkout 提交HEAD~3以进行临时检查或试验,而不创建新分支,请执行以下操作:

$ git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'


如果你所做的事情值得保留,你可以给它起一个新名字(不用换掉):

$ git switch -c good-surprises


请注意错误消息“git switch“提到了创建新分支的选项,显示了“-b/-B“选项,而“-c/-C“选项应该在其中,这已在Git 2.27(Q2 2020)中得到纠正。
参见Denton Liu ( Denton-L )commit 7c16ef7(2020年4月30日)。
(2020年5月8日,由Junio C Hamano -- gitster --合并于commit f4675f3

switch:修复与-c和-C相关的错误和注解

报告人:Robert Simpson
签核人:丹顿Liu
审核人:Taylor Blau
d787d311db(“checkout:split part of it to new command 'switch'”,2019-03-29,Git v2.23.0-rc 0--mergebatch #4中列出)中,通过提取checkout_main()cmd_checkout()的公共功能创建了git switch命令。
然而,在b7b5fce270(“switch-b-B的更好的名称“,2019-03-29,Git v2.23.0-rc 0--mergebatch #4中列出)中,”switch“的分支创建选项和强制创建选项分别更改为-c-C
因此,以前引用-b-B的错误消息和注解对于git switch无效。
对于引用-b-B的错误消息,请改用格式字符串,以便在调用git switch时可以打印-c-C

ioekq8ef

ioekq8ef2#

Git有一个普遍的问题,就是在一个命令中塞进八到十个不同的东西。注意:Git 2.23将其中一些拆分出来--这是有帮助的,当然,也是一个非常大的变化。(* Git 2.23应该被称为Git 3.0吗?Git 2.0改变了git add的行为,在我看来这在程度上是相似的。*)参见VonC's answer
git checkout * 可以 * 更新工作树,而且通常会这样做。
它可以改变HEAD指向的位置,有时会,有时不会。
它可以覆盖你对文件所做的工作,以防你想重置文件并撤消你的工作。或者它可以拒绝覆盖你对文件所做的工作,在改变HEAD或不改变HEAD时保持不变。
关于这一切的事情是,虽然它非常难以描述,但实际上它都是有意义的,过了一段时间,你习惯了这一点,发现一个命令在大多数时候都能做到你想做的事情。(当然,“大多数时候”可能是一个问题.)
无论如何,你看到的特定行为是一个故意的特性。假设你从分支main开始,就像大多数仓库一样:

$ git clone ...
$ git branch
* main
$

字符串
此时,您可能会编辑一些文件,进行一些工作,然后才意识到:“天哪!我本来想在分支develop上做这个!“1
Git允许您在这一点上切换到(或创建)分支develop,* 保留您的修改 *,只有一个条件:切换到develop并不需要清除它们。假设您修改了文件f1并创建了一个新的f2,现在您希望创建并 checkout 本地分支develop,该分支应该从,并自动“跟踪”,2 origin/develop

$ git checkout develop


(in非常旧的git版本,你必须拼写这个git checkout -b develop --track origin/develop)。
假设文件f1在分支main和分支develop的顶端是相同的。3这对git来说意味着它可以执行这个 checkout ,因为它不需要修改文件f1,所以它可以保留对f1的现有更改。
如果文件f2在两次提交中 * 也 * 相同,或者(如本例中所示)不存在,则不会删除任何文件,git checkout将创建新的本地分支develop,根据需要修改工作树以匹配origin/develop-这不包括修改f1,也不包括删除f2,所以你迄今为止所做的工作仍然完好无损。
这允许您将新更改提交到本地develop
(If如果你遇到Git * 确实 * 必须撤销你的更改,但仍然想将它们“移动”到另一个分支,通常的技巧是使用git stash脚本。这听起来很简单,git stash通常使用起来很简单,但它实际上是一个相当复杂的小野兽。不过,不要担心,直到你需要它。)
1这种情况经常发生在我身上。很多时候我想创建一个新的非跟踪分支,这比切换到现有的分支要简单一些,但原则仍然适用。
2这种自动跟踪允许您更轻松地引入其他人所做的更改:一旦Git使用git fetch拾取它们,Git将通知您其他人的更改,并允许您使用git mergegit rebase将您的更改与他们的更改合并合并,而无需大量额外的探查来确定谁的更改在哪里。
3因为你是Git新手,所以你应该暂时忽略一些概念,比如区分“分支的顶端”,这是一个特定的提交,“分支”,这实际上是模棱两可的--有分支 * 标签 *,然后还有由提交树形成的分支 * 结构 *。主要需要注意的是,Git仓库中有一个特殊的文件,名为HEAD,在这个特殊的文件中,git写入字符串ref: refs/heads/mainref: refs/heads/develop,以跟踪您在哪个分支上。因此,一旦git checkout X切换到分支X,它就会将ref: refs/heads/X写入HEAD
与此同时,仓库中的另一组特殊文件告诉Git,分支main引用了一个像c06f8d11b75e28328cdc809397eddd768ebeb533这样的大而丑陋的SHA-1。这是分支main的“提示”。当你在main上进行新的提交时,Git会创建新的提交“旧的提示”,然后将新的SHA-1写入分支文件,因此main现在是新提交者。
精确的细节并不重要,因为 new 提交只是推进了分支提示。

anhgbhbe

anhgbhbe3#

当您创建一个分支时,该分支将自动获取您创建此新分支时所在的分支的文件。
假设你在main分支中,你想创建一个develop分支。所有这些看起来应该是这样的:

git checkout -b develop    # create and switch to develop branch
touch text.txt             # create a file
git add .                  # add file to staging area
git commit -m "adding text.txt" 
git checkout main

字符串
然后你不会看到text.txt,因为你在main中。

相关问题