git恢复选择性更改

时间:2017-09-26 16:33:57

标签: git

人, 我有以下提交推送到远程主人。

commit fba0f87
commit 1025716
commit 0f2d03c
commit 6449799
commit 4854bf7

所以现在我的脑袋坏了,我想恢复原状。我想删除提交1025716和6449799,但保留其余的。我怎样才能做到这一点? 如何创建只有fba0f87,0f2d03c和4854bf7更改的新提交并推送该提交以使我的主服务器恢复正常。

3 个答案:

答案 0 :(得分:1)

由于您已经将这些提交推送到远程存储库,因此您不应该使用任何重写历史记录的命令(例如git rebase),因为这会导致其他人从此存储库中提取更改时出现问题

您剩下的选择是使用git revert来摆脱您不想要的提交:

git revert 6449799
git revert 1025716

git revert的每个实例都将创建一个新的提交,用于删除指定提交所做的更改。

运行这些命令(包括根据需要修复任何合并冲突)后,您可以推送这两个新提交,以有效删除您不再需要的原始提交。

答案 1 :(得分:1)

将来避免这种情况

首先,请考虑以下因素以避免再次遇到这种情况:

  1. 在单独的分支中进行持续更改,直到您准备好一些经过测试和工作的更改合并到master。然后,您可以将干净的历史记录合并或变为master
  2. 在进行正在进行的小改动时,不要经常远程推送。只需在本地提交,然后在完成所有测试和工作后,就可以通过单个提交进行远程合并。
  3. 这可以让你在遇到这样的问题时重写本地历史记录,如果你愿意,然后当你推送历史记录时会很干净。

    最好的答案是......

    根据Andy的回答,

    git revert将添加一个新的提交,以撤消您需要撤消的提交中的更改。

    在大多数情况下,这确实是最好的答案 - 真的没有必要拥有完整的历史记录 - 当您创建缺陷时,只需修复它并提交修复程序。

    但如果您真的想知道如何清理历史记录,请继续阅读......

    清理master

    的历史记录

    如果您是唯一使用此遥控器的人,则只需重写历史记录即可。有很多不同的方法可以做到这一点 - rebase,cherry-pick等。例如,你可以:

    1. 结账4854bf7
    2. 创建一个新分支(可能称之为fix?)
    3. cherry-pick 0f2d03c
      • 如果在此处进行新提交,则修复任何合并冲突
      • 如果您想保留提交,您可以在此时提交,保留原始提交消息或创建新提交消息
    4. cherry-pick fba0f87
      • 修复任何合并冲突
      • 进行最终提交(再次,只需重用原始提交消息,添加或创建新消息)
    5. a - b - c - d - e  <-- master currently here  
       \                                            
        c' - e'          <-- fix currently here            
      
      1. 此时,如果您想将master分支移至此新分支并有效删除原始master
        • 结帐master
        • 将主分支重置为fix
        • 删除fix分支
      2. 如果你遵循#5,你最终得到:

        a - c' - e'              <-- master
         \
          [b] - [c] - [d] - [e]  <-- will be garbage collected eventually
        

        这可能需要强制推送才能将这些新更改推送到远程,当然,只有在没有其他人已经进行了这些更改或者您已经与可能拥有它的所有人协调此修复时,才应该这样做。

        请注意,您也可以将上述策略与fix一起使用,以便按照您希望的方式获取所有内容,然后从master合并到fix。这与revert相同,但是如果这些提交中的更改很大和/或很复杂,您可能希望在单独的分支中处理重新集成,这更容易处理,然后尝试跟踪进程内的逆转。

答案 2 :(得分:0)

Checkout commit 4854bf7(最后一个好的提交)并挑选你要保留的其他提交。然后强制推送到master以覆盖提交历史记录。

警告:确保在强制推送之前合并其中的任何其他提交是否合并,因为这将覆盖master中的历史记录。此外,任何包含原始历史记录的存储库都需要在它们可以推送之前从主服务器强制提取,这意味着它们可能会丢失本地更改。

git checkout 4854bf7
git cherry-pick 0f2d03c
git cherry-pick fba0f87

现在,您当前的HEAD位于fba0f87,日志中只包含您要保留的提交。您可以使用git log进行检查。

现在,确保您仍在跟踪远程主控,并执行上述警告中提到的检查:

git push -f