我怎样才能调和分离的HEAD与主/来源?

我是Git分支复杂性的新手。 我总是在单个分支上工作并提交更改,然后定期推送到我的远程原点。

最近,我做了一些文件的重置,让它们脱离了提交阶段,后来又做了一次rebase -i来摆脱最近的一些本地提交。 现在我处于一个我不太明白的状态。

在我的工作区域, git log显示了我期望的内容 - 我在正确的列车上提交了我不想去的地方,以及那里的新地方等。

但是我只是推到了远程仓库,那里有什么不同 - 我在rebase中杀死的一些提交被推迟了,而在本地提交的新提交不在那里。

我认为“master / origin”与HEAD是分开的,但我不清楚这意味着什么,如何使用命令行工具将其视觉化,以及如何修复它。


首先,让我们澄清一下HEAD是什么以及它在分离时的含义。

HEAD是当前签出的提交的符号名称。 当HEAD未被分离时(“正常”1情况:你有一个分支被检出),HEAD实际上指向分支的“ref”,分支指向提交。 HEAD因此“附属于”一个分支。 当您进行新的提交时,HEAD指向的分支会更新为指向新的提交。 由于HEAD指向分支,HEAD会自动跟随。

  • git symbolic-ref HEAD产生refs/heads/master
    名为“主”的分支已检出。
  • git rev-parse refs/heads/master yield 17a02998078923f2d62811326d130de991d1a95a
    该提交是主分支的当前提示或“头”。
  • git rev-parse HEAD也产生17a02998078923f2d62811326d130de991d1a95a
    这就是“符号参考”的含义。 它通过其他参考指向一个对象。
    (符号引用最初是作为符号链接实现的,但后来更改为带有额外解释的纯文本文件,以便可以在没有符号链接的平台上使用它们。)
  • 我们有HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

    当HEAD分离时,它直接指向一个提交 - 而不是间接指向一个分支。 你可以将分离的HEAD想象成一个未命名的分支。

  • git symbolic-ref HEAD失败并fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEAD得出17a02998078923f2d62811326d130de991d1a95a
    由于它不是符号引用,它必须直接指向提交本身。
  • 我们有HEAD17a02998078923f2d62811326d130de991d1a95a

    用分离的HEAD记住的重要事情是,如果它指向的提交不是其他引用(其他引用无法达到它),那么当您签出其他提交时它将变成“悬挂”。 最终,这种悬而未决的提交将通过垃圾收集过程进行修剪(默认情况下,它们会保留至少2周,并且可能会被HEAD的reflog引用而延长)。

    1使用分离的HEAD进行“正常”工作是完全正确的,您只需跟踪自己在做什么以避免将丢弃的历史记录从reflog中删除。


    交互式底座的中间步骤是通过分离的HEAD完成的(部分是为了避免污染活动分支的引用日志)。 如果您完成了全部的重新布局操作,它将使用重新布局操作的累积结果更新您的原始分支,并将HEAD重新附加到原始分支。 我的猜测是,你从来没有完全完成rebase进程; 这会让你有一个分离的HEAD指向最近由rebase操作处理的提交。

    为了从你的情况中恢复,你应该创建一个分支,指向你分离的HEAD当前指向的提交:

    git branch temp
    git checkout temp
    

    (这两个命令可以缩写为git checkout -b temp

    这会将您的HEAD重新附加到新的temp分支。

    接下来,您应该将当前提交(及其历史记录)与您希望工作的常规分支进行比较:

    git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
    git diff master temp
    git diff origin/master temp
    

    (您可能会想要尝试日志选项:add -p ,leave off --pretty=…以查看整个日志消息等)

    如果你的新temp分支看起来不错,你可能想更新(例如) master指向它:

    git branch -f master temp
    git checkout master
    

    (这两个命令可以缩写为git checkout -B master temp

    您可以删除临时分支:

    git branch -d temp
    

    最后,你可能会推动重建的历史:

    git push origin master
    

    如果远程分支不能被快速转发到新的提交中,你可能需要在这个命令的最后加上--force (即你删除了,或者重写了一些现有的提交,或者重写了一些历史记录)。

    如果您正在进行重建操作,您应该清理它。 您可以通过查找目录.git/rebase-merge/来检查是否正在进行重新.git/rebase-merge/ 。 您可以通过删除该目录(例如,如果您不再记住激活的rebase操作的目的和上下文)来手动清理正在进行的rebase。 通常你会使用git rebase --abort ,但是这会做一些你可能想要避免的额外重置操作(它会将HEAD移回原始分支并将其重置回原始提交,这将撤消上面我们做的一些工作)。


    只要这样做:

    git checkout master
    

    或者,如果您有想要保留的更改,请执行以下操作:

    git checkout -b temp
    git checkout -B master temp
    

    我遇到了这个问题,当我读到顶级投票答案时:

    HEAD是当前签出的提交的符号名称。

    我想:啊哈! 如果HEAD是为currenlty结账符号名提交,我可以调和这对master通过衍合靠在master

    git rebase HEAD master
    

    这个命令:

  • 检查master
  • HEAD的父提交标识回到从master发出的头HEAD
  • master上播放这些提交
  • 最终的结果是,所有在HEAD但不是master提交都在mastermaster仍然检出。


    关于遥控器:

    在rebase中我遇害的几个提交被推到了一边,而在本地犯下的新提交不在那里。

    远程历史记录不能再使用本地历史记录进行快速转发。 您需要强制推送( git push -f )来覆盖远程历史记录。 如果你有任何合作者,通常有必要与他们协调,这样每个人都在同一页面上。

    master推送到远程origin ,远程跟踪分支origin/master将更新为指向与master相同的提交。

    链接地址: http://www.djcxy.com/p/557.html

    上一篇: How can I reconcile detached HEAD with master/origin?

    下一篇: Move existing, uncommitted work to a new branch in Git