【问题标题】:Git revert screwup - recovery?Git revert 搞砸 - 恢复?
【发布时间】:2013-07-16 20:56:07
【问题描述】:

所以我在 github 上有两个分支——master 和 refactor。我在本地检查了重构,然后去了城里。在某些时候,我搞砸了并做了一个git push origin master,而不是推送到原始重构,此外,直到两周后对 master 提交进一步的有效更改后才注意到这个问题。

/我的脸

为了尝试解决问题,我在本地检查了 master,并做了一个git revert <some tag>,它通过删除我添加的各种文件来修复 master,等等。美好的结局!推给起源大师,一切都很好。继续在我的本地重构分支上工作,偶尔推动原始重构。

今天,我完成了重构的第一遍,并希望将我的更改推送到 master。我git addgit commitgit push origin refactor。一切都很好。然后我尝试推送到原始大师。失败!不足为奇,由于恶作剧需要手动合并,对吧?所以我在我的本地重构分支中 git pull origin master ......然后一切都变得松散了。我所有的新文件都被删除了,到处都是冲突。

认为正在发生的事情是,正在尝试应用恢复推送,并且与我应该干净地应用在 master 之上的完全满意的更改相冲突,如果只是的话。

所以,我还是个 git newb,有什么建议可以挽救我的跛足吗?如果您可以就如何在我未来的工作流程中避免此类错误提供一些一般性指导/教育,则可以加分。谢谢!

【问题讨论】:

    标签: git git-revert


    【解决方案1】:

    关于将来如何避免这种情况:将push.default 设置为upstream,并且只在没有进一步参数的情况下运行git push,除非您明确想要推送到不同的分支(我个人从未这样做过)。不要推到其他分支。查看master,合并refactor,推送。

    您可能还想考虑合并中的父顺序。您的工作流程导致那里一团糟。

    关于解决您的问题:您猜对了:您正在合并您的还原提交,这就是 git 所做的。以下是防止这种情况的方法:

    • 创建master 的新分支master-fix-revert 并查看:

      git checkout -b master-fix-revert master
      
    • 还原你还原:

      git revert **SHA-of-revert-commit**
      
    • 查看您的 refactor 分支并合并您的 master-fix-revert

      git checkout refactor
      git merge master-fix-revert
      
    • 删除临时分支:

      git branch -d master-fix-revert
      

    【讨论】:

    【解决方案2】:

    git revert 通过添加新提交撤消更改,这些新提交应用对先前提交中所做的反向更改。当您想要撤消更改而不重写您公开推送的分支的历史记录以及其他可能已经拉入自己的存储库的分支时,它非常有用。

    如果不是这样,我建议使用更直观的技术撤消更改,例如 git reset。假设您的主分支提交了 A、B、C,而您在此之上不小心提交了 D 和 E。

                           master
     A <-- B <-- C <-- D <-- E
    

    如果 D 和 E 是您不需要的、多余的提交,您可以这样做:

    转到本地主分支:

    git checkout master
    

    使用--hard 使其指向特定的提交。这是一个非常通用的命令,提交可以是你的对象库中的任何东西,它不一定是主历史中的提交。在你的情况下:

    git reset --hard <sha1 of C>
    
               master           
     A <-- B <-- C
    

    然后使用强制推送到您的仓库,因为您已经重写了历史记录,因此它是非快进的:

    git push origin master -f
    

    然后,结帐重构并继续努力。如果你想从你的主分支指向的地方拾取(即额外的多余提交),你可以使用 git reset 将它设置在那里:

    git checkout refactor
    git reset --hard <sha1 of E>
    
               master      refactor
     A <-- B <-- C <-- D <-- E
    

    这是可选的,当然,您可以决定使用其他方式,例如从新 master 分支重构并手动添加以前的修改,或者通过cherrypicking等。

    然后继续向refactor添加提交,然后合并到master并推送master:

    git checkout master
    git merge refactor
    git push origin master
    
                                master  
                                refactor
     A <-- B <-- C <-- D <-- E <-- F
    

    在那里,它仍然是一个非常基本的工作流程。我的建议是使用像gitk这样的工具:

    gitk --all
    

    尽可能多地查看不同分支机构的情况。

    【讨论】:

      猜你喜欢
      • 2019-03-09
      • 2015-09-02
      • 2022-01-05
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 2018-11-22
      • 2012-05-08
      相关资源
      最近更新 更多