git checkout感到困惑

时间:2014-06-24 11:03:12

标签: git

我是git的新手,并试图围绕分支的工作方式。根据文档git checkout

  

更新工作树中的文件以匹配索引或指定树中的版本。如果>没有给出路径,git checkout也会更新HEAD以将指定的分支设置为>当前分支。

据我所知,我工作的目录中的文件(我执行git init的文件)应该根据我所在的分支进行更改。我很困惑,因为当我改变之间不会发生这种情况分支机构。在切换分支之前我正在编辑的编辑存在于我切换到的分支中。我做错了什么或git checkout不能以这种方式工作,我只是误解了文档?

3 个答案:

答案 0 :(得分:5)

Git有一个将一八个或十个不同的东西塞进一个命令的普遍问题。

git checkout 可以更新工作树,通常可以。

可以更改HEAD点的位置,有时甚至不会。

可以覆盖您对文件所做的工作,以防您想重置文件并撤消工作。或者可以拒绝覆盖您对文件所做的工作,在更改HEAD更改HEAD时保持不变。

关于这一切的事情是,虽然它非常难以描述,但它实际上都是有道理的,过了一段时间你习惯了这一点,并发现一个命令符合你的意思,大多数时间。 (这是"大部分时间"当然可能是个问题......)

无论如何,您所看到的特定行为是一种刻意的功能。我们假设您从分支master开始,就像大多数存储库一样:

$ git clone ...
$ git branch
* master
$

此时你可能会编辑一些文件,进行一些工作,然后才意识到:" gah!我打算在分支develop上执行此操作!" 1

此时允许你执行的git是切换到(或创建)分支develop保留修改,在一个条件下:切换到develop不会需要擦掉它们。我们假设您修改了文件f1并创建了一个新的f2,您现在想要创建并签出本地分支develop,该分支应该自动启动并自动生成#34 ; track", 2 origin/develop

$ git checkout develop 

(在非常旧版本的git中,你必须拼写这个git checkout -b develop --track origin/develop)。

我们还要说文件f1在分支master和分支develop的提示处是相同的。 3 这意味着什么,要git,它是可以执行此结帐,因为它不必修改文件f1,因此它可以将您现有的更改保留到f1

