【问题标题】:After git rebase --hard, why didn’t my topic branch change?git rebase --hard 之后,为什么我的主题分支没有变化?
【发布时间】:2019-09-11 10:55:34
【问题描述】:

我不小心用 DEV 分支重新定位了我的分支,然后将其推送到远程存储库。通过变基,我选择了当前的更改,因此我的本地更改被覆盖了。

我在变基中丢失了我之前的提交,但通过运行git log 找到了它。然后我跑了git checkout commitId 甚至git reset --hard commitId。但是,在这两种情况下,我的代码库仍然会在我的分支上显示最新的重新定位代码。

如何将我的分支恢复到之前的状态?

【问题讨论】:

  • 您是否提交了被覆盖的本地更改?如果是,请从更改中选择一个关键字并尝试git log -S <keyword> --reflog 找出哪个提交删除了更改。
  • Reset 移动分支标签。如果你先将 HEAD 从一个分支中分离出来,reset 将没有一个分支可以移动。

标签: git git-rebase git-push git-checkout git-detached-head


【解决方案1】:

分离什么?伙计,我的承诺在哪里?

检查提交的哈希或对象名称会输入 git 文档所指的 detached HEAD state

有时能够检查不在任何命名分支顶端的提交,或者甚至创建一个未被命名分支引用的新提交,这有时很有用。让我们看看当我们 checkout commit b 时会发生什么(这里我们展示了 [三种] 可能完成的方式):

$ git checkout v2.0      # or
$ git checkout master^^  # or
$ git checkout b

   HEAD (refers to commit 'b')
    |
    v
a---b---c---d  branch 'master' (refers to commit 'd')
    ^
    |
  tag 'v2.0' (refers to commit 'b')

请注意,无论我们使用哪个签出命令,HEAD 现在都直接指向提交 b。这被称为处于分离的 HEAD 状态。这意味着HEAD 指的是一个特定的提交,而不是指一个命名的分支。

正如您所观察到的,git 很乐意使用分离的 HEAD 创建新的提交、变基、合并等,但由于没有标签或分支引用生成的未命名分支,因此很容易丢失它。您可以使用git log 找到您的原始提交。当你做了更剧烈的手术时,git reflog 的输出是另一个值得关注的地方。

修复

如您的问题中所述修复您的分支将涉及以下顺序。

  1. HEAD 重新附加到您的分支(以下称为topic/my-branch
  2. topic/my-branch 重置为之前的位置
  3. 修复了之前推送中的origin/topic/my-branch
    • 要么用力推一下,要么
    • 删除旧的远程分支并推送您的固定历史记录

重新连接 HEAD

而不是通过它的 SHA-1 哈希,按名称检查您的分支

git checkout topic/my-branch

修复您的本地分支

接下来,用git reset --hard 将其放回原处。您将使用相同的命令,但上下文不同:git checkout 之后的 HEAD 指向 topic/my-branch 而不是直接指向 commitId

git reset --hard commitId

修复远程分支

您说您推送了重新定位的分支,因此更新远程存储库以反映您的更改。在一个命令中完成所有操作的方法是

git push --force origin topic/my-branch

远程存储库的管理员可能采取了非常合理的步骤来拒绝强制推送(原因见下文)。如果是这样,请尝试一系列

  1. 在远程端删除你的分支,然后
  2. 推送更正后的本地分支

在糟糕的过去,我们不得不删除不明显的远程分支

git push origin :topic/my-branch

但现在,它是拼写的

git push --delete origin topic/my-branch

已经扫清了道路,现在推动你的分支将事情恢复到原来的位置。

git push origin topic/my-branch

如果在您的遥控器上同时禁用强制推送和删除,请向对该存储库具有管理访问权限的人寻求帮助。

注意事项

大多数时候,你必须非常努力地说服 git 破坏工作。但是,git reset --hard、删除远程分支和git push --force 都是锋利的工具——在需要时很有用,但在不小心使用时会很危险。与rm -rf 一样,暂停一下,考虑一下您是否真的指的是您将要运行的命令。

【讨论】:

    【解决方案2】:

    我怀疑这里的命令顺序有点混乱。如果你这样做了

    git checkout <commitId>
    

    它会分离你的HEAD 然后你的后续

    git reset --hard <commitId>
    

    没有任何效果,因为当前没有签出分支。

    在重置之前检查您的分支,一切都会好的:

    git checkout <yourBranchName>
    git reset --hard <commitId>
    

    【讨论】:

    • 不是git reset --hard在签出提交哈希后有no效果。只是它不会影响任何分支名称,因为没有当前分支。你仍然移动到选定的提交,删除任何未提交的工作——因此git reset --hard &lt;hash&gt; 很像另一个git checkout &lt;hash&gt;,除了后者将单独对索引和工作树进行未提交的修改,代价是@ 失败987654328@ 在某些情况下。
    • @torek 我的意思是“对分支没有影响”,但你是对的,让我们避免误解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 2023-02-07
    • 2021-08-20
    • 2016-03-25
    • 2021-06-28
    • 1970-01-01
    相关资源
    最近更新 更多