在查看分支上的任何先前提交时,Git开始分离头了吗?

时间:2020-05-12 02:45:57

标签: git git-branch git-bash git-detached-head

我是git的新用户,所以这可能是一个愚蠢的问题,但是突然间,每当我在git checkout 050aa9f分支中使用Development检出任何先前的提交时,git就会立即断开头部:

您处于“分离头”状态。您可以环顾四周,进行实验 更改并提交,您可以放弃在此所做的任何提交 通过执行另一次签出,不会影响任何分支机构。

如果您想创建一个新分支来保留您创建的提交,则可以 (现在或以后)通过再次将-b与checkout命令一起使用来执行此操作。示例:

git checkout -b

HEAD现在位于050aa9f [此处为代码提交标题]

但是,当我从另一个分支(例如master)签出提交时,它并没有分离头部。

我是否做了某种破坏树的工作?如何找到它的开始位置以及如何解决?

2 个答案:

答案 0 :(得分:3)

每当我[使用] ... git checkout 050aa9f ... git立刻松开头部

那是因为这种git checkout专门是分离HEAD的请求。

任何,只要您使用的名称不是分支名称,但可以将其解析为提交哈希ID,git checkout会让您处于分离状态- HEAD模式。但是,只要您使用分支名称的内容,git checkout都会使您进入正常模式。 (Git不会将其称为“ attached-HEAD”模式,但这显然是该模式的正确名称。)

这里有一些棘手的地方,通过使用新的(在Git 2.23和更高版本中)git switch命令作为VonC recommends,部分地帮助了他们。我将在这里进行介绍,但请记住,其中一些是Advanced Git,并且您不应该马上了解所有内容。 ?

  • Git可以创建一个新分支,然后按名称检查该分支,从而产生一个附加的HEAD。

  • 即使提供分支名称,也可以将--detach与分支名称一起使用,以强制Git进入分离的HEAD模式。

  • 使用-b选项,Git将始终尝试创建一个新的分支名称(然后附加到该分支名称)。在某些情况下,这可能会失败,尽管我在这里不再赘述。

  • 使用--track选项,您可以命名远程跟踪名称,例如origin/develop,Git将使用该名称来确定要创建的分支名称。 。 Git在这里选择的名称是通过剥离远程部分而形成的,因此运行git checkout --track origin/develop与运行git checkout -b develop --track origin/develop大致相同。我说大致相同,因为其他选项可以修改此行为。

  • git checkout命令本身实现了在Git 2.23及更高版本中已拆分为两个单独的命令的内容:git switchgit restore。在某些情况下,当您期望git checkout做我要描述的事情时,Git会发现您有一个名为dev文件或文件夹,并实现了现在拆分的内容输出为git restore,而不是现在的git switch。只是说这不是一件好事,而且自Git 2.23以来,git checkout现在告诉您您不确定这是什么意思,并且不只是做错误的事情。

  • 给出一个不存在但可以创建的分支名称,有时会导致创建该分支。例如,如果您还没有名为dev的分支,但是确实有origin/dev,并且您运行git checkout dev,则可能希望Git说:嗯...没有名为dev分支,也没有名为dev的文件或文件夹。我不能将其转换为分支名称,所以我将因错误退出。但这不是事实。取而代之的是,Git自言自语:呵呵,没有名为dev分支,也没有命名为文件或文件夹的文件。但是有一个origin/dev。我敢打赌,您想让我创建一个名为dev的分支,就像您已经运行git checkout --track origin/dev一样。然后就可以了。


这里值得准确地描述旧的git checkout出了什么问题,而新的git switch / git restore则没有。 (而且,正如我所提到的,git checkout本身已经变得更聪明,因此它现在不仅可以盲目地做错事,而且对于版本低于2.23的Git,请当心!){ {1}}是:

  • 切换分支的那个。这是一个非破坏性的命令:如果您有未提交的工作,git checkout 可以允许您切换分支,但是只有在此过程中您所有未提交的工作都不会被破坏时,它才会这样做。 (这很复杂。暂时不要看看,this question is all about that。)

    在Git 2.23中,您可以使用git checkout来执行此命令。您仍然仍然可以使用git switch

  • 那个掩盖您未完成的工作的人。这是一个破坏性的命令!假设您一直在编辑某些文件,并且已经决定尝试做有用的事情是没有结果的,那么现在应该彻底,不可撤消地销毁它。您希望将情况恢复原样-至少对于一个特定文件,也许对于多个文件。

    在Git 2.23中,您可以使用git checkout来执行此命令,但是在每个版本的Git中,您也可以在此处使用git restore

这意味着git checkout是一种完全安全的方法:它不会破坏正在进行的工作。 git checkout的另一种非常危险:您是在告诉Git 请抹去我正在进行的工作,这是不可挽回的。

这是我上面提到的危险。假设您在名为git checkout的文件夹中有一堆文件,的远程跟踪名称为dev,但是您还没有名为{{ 1}} 。如果您运行:

origin/dev

期望Git现在基于dev创建一个名为git checkout dev 的分支,您会感到讨厌:Git(在2.23之前)会清除您在dev上所做的所有工作文件。


origin/dev可以做更多的事情,所有这些现在都是拆分命令的一部分。为了使这个答案简短,我省略了这些内容。嗯,简短的 er 。)

答案 1 :(得分:2)

因为当我结帐我的master分支时,它不会创建分离的头部

首先,请确保执行use git switch,这样就可以确保处理分支或提交(结帐还可以处理文件,现在可以更好地与git restore配合使用)

第二,当您结帐master时,您将切换到对分支HEAD提交的间接引用。
间接是因为:

  • select value, width_bucket(value, min_value, max_value + 1, 10) bucket from ( select t.*, min(value) over () min_value, max(value) over () max_value from t ) ; 将包括“ .git/HEAD
  • refs/heads/master将包含实际的SHA1

相对于检出/切换提交,.git/refs/heads/master直接包括SHA1(无分支间接)

这就是为什么我喜欢新的git switch命令的原因:正如我在“ Why did my Git repo enter a detached HEAD state?”中解释的那样,它默认情况下期望分支而不是提交。最终很难获得不需要的/意外的分离的HEAD。