如果文件f2 在两次提交中都相同,或者(在这种情况下)在任何一个提交中都不存在,那么任何文件都不会被破坏,{{1将创建新的本地分支git checkout,根据需要修改工作树以匹配develop - 这不包括修改origin/develop,也不包括删除f1,所以到目前为止你所完成的工作仍然完好无损。

这样,您就可以将新的更改提交到本地f2

(如果遇到git 必须撤消更改的情况,但仍希望"将它们移动到另一个分支,通常的诀窍是使用{ {1}}脚本。这听起来很简单,develop通常很容易使用,但它实际上是一个非常复杂的小动物。不要担心,直到你需要它但是。)


1 这种情况一直发生在。很多时候我想创建一个新的非跟踪分支,这比切换到现有分支要简单一点,但原则仍然适用。

2 这种自动跟踪功能可以让您更轻松地引入其他人所做的更改:一旦git选择了git stash,git就会通知您其他人&#39 ; s-changes,让你使用git stashgit fetch将你的变化与他们的变化结合起来,而不需要进行太多额外的探索 - 即可找出哪些变化在哪里。

3 既然你是git的新手,那么概念就像分辨"分支的尖端",这是一个特定的提交,来自"分支& #34;,这实际上是模糊的 - 有分支标签,然后有提交树形成的分支结构 - 你应该忽略一段时间的其他东西。需要注意的主要事项是git存储库中有一个名为git merge的特殊文件,在该特殊文件中,git会写入字符串git rebaseHEAD,以便跟踪你所在的分支。因此,ref: refs/heads/master一旦切换到分支ref: refs/heads/develop,就会将git checkout X写入ref: refs/heads/X

同时,存储库中的另一组特殊文件告诉git,分支HEAD指的是像X这样的丑陋SHA-1之一。这是"提示"分支master。当您在c06f8d11b75e28328cdc809397eddd768ebeb533上进行新的提交时,git会创建新的提交"一个旧的提示",然后将新的SHA-1写入分支文件,以便master现在是你的新提交。

准确的细节并不重要,因为 new 提交只是推进分支提示。

答案 1 :(得分:1)

Git 2.23确认了这种混淆,它用两个新命令代替了checkout:

请参见commit 97ed685commit d16dc42commit bcba406(2019年6月20日),commit 4e43b7fcommit 1235875commit 80f537fcommit fc991b4commit 75f4c7ccommit 4df3ec6commit 2f0896ecommit a5e5f39commit 3a733cecommit e3ddd3bcommit 183fb44commit 4058199,{ {3}之前的{3}},commit a6cfb9bcommit be8ed50commit c9c935fcommit 46e91b6(2019年3月29日)。
(由commit 328c6cbNguyễn Thái Ngọc Duy (pclouds)中合并,2019年7月9日)

  

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

     

git checkout”对很多用户来说是太多困惑的来源(有时甚至会咬住旧计时器)。
  为了解决这个问题,该命令将分为两个新命令:switch和restore。好的旧的“ git checkout”命令仍然在这里,直到所有(或大多数)   的用户)已经厌倦了。

并且:

  

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

     

除非您知道自己在做什么,否则切换到另一个分支以执行某些操作然后又切换回去可能会造成混乱。更糟糕的是,您甚至可能会忘记自己陷入了困境。   到您意识到的时候,您可能已经做了大量的工作,并且很难回头。

     

考虑了一个新选项--ignore-in-progress,但由于尚不清楚应该发生什么,所以放弃了该选项。
  有时您可以离开并安全地返回并继续操作。有时候不行。
  并且git-checkout的行为是自动清除合并/还原/樱桃选择,   这使它变得更加混乱。
  Junio C Hamano -- gitster --

     

将来我们可能会重新访问并添加此选项。
  但是,现在就安全地播放它,并不允许它(您甚至无法使用--force跳过此检查)。
  建议用户自己取消操作(并希望他们考虑后果,而不是盲目地键入命令),或者创建一个单独的工作树而不是切换。

     

第三个选项是旧的“ git checkout”,但未提及。


请参见commit f496b06

  

说明

     

切换到指定的分支。
  更新工作树和索引以匹配分支。
  所有新提交都将添加到该分支的提示。

     

(可选)可以使用-c-C从同名的远程分支(请参见--guess)中自动创建新分支,也可以使用以下方法从任何分支中分离工作树: --detach,以及切换。

     

切换分支不需要干净的索引和工作树(即与HEAD相比没有任何区别)。
  但是,如果该操作导致丢失本地更改,则该操作将中止,除非用--discard-changes--merge另行通知。


  

示例

     

以下命令切换到“ master”分支:

$ git switch master
     

在错误的分支上工作之后,将使用以下命令完成切换到正确的分支的操作​​:

$ 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将向您显示自新分支的尖端以来所做的更改。 / p>      

要切换回上一个分支,然后再切换到mytopic(即“ master”分支):

$ 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'
     

要检出提交HEAD~3以进行临时检查或实验   而不创建新分支:

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

如果事实证明您所做的一切值得保留,您可以   始终为其创建一个新名称(无需切换):

$ git switch -c good-surprises

答案 2 :(得分:0)

当您创建分支时,该分支将自动获取您在创建此新分支时所在分支的文件。

让我们说你在主分公司,你想创建一个" develop"分支

所有这些都应该是这样的:

** git checkout -b develop //创建并切换到开发分支

触摸text.txt //创建text.txt文档

git add。 //添加text.txt

git commit -m"添加text.txt"

git checkout master

然后你因为你在Master中而没有看到text.txt