Git 恢复远程分支上的提交

Git 恢复远程分支上的提交,git,Git,我在一家本地分支机构工作,添加了许多提交。 然后我把它推到了远程登台分支 现在,我必须撤消已推送到remote staging的最后一次提交,这是我的本地分支到remote staging的合并 从其他答案来看,我所理解的是,我必须使用revert而不是reset以干净的方式进行恢复,不是吗 所以我要做的是: 创建一个新的本地分支,名为cleaning,将master作为父级(位于staging之后) 将远程暂存拉入清洗 使用git revert{staging中最后一个好的提交哈希值} 现在,

我在一家本地分支机构工作,添加了许多提交。
然后我把它推到了
远程登台
分支

现在,我必须撤消已推送到
remote staging
的最后一次提交,这是我的本地分支到
remote staging
的合并

从其他答案来看,我所理解的是,我必须使用revert而不是reset以干净的方式进行恢复,不是吗

所以我要做的是:

  • 创建一个新的本地分支,名为
    cleaning
    ,将
    master
    作为父级(位于staging之后)
  • 将远程
    暂存
    拉入清洗
  • 使用
    git revert{staging中最后一个好的提交哈希值}
  • 现在,
    清理
    应该处于良好的提交状态,并且在我的错误推送之前处于与远程转移相同的状态,不是吗
  • 现在我应该将
    cleaning
    推入
    remote staging
    以恢复远程分支。用什么旗子

  • 我说得对吗?因为
    git status
    处于第4点告诉我,我已经掌握了
    登台的最新信息,所以不要让它变得复杂

    首先,您需要执行一个
    git日志
    ,以找出要还原的提交ID。例如,它是commit
    abc123
    。如果你知道这是最后一个,你可以使用一个特殊的标识符“头”

    然后,首先在本地“暂存”分支中本地还原它:

    注意:对于日志中的最后一次提交,您将写入
    git revert HEAD

    然后更新远程“登台”:

    说明:在git中,如果您有一个远程存储库,您将处理两个不同的存储库(本地和远程)。在执行git签出暂存之后,实际上创建了一个表示远程分支的独特本地名称
    git revert
    实际上不会删除您的提交,但它会在顶部创建一个新的提交,该提交会撤消所有更改(如果您添加了一个文件,新的提交会将其删除,如果您删除了一行,新的提交会将其重新添加,等等),也就是说,它是对日志的一个添加,这就是推送将被清除的原因

    如果你真的想让它消失,这样就没有人可以责怪你,你可以冒险:

    git checkout staging
    git reset --hard HEAD^
    git push -f
    
    (重置行重定本地“暂存”分支的目标,以使其指向在顶部提交之前的提交)

    一般来说,强制推送是一种不好的做法,但保留无用的提交和恢复也不好,因此另一种解决方案是实际创建一个新分支“staging2”,并在该分支中进行测试:

    git checkout staging
    git checkout -b staging2
    git reset --hard HEAD^
    git push
    
    TL;博士 记住,
    git revert
    实际上意味着撤销更改,恢复到某个特定版本。可以实现还原到/还原,但执行此操作的命令是
    git checkout
    git read tree
    (由于不同的原因,这两个命令都有点棘手)。具体见和

    这里唯一真正棘手的部分是“恢复合并”。这相当于在合并提交上使用
    git revert-m1
    ,这非常容易运行;但这意味着之后,您不能重新合并,因为Git非常确定(而且正确)您已经合并了所有这些工作,并且正确的结果已经就绪(事实就是这样,您只是稍后才将其取消)。要将其全部放回原处,您可以还原还原

    恢复会进行一次新的提交,与每次提交一样,只会向当前分支添加一次新的提交。您可以像往常一样在自己的存储库中执行此操作。剩下的工作只是将新提交推送到其他Git存储库中,将其添加到其他Git的集合中,作为其分支之一的新提示

    长(涉及很多细节) 首先,让我们回顾一下,因为短语remote branch没有任何意义,或者更确切地说,对太多不同的人来说意味着太多不同的事情。在这两种情况下,它都会导致通信失败

    Git确实有分支,但即使是“分支”一词也有歧义(请参阅)。我发现最好是具体一点:我们有分支名称,如
    master
    staging
    以及您建议的
    cleaning
    。Git也有远程跟踪名称或远程跟踪分支名称,如
    源代码/staging
    ,但令人困惑的是,Git将这些名称存储在本地,即存储在您自己的存储库中(仅限)。您的Git使用您的
    origin/staging
    来记住您的Git在他们的Git上看到了什么,当您的Git最后一次与他们的Git交谈时,并询问他们有关他们的
    staging

    因此,这里问题的根源是您的Git存储库是您的,但是还有第二个Git存储库不是您的,您最终希望在另一个Git存储库上做一些事情。这里的限制是,Git只允许您在存储库中执行这些操作,之后您将最终运行
    gitpush
    git push
    步骤将把一些提交从您的git存储库转移到他们的git存储库。此时,您可以要求他们的Git设置他们的名称他们的
    staging
    ——他们要么说是,我已经设置好了(您的Git现在将更新您的
    origin/staging
    ,以记住这一点),要么说否,我拒绝设置,原因如下:___;(在此处插入原因)

    因此,您将在存储库中执行的操作是设置适当的步骤,以便他们的Git在存储库中接受commit you
    Git push
    ,并更新他们的
    staging
    。在完成这些步骤时,请记住这一点。有多种方法可以做到这一点,但以下是我将使用的方法

  • 运行
    git fetch
    。此命令始终可以安全运行。如果您有多个遥控器,您可以给它一个特定遥控器的名称,但大多数人只有一个,名为
    origin
    ,如果您只有一个,则有
    git checkout staging
    git reset --hard HEAD^
    git push -f
    
    git checkout staging
    git checkout -b staging2
    git reset --hard HEAD^
    git push
    
    git checkout staging
    git merge --ff-only origin/staging
    
    ...--o--o--o---M   <-- staging (HEAD), origin/staging
             \    /
              o--o   <-- feature/whatever
    
                     W   <-- staging (HEAD)
                    /
    ...--o--o--o---M   <-- origin/staging
             \    /
              o--o   <-- feature/whatever
    
                     W   <-- staging (HEAD), origin/staging
                    /
    ...--o--o--o---M
             \    /
              o--o   <-- feature/whatever
    
    git checkout <something-else>
    git branch -d staging
    
    ...--o--o--o---M--W   <-- origin/staging
             \    /
              o--o   <-- feature/whatever