Git 在查看分支上的任何先前提交时开始分离头部?
Git started detaching head when viewing any previous commits on a branch?
我是一个新的 git 用户,所以这可能是一个愚蠢的问题,但是每当我在我的 Development
分支中检查任何以前提交的类似 git checkout 050aa9f
的东西时,突然间, git 立即分离头部:
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b
HEAD is now at 050aa9f [Code commit title here]
但是当我从另一个分支签出提交时,例如 master
它不会分离头部。
我是不是以某种方式破坏了我的树?我怎样才能找到它的起点,我该如何解决它?
Because when I checkout my master branch, it does not create a detached head
首先,确保 use git switch
, that way you are sure to deal with branch or commits (checkout deals also with files, now better served with )
其次,当您签出 master 时,您正在切换到对分支 HEAD 提交的间接引用。
间接原因:
.git/HEAD
将包括“refs/heads/master
.git/refs/heads/master
将包括实际的 SHA1
与 checkout/switch 提交相反,.git/HEAD
直接包含 SHA1(无分支间接)
这就是为什么我喜欢新的 git switch
command: as I explain in "Why did my Git repo enter a detached HEAD state?",它默认需要一个分支,而不是提交。很难以 unwanted/unexpected 分离的 HEAD 结束。
whenever I [use] ... git checkout 050aa9f
... git immediately detaches the head
那是因为这种git checkout
是专门要求detach HEAD
.
任何 你使用的东西不是分支名称,但可以解析为提交哈希 ID,git checkout
会让你进入分离头模式。但是任何时候你使用 是 分支名称的东西,git checkout
都会让你进入正常模式。 (Git 不称此为“附加头”模式,但这是该模式的明显正确名称。)
这里有几个棘手的问题,其中一些可以通过使用新的(在 Git 2.23 及更高版本中)git switch
命令作为 来部分解决。我将在这里逐一介绍,但请记住,其中一些是高级 Git 并且您不需要立即了解所有内容。
Git 可以创建一个新分支,然后按名称检查该分支,从而产生附加的 HEAD。
您可以使用带有分支名称的 --detach
来强制 Git 进入分离的 HEAD 模式,即使您提供了分支名称也是如此。
使用 -b
选项,Git 将始终尝试创建一个新的分支名称(然后附加到它)。这在某些情况下可能会失败,但我不会在这里详细介绍。
使用--track
选项,您可以命名一个远程跟踪名称,如origin/develop
和Git使用该名称来确定要创建的分支名称。 Git这里取的名字是把remote部分剥离出来的,所以运行ninggit checkout --track origin/develop
和运行ninggit checkout -b develop --track origin/develop
大致相同。我说 大致 相同,因为其他选项可以修改此行为。
git checkout
命令本身实现了在 Git 2.23 及更高版本中被拆分为两个单独的命令:git switch
和 git restore
.在某些情况下,当您希望 git checkout
执行我将要描述的操作时,Git 会发现您有一个名为 dev
的 文件或文件夹 ] 并实施现在拆分为 git restore
的内容,而不是现在 git switch
的内容。这...不是一件好事,我们只是说,自从 Git 2.23 以来,git checkout
现在 告诉 你不确定你的意思在这里,不只是做 错误的 事情。
给一个不存在但可以创建的分支命名,有时会导致创建该分支。例如,如果您 还没有 一个名为 dev
的分支,但是有一个 origin/dev
,并且您 运行 git checkout dev
,您可能希望 Git 说:Huh ...没有 branch 命名为 dev
并且没有文件或文件夹命名为 dev
。我不能把它变成一个分支名称,所以我会报错退出。 但事实并非如此。相反,Git 对自己说:嗯,没有 分支 命名为 dev
,也没有文件或文件夹命名。但是有一个origin/dev
。我敢打赌你想让我 创建 一个名为 dev
的分支,就好像你有 运行 git checkout --track origin/dev
. 然后它做到了。
值得在这里准确描述旧的 git checkout
出了什么问题,而新的 git switch
/ git restore
拆分没有。 (而且,正如我提到的,git checkout
本身变得更加智能,因此它现在不会盲目地做错事——但是对于 2.23 之前的 Git 版本,请注意!)两个“ git checkout
的种类”是:
切换分支的那个。这是一个非破坏性命令:如果您有未提交的工作,git checkout
可能 让您切换分支,但它只会在您未提交的 none工作将在此过程中被破坏。 (这个比较复杂,先不看,但是this question is all about that。)
在Git 2.23中,您可以使用git switch
来执行此命令。您仍然可以使用 git checkout
。
破坏您未提交的工作的那个。这是破坏性的命令!假设您一直在编辑一些文件,并且您认为您尝试做一些有用的事情是徒劳的,现在应该彻底地、不可挽回地销毁。您想将事情恢复到原来的样子 — 至少,对于一个特定的文件,也许对于几个文件。
在Git 2.23中,您可以使用git restore
执行此命令,但在Git的每个版本中,您也可以在此处使用git checkout
。
这意味着一种 git checkout
是完全安全的:它永远不会破坏正在进行的工作。另一种 git checkout
非常危险:你在告诉 Git 请彻底清除我正在进行的工作。
这就是我上面提到的危险。假设您在名为 dev
、 和 的文件夹中有一堆文件,远程跟踪名称 origin/dev
,但您 还没有一个名为 dev
的分支。如果你 运行:
git checkout dev
期望Git现在基于origin/dev
创建一个名为dev
的分支,你会得到一个令人讨厌的惊喜:Git(2.23之前)抹掉你的任何工作改为在 dev/*
文件上完成。
(git checkout
可以做更多的事情,所有这些现在都是拆分命令的一部分。为了让这个答案简短,我将它们省略了。好吧,简短呃,总之。)
我是一个新的 git 用户,所以这可能是一个愚蠢的问题,但是每当我在我的 Development
分支中检查任何以前提交的类似 git checkout 050aa9f
的东西时,突然间, git 立即分离头部:
You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example:
git checkout -b
HEAD is now at 050aa9f [Code commit title here]
但是当我从另一个分支签出提交时,例如 master
它不会分离头部。
我是不是以某种方式破坏了我的树?我怎样才能找到它的起点,我该如何解决它?
Because when I checkout my master branch, it does not create a detached head
首先,确保 use git switch
, that way you are sure to deal with branch or commits (checkout deals also with files, now better served with
其次,当您签出 master 时,您正在切换到对分支 HEAD 提交的间接引用。
间接原因:
.git/HEAD
将包括“refs/heads/master
.git/refs/heads/master
将包括实际的 SHA1
与 checkout/switch 提交相反,.git/HEAD
直接包含 SHA1(无分支间接)
这就是为什么我喜欢新的 git switch
command: as I explain in "Why did my Git repo enter a detached HEAD state?",它默认需要一个分支,而不是提交。很难以 unwanted/unexpected 分离的 HEAD 结束。
whenever I [use] ...
git checkout 050aa9f
... git immediately detaches the head
那是因为这种git checkout
是专门要求detach HEAD
.
任何 你使用的东西不是分支名称,但可以解析为提交哈希 ID,git checkout
会让你进入分离头模式。但是任何时候你使用 是 分支名称的东西,git checkout
都会让你进入正常模式。 (Git 不称此为“附加头”模式,但这是该模式的明显正确名称。)
这里有几个棘手的问题,其中一些可以通过使用新的(在 Git 2.23 及更高版本中)git switch
命令作为
Git 可以创建一个新分支,然后按名称检查该分支,从而产生附加的 HEAD。
您可以使用带有分支名称的
--detach
来强制 Git 进入分离的 HEAD 模式,即使您提供了分支名称也是如此。使用
-b
选项,Git 将始终尝试创建一个新的分支名称(然后附加到它)。这在某些情况下可能会失败,但我不会在这里详细介绍。使用
--track
选项,您可以命名一个远程跟踪名称,如origin/develop
和Git使用该名称来确定要创建的分支名称。 Git这里取的名字是把remote部分剥离出来的,所以运行ninggit checkout --track origin/develop
和运行ninggit checkout -b develop --track origin/develop
大致相同。我说 大致 相同,因为其他选项可以修改此行为。git checkout
命令本身实现了在 Git 2.23 及更高版本中被拆分为两个单独的命令:git switch
和git restore
.在某些情况下,当您希望git checkout
执行我将要描述的操作时,Git 会发现您有一个名为dev
的 文件或文件夹 ] 并实施现在拆分为git restore
的内容,而不是现在git switch
的内容。这...不是一件好事,我们只是说,自从 Git 2.23 以来,git checkout
现在 告诉 你不确定你的意思在这里,不只是做 错误的 事情。给一个不存在但可以创建的分支命名,有时会导致创建该分支。例如,如果您 还没有 一个名为
dev
的分支,但是有一个origin/dev
,并且您 运行git checkout dev
,您可能希望 Git 说:Huh ...没有 branch 命名为dev
并且没有文件或文件夹命名为dev
。我不能把它变成一个分支名称,所以我会报错退出。 但事实并非如此。相反,Git 对自己说:嗯,没有 分支 命名为dev
,也没有文件或文件夹命名。但是有一个origin/dev
。我敢打赌你想让我 创建 一个名为dev
的分支,就好像你有 运行git checkout --track origin/dev
. 然后它做到了。
值得在这里准确描述旧的 git checkout
出了什么问题,而新的 git switch
/ git restore
拆分没有。 (而且,正如我提到的,git checkout
本身变得更加智能,因此它现在不会盲目地做错事——但是对于 2.23 之前的 Git 版本,请注意!)两个“ git checkout
的种类”是:
切换分支的那个。这是一个非破坏性命令:如果您有未提交的工作,
git checkout
可能 让您切换分支,但它只会在您未提交的 none工作将在此过程中被破坏。 (这个比较复杂,先不看,但是this question is all about that。)在Git 2.23中,您可以使用
git switch
来执行此命令。您仍然可以使用git checkout
。破坏您未提交的工作的那个。这是破坏性的命令!假设您一直在编辑一些文件,并且您认为您尝试做一些有用的事情是徒劳的,现在应该彻底地、不可挽回地销毁。您想将事情恢复到原来的样子 — 至少,对于一个特定的文件,也许对于几个文件。
在Git 2.23中,您可以使用
git restore
执行此命令,但在Git的每个版本中,您也可以在此处使用git checkout
。
这意味着一种 git checkout
是完全安全的:它永远不会破坏正在进行的工作。另一种 git checkout
非常危险:你在告诉 Git 请彻底清除我正在进行的工作。
这就是我上面提到的危险。假设您在名为 dev
、 和 的文件夹中有一堆文件,远程跟踪名称 origin/dev
,但您 还没有一个名为 dev
的分支。如果你 运行:
git checkout dev
期望Git现在基于origin/dev
创建一个名为dev
的分支,你会得到一个令人讨厌的惊喜:Git(2.23之前)抹掉你的任何工作改为在 dev/*
文件上完成。
(git checkout
可以做更多的事情,所有这些现在都是拆分命令的一部分。为了让这个答案简短,我将它们省略了。好吧,简短呃,总之。)