我在我的存储库中做一些工作,注意到一个文件发生了本地更改。我不再需要它们了,所以我删除了文件,以为我可以签出一份新的副本。我想做的Git相当于

svn up .

使用git pull似乎不起作用。一些随机搜索让我找到了一个有人推荐的网站

git checkout HEAD^ src/

(src是包含已删除文件的目录)。

现在我发现我有一个分离的脑袋。我不知道那是什么。我怎么撤销?


当您在git中签出一个特定的提交时,您将处于分离的头部状态。。。也就是说,您的工作副本不再反映命名引用的状态(如“master”)。这对于检查存储库的过去状态非常有用,但如果您确实试图恢复更改,则不需要检查。

如果您对特定文件进行了更改,并且只想放弃这些更改,则可以使用如下签出命令:

git checkout myfile

这将丢弃所有未提交的更改,并将文件恢复到当前分支头部的任何状态。如果要放弃已提交的更改,可以使用reset命令。例如,这将将存储库重置为上一次提交的状态,并放弃任何后续更改:

git reset --hard HEAD^

但是,如果您与其他人共享存储库,git重置可能会造成中断(因为它会擦除存储库历史的一部分)。如果您已经与其他人共享了更改,您通常希望查看git-restore,它会生成一个“反提交”,也就是说,它会创建一个新的提交来“撤消”所涉及的更改。

GitBook有更多细节。


分离的头部意味着您不再在分支上,您已经在历史中签出了一个提交(在本例中,提交是head之前的提交,即head^)。

如果要删除与分离的HEAD关联的更改

你只需要检查你所在的分行,例如。

git checkout master

下次更改文件并希望将其恢复到索引中的状态时,不要先删除该文件,只需执行以下操作

git checkout -- path/to/foo

这将把文件foo恢复到索引中的状态。

如果您希望将更改与分离的HEAD保持关联

运行gitbranchtmp-这将在名为tmp的新分支中保存更改。运行git签出主机如果您想将所做的更改合并到master中,请从master分支运行gitmergetmp。运行git checkout master后,您应该在master分支上。


不创建临时分支的解决方案。

如何退出(“修复”)分离的HEAD状态,当您已经在该模式中更改了某些内容,并且(可选)想要保存更改时:

提交要保留的更改。如果您想接管在分离HEAD状态下所做的任何更改,请提交它们。喜欢:gitcommit-a-m“您的提交消息”放弃不想保留的更改。硬重置将丢弃您在分离HEAD状态下所做的任何未提交的更改:git重置--硬(如果没有这一点,步骤3将失败,抱怨分离的HEAD中修改了未提交的文件。)查看您的分支。通过检查之前处理的分支来退出分离的HEAD状态,例如:切换到主分支接管你的承诺。现在,您可以通过樱桃采摘来接管在分离HEAD状态下所做的提交,如我对另一个问题的回答所示。数字刷新gitcherry-pick<hash1><hash2><hash3>…


如果您已经更改了不想丢失的文件,可以将其推送。我已经在分离模式下提交了它们,之后您可以移动到一个临时分支以稍后在master中集成。

git commit -m "....."
git branch my-temporary-work
git checkout master
git merge my-temporary-work

摘自:

如何处理在分离的头脑中做出的承诺


git pull origin master

对我来说很有用。它只是明确地给出了远程和分支名称。


这是我在意识到自己头脑清醒,已经做出了一些改变之后所做的事情。

我提交了更改。

$ git commit -m "..."
[detached HEAD 1fe56ad] ...

我记得提交的哈希值。然后我检查了我本该去的那家分店。

$ git checkout master
Switched to branch 'master'

最后,我将提交的更改应用于分支。

$ git cherry-pick 1fe56ad
[master 0b05f1e] ...

我认为这比创建一个临时分支要简单一些。


如果你做出了改变,然后意识到你是一个独立的人,你可以这样做:stash->checkout master->stash pop:

git stash
git checkout master   # Fix the detached head state
git stash pop         # Or for extra safety use 'stash apply' then later 
                      #   after fixing everything do 'stash drop'

您将拥有未提交的更改和正常的“附加”HEAD,就像什么都没有发生一样。


由于“分离的头状态”使您处于临时分支,所以只需使用git checkout,这将使您处于上一个分支。


补遗

如果您希望返回的分支是最后一次签出,则可以简单地使用checkout@{-1}。这将带您返回上一次结账。

此外,您可以将此命令别名为,例如,git global--config alias.prev,这样您只需键入git prev即可切换回上一个签出。


分离头部是指:

你不再在树枝上,您已在历史记录中检出一次提交

如果没有更改:可以通过应用以下命令切换到master

  git checkout master

