处于分离头状态时如何保存更改?

20

在使用Git时,我需要回到一个特定的提交。我进行了一些更改,现在想要提交它们。有什么正确的方法吗?

我的项目现在处于分离头状态。如果我提交更改,它们会被保存吗?

git commit

? 否则,我应该怎么做才能不丢失我的更改?


1
我做了一些更改,现在想要保存它们。请具体说明:你所说的“保存”是什么意思?你主要有两个选项:提交(commit)或者隐藏(stash)。无论哪种方式都会在某种程度上“保存”你的更改。你指的是哪一个?此外,你可能还想创建一个分支(branch)。 - jub0bs
我想提交我的修改。 - Nikolas
我已经相应地编辑了你的问题。 - jub0bs
1
你想对在你前面的旧提交发生什么?也就是说,你回到了某个提交,那么该提交之前还有一些提交。你还关心那些提交吗?(它们是否已经推送到其他人的上游,并且你是否关心这些人) - RJFalconer
我想将“在前面”的提交与此处的分离头状态合并。由于“在前面”存在一些错误,所以我回到了之前的提交。 - Nikolas
我想你想要将现有的“in front”提交应用于更改后的父提交。这样说对吗?听起来像是你想要使用git rebase <commit to edit> -i,然后按照交互式变基指南操作。指南链接:https://help.github.com/articles/about-git-rebase/ - RJFalconer
4个回答

45

免责声明:Git并不复杂,只是功能强大。请不要因为我写了一个很长的答案而感到害怕 :)

您拥有:
master: a-b-c-d-e-f

并且想要更改c。您执行了以下操作:
* git checkout c (避免在将来检出提交记录。转而移动分支头)
* 更改了一些文件

您现在所在位置如下:

master: a-b-c-d-e-f
             \未提交的工作,已分离

如果您想要在修改后的"c"上重新应用"d-e-f"

(如果您已经推送,下游的人将需要从上游的变基中恢复)

  1. git stash .
  2. git checkout master
  3. git stash pop (解决冲突)
  4. git stage .
  5. git commit -m "g的临时名称"
  6. (master: a-b-c-d-e-f-g)
  7. git rebase c -i ("将我的当前分支重新应用到点c上,让我交互地操作提交记录",即使 d-e-f 重新父节点(变基)到一个新的c)
  8. 按照交互式变基指南,你需要重新排序g,使其在c之后,然后将变基命令从pick改为fixup。使用dd删除一行,使用P放置它,在输入模式下输入“fixup”,然后:wq保存并退出vim。
  9. (master: a-b-c'-d'-e'-f',其中c'是你在变基过程中合并gc的结果。d-e-f已经变成了d'-e'-f',因为它们的祖先已经改变,所以就git而言,它们不是“相同”的提交,但它们的内容保持不变)

  10. 如果您想撤消d-e-f(并重写历史记录,使其好像从未存在)

    (如果您已经推送了,下游的人将需要从上游的变基中恢复):

    1. git stash .
    2. git checkout master
    3. (master: a-b-c-d-e-f,stashed文件最初基于c)
    4. git reset --hard c(放弃从c开始的主分支上的所有文件和提交)
    5. (master: a-b-c,带有stashed文件)
    6. git stash pop (解决冲突)
    7. (master: a-b-c-*)
    8. git stage .
    9. git commit -m "g的描述"
  11. (主分支: a-b-c-g)

如果你想撤销d-e-f(但保留它们在历史记录中):

  1. git stash
  2. git revert --no-commit d
  3. git revert --no-commit e
  4. git revert --no-commit f
  5. git push
  6. git stash pop (将没有冲突)
  7. git stage .
  8. git commit -m“为了修复...撤销d-e-f”
  9. git push

如果你已经git push了d-e-f,并且你想将它们保持分开:

听起来你的新更改是基于主分支的一个新分支。 git branch <foo>


1
令人惊叹的全面回答,提供了多种技术和工作流程的见解。你应该得到更多的赞誉/关注。只有一个点赞?天哪。 - temporary_user_name
非常好的答案!谢谢!帮了我很多! - Guilhermlimma

8

从这个提交中创建一个新分支,然后进行 commit

git checkout -b <branchname>
git commit 

假设您已经将文件暂存(即git add myfile1 myfile2)。

1
在这种情况下,您可能希望说明为什么创建分支更可取。 - jub0bs
我还没有做任何事情。我认为我需要更多了解有关暂存文件的知识。 - Nikolas
执行这些命令后,它确实将我的更改放入了新分支中,但我仍然看到新(当前)分支为“detached”。 - user2568374

5

如何在分离的 HEAD 中保存您的工作:

git checkout -b <new-branch-name-for-detached-head> <sha-of-the-detached-head>

如果你想将它合并到主分支:

git checkout master
git merge <new-branch-name-you-have-just-created>

0

如果您因为检出标签(git checkout tags/<tag-name>)而处于“分离的 HEAD”状态,则可以使用 -c 开关命令创建一个新分支来保留您创建的提交。

git switch -c <new-branch-name>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接