修复一个Git分离的头?


Fix a Git detached head?

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

1
svn up .

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

1
git checkout HEAD^ src/

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

现在我发现我有一个超然的头。 我不知道那是什么。 我怎么撤消?


分离头意味着您不再在分支上,您已在历史记录中检出单个提交(在这种情况下是HEAD之前的提交,即HEAD ^)。

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

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

1
git checkout master

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

1
git checkout -- path/to/foo

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

如果要保持更改与分离的HEAD相关联

  • 运行git log -n 1;这将显示分离的HEAD上的最新提交。复制提交哈希。
  • 运行git checkout master
  • 运行git branch tmp 。这会将您的更改保存在名为tmp的新分支中。
  • 如果要将所做的更改合并到master中,请从master分支运行git merge tmp。运行git checkout master后,您应该在master分支上。

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

    1
    2
    3
    4
    git commit -m"....."
    git branch my-temporary-work
    git checkout master
    git merge my-temporary-work

    摘自:

    如何处理分离头中的提交


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

    当您在此模式下已经更改了某些内容时,如何退出("修复")分离的HEAD状态,并且可选地,您希望保存更改:

  • 提交您想要保留的更改。如果要接管在分离的HEAD状态下所做的任何更改,请提交它们。喜欢:

    1
    git commit -a -m"your commit message"
  • 放弃您不想保留的更改。硬重置将丢弃您在分离的HEAD状态下所做的任何未提交的更改:

    1
    git reset --hard

    (如果没有这个,第3步就会失败,抱怨分离的HEAD中修改过的未提交文件。)

  • 看看你的分公司。通过检出之前处理过的分支退出分离的HEAD状态,例如:

    1
    git checkout master
  • 接管你的提交。您现在可以通过挑选来接管您在分离的HEAD状态下所做的提交,如我对另一个问题的回答所示。

    1
    2
    git reflog
    git cherry-pick <hash1> <hash2> <hash3> …

  • 分离头意味着:

  • 你不再是一个分支,
  • 您已在历史记录中检出了单个提交
  • 如果没有更改:可以通过应用以下命令切换到master

    1
      git checkout master

    如果您要保留更改:

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

    1
    2
    3
    git branch  temp
    git checkout master
    git merge temp


    这是我刚刚意识到自己处于一个独立的头脑并且已经做出一些改变后我刚刚做的事情。

    我承诺了改变。

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

    我记得提交的哈希值(1fe56ad)。然后我检查了我应该去的那个分支。

    1
    2
    $ git checkout master
    Switched to branch 'master'

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

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

    我认为这比创建临时分支要容易一些。


    如果你做了一些改变,然后意识到你是一个独立的头,有一个简单的解决方案:stash - > checkout master - > stash pop:

    1
    2
    3
    4
    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中签出特定提交时,您最终处于分离头状态...也就是说,您的工作副本不再反映命名引用的状态(如"master")。这对于检查存储库的过去状态非常有用,但如果您实际尝试还原更改,则不是您想要的。

    如果您对特定文件进行了更改而只是想丢弃它们,则可以使用checkout命令,如下所示:

    1
    git checkout myfile

    这将丢弃任何未提交的更改,并将文件还原为当前分支头部的状态。如果要放弃已提交的更改,可能需要使用reset命令。例如,这会将存储库重置为先前提交的状态,并丢弃任何后续更改:

    1
    git reset --hard HEAD^

    但是,如果您与其他人共享存储库,则git reset可能会造成中断(因为它会删除存储库历史记录的一部分)。如果您已经与其他人共享了更改,则通常需要查看git revert,这会生成"反提示" - 也就是说,它会创建一个新的提交,"撤消"相关更改。

    Git Book有更多细节。


    由于"分离头状态"让你在临时分支上,只需使用git checkout -将你带到你所在的最后一个分支上。


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

    git cherry-pick

    cherry-pick之前,在这种情况下需要git checkout master。此外,仅需要commit in detached head


    附录

    如果您要返回的分支是您最后一次结账,则只需使用checkout @{-1}即可。这将带您回到之前的结账时间。

    此外,您可以使用例如git global --config alias.prev对此命令进行别名,这样您只需键入git prev即可切换回上一个结帐。


    处于"分离头"意味着HEAD引用特定的未命名提交(与命名分支相反)(参见:https://git-scm.com/docs/git-checkout section Detached head)

    要解决此问题,您只需选择之前选择的分支

    git checkout @{-1}


    当您处于分离头状态并创建新文件时,首先要确保将这些新文件添加到索引中,例如:

    1
    git add .

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

    1
    git commit -a -m"my adjustment message"

    然后,您只需使用当前状态创建一个新分支:

    1
    git checkout -b new_branch_name

    你将有一个新的分支,所有的调整都将在那个新的分支中。然后,您可以继续按下遥控器和/或结账/拉/合并。


    Git告诉我该怎么做。

    如果你输入:

    1
    git checkout <some-commit_number>

    保存状态

    1
    2
    git add .
    git commit -m"some message"

    然后:

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

    1
    git pull origin master

    为我工作。它只是明确地给出远程和分支名称。


    我想保留我的更改,我只是解决这个问题......

    1
    2
    3
    4
    5
    6
    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 status,我看到我的工作目录中有一些未跟踪的文件。

    我只需要清理它们(因为我不需要它们)来运行我想要执行的rebase。