如果您有要保留的更改:

在分离HEAD的情况下,提交工作正常,除非没有命名分支得到更新。若要使用已提交的更改更新主分支,请在您所在的位置创建一个临时分支(这样,临时分支将具有您在分离的HEAD中所做的所有已提交更改),然后切换到主分支并将临时分支与主分支合并。

git branch  temp
git checkout master
git merge temp

为了进一步澄清@Philippe Gerber的答案,这里是:

在樱桃采摘之前,在这种情况下,需要一个git结账大师。此外,它只需要在分离头中提交。


我想保留我的更改,所以,我只是在做。。。

git add .
git commit -m "Title" -m "Description"
(so i have a commit now example: 123abc)
git checkout YOURCURRENTBRANCH
git merge 123abc
git push TOYOURCURRENTBRANCH

这对我很有用


吉特告诉我怎么做。

如果键入:

git checkout <some-commit_number>

保存状态

git add .
git commit -m "some message"

然后:

 git push origin HEAD:<name-of-remote-branch>

处于“分离头部”意味着head指的是特定的未命名提交(与命名分支相对)(cf:https://git-scm.com/docs/git-checkout部分分离的头部)。实际上,这意味着您签出了一个提交,但没有与之关联的分支名称。

您可以选择只创建与提交相关联的新分支

gitbranch新的分支名称。

这允许您将当前状态保存在名为new branch name的新分支中,而不再处于分离的头部状态。

或者,如果您希望返回到以前的状态,则需要选择之前选择的分支

git结帐@{-1}


当您处于分离头部的情况并创建了新文件时,首先确保将这些新文件添加到索引中,例如:

git add .

但是,如果您只更改或删除了现有文件,则可以通过以下方式同时添加(-a)和提交消息(-m):

git commit -a -m "my adjustment message"

然后,您可以简单地使用当前状态创建一个新分支:

git checkout -b new_branch_name

你将有一个新的分支,所有的调整都将在新分支中。然后,您可以根据需要继续推送到远程和/或签出/拉入/合并。


HEAD是一个指针,它直接或间接指向特定的提交:

连接的HEAD表示它连接到某个分支(即它指向某个分支)。分离的HEAD意味着它不附加到任何分支,即它直接指向某个提交。

换句话说:

如果它直接指向提交,则HEAD被分离。如果它间接指向提交(即,它指向分支,而分支又指向提交),则会附加HEAD。


为了更好地理解带有附加/分离头的情况,让我们展示通向上面四幅图片的步骤。

我们从存储库的相同状态开始(所有象限中的图片都相同):


现在我们要执行git签出-在单个图片中使用不同的目标(顶部的命令变暗以强调我们只应用这些命令):


以下是执行这些命令后的情况:

如您所见,HEAD指向git checkout命令的目标-指向分支(四元组的前3个图像),或(直接)指向提交(四元组最后一个图像)。

工作目录的内容也会更改,以符合适当的提交(快照),即HEAD(直接或间接)指向的提交。


因此,现在我们的情况与答案开头的情况相同:


通常HEAD指向分支。当它不是指向分支,而是指向像69e51这样的提交散列时,这意味着你有一个分离的HEAD。你需要指出两个分支来解决这个问题。你可以做两件事来解决它。

git checkout other_branch//当您需要提交哈希中的代码时不可能创建一个新分支,并将提交哈希指向新创建的分支。

HEAD必须指向分支,而不是提交哈希是黄金法则。


分离的头意味着你没有正确地签出你的分支,或者你刚刚签出了一个提交。

如果您遇到这样的问题,请首先隐藏本地更改,这样您就不会丢失更改。

之后。。。使用以下命令签出所需的分支:

假设您想要分支MyOriginalBranch:

git checkout-b someName origin/MyOriginalBranch


这对我有用,它将为分离的头部分配一个新分支:

git checkout new_branch_name detached_head_garbage_name


您可能做了git重置--硬原点/分支。

试着在你的分行结账


分离的HEAD表示您当前不在任何分支上。如果您想保留当前的更改并简单地创建一个新分支,您可以这样做:

git commit -m "your commit message"
git checkout -b new_branch

之后,您可能希望将此新分支与其他分支合并。git“a dog”命令总是有用的:

git log --all --decorate --oneline --graph

意识到我有一个超然的头脑,却不知道我是如何做到的(就像三次提交一样),我还发现尝试合并、重基或樱桃选择会引发数百次合并冲突,所以我采取了不同的方法:

(假设一切都已完成(工作树“干净”))保存我的提交消息:gitlog>/tmp/log保存我的工作树:mkdir/tmp/backup&&cp-a all_my files_and_directories/tmp/backup还原到master:git checkout master删除所有工作文件和目录:rm。。。使用备份:cp-a/tmp/backup/。gitadd和gitcommit使用保存的/tmp/log中的消息,可能使用不同的文件子集重复它。。。

缺点是,如果一个文件在master之后多次更改,则会丢失提交历史记录,但最终我有了一个干净的master。


这种方法可能会丢弃部分提交历史记录,但如果旧主分支和当前状态的合并很棘手,或者您不介意丢失部分提交历史,则会更容易。

要简单地保持当前状态而不合并,请将当前分离的HEAD转换为主分支:

手动备份存储库,以防发生意外错误。提交您要保留的最后更改。创建一个临时分支(让我们将其命名为分离头),该分支将包含当前状态的文件:

git checkout -b detached-head

(a) 如果不需要保留主分支,请将其删除

git branch -D master

(b) 如果要保留,请重命名

git branch -M master old-master

将临时分支重命名为新的主分支

git branch -M detached-head master

资料来源:改编自Gary Lai的这篇Medium文章。


我也遇到过类似的情况。由于某种原因,我最终得到了一个分离的头部-我在与我认为我所在的分支相同的路径上进行了提交-例如,head是分支标记的子级,但由于某种原因分支标记停留在历史提交。。。可能是因为我推了??

它不会让我推动,因为我不被认为是在我认为我在的分支上。

我不想改变我的历史,也不想摘樱桃,我只是花了大约8周的时间在树枝上工作,所以重新设置了——这让我有点紧张!

解决方案只是执行以下操作:

git branch -f myStuckBranch HEAD
git checkout myStuckBranch

即使HEAD和myStuckBranch现在指向同一个对象,您仍需要执行签出,因为您仍然被认为处于分离的头部状态(而不是在分支上)

我不是git的专家(主要使用mercurial,这绝不会造成这种奇怪的情况),但我对这个命令的理解是,它只是说“将myStuckBranch更改为指向HEAD”。

我经常发现自己在获取后使用此命令合并来自master的更改,而不必交换我的工作目录,否则它会尝试使用旧的(无趣的)master版本:

git fetch
git branch -f master origin/master  -- err yeah don't just ignore what's been going on remotely - eg point my master at the real master
git merge master -- merge the changes into my local branch

必须一直手动执行这一操作有点烦人,但总比为了合并来自另一个分支的更改而更改工作目录要好。


使用gitrebase,您可以将HEAD移动到所需的提交

假设您的分支处于分离状态,如下所示:

* bfcb8f9 Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 (HEAD -> master) Commit 2 --amend
|/
* 1818f91 Commit 1

分离的头部是通过错误地重新定基而创建的,指向一个分离的提交,该提交之前是通过gitcommit--modify命令创建的。

如果要将HEAD ref移动到最近的提交,请使用要指向的所需HASH提交应用重基。在本例中,哈希是最近的提交:

git rebase bfcb8f9

这将使分支的HEAD指向所需的提交(在本例中是最近的):

* bfcb8f9 (HEAD -> master) Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2 --amend
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 Commit 2
|/
* 1818f91 Commit 1

补充@ralphteninija的答案。如果使用git checkout master后收到此消息:

请在切换分支之前提交更改或将其隐藏。正在中止

然后,您可以简单地使用-f标志强制签出,如下所示:

git checkout -f master

显然,这将导致丢失在分离模式中所做的所有更改。所以使用时要小心。


当我开始使用git时,这对我来说是一件令人困惑的事情,后来我明白了为什么会发生这种情况,以及处理这种情况的最佳方法是什么。

出现这种情况的根本原因是,通常gitHEAD总是指向某个分支,当您试图将HEAD指向某个特定的提交时,就会将HEAD置于分离的HEAD状态。

HEAD连接时的状态-

cat .git/HEAD     # output--> ref: refs/heads/master or ref: refs/heads/main

当HEAD处于分离状态时-

cat .git/HEAD     # output--> b96660a90cad75867453ebe1b8d11754bbb68b0e <commit hash>

解决方案-

git stash           # Temporarily shelves (or stashes) changes
git branch          # Find your default branch
git switch master   # Point HEAD to master or main branch
git stash pop       # Apply all the changes you had previously

Git:您当前不在分支上。

Git不时显示:

将历史推到当前(分离的HEAD)立即状态,使用git push origin HEAD:<name of remote branch>

这意味着:

“HEAD没有分支”

要修复此问题,请运行2个命令:

gitbranch-f{{your_working_branch}}HEAD—将分支设置为头部git checkout{{your_working_branch}}--checkout==开关分支