将合并还原为母版,保留要素分支更改,而无需更改历史记录

时间:2019-12-18 23:07:56

标签: git

我有一个功能分支和一个主分支。我对该功能进行了一些工作,合并到母版中,推送了更改,然后在远程和本地删除了功能分支。到目前为止,一切都很好。

合并后,我意识到我的功能更改存在问题。我想撤消母版上的合并,但仍保留功能更改,以便我可以再次进行处理。我不想重写master的历史,因为其他人也在研究它。我认为我最好的选择是使用revert进行新的提交以解决问题?

我最初的经历:

A---B---C---D   [master]
     \      
      E----F    [feature]

我现在所拥有的:

A---B---C---D---E'---F' [master]

我想要什么:

A---B---C---D---E'---F'---RE'---RF'        [master]
                                 \
                                  E"---F"  [feature]

RE'还原E',RF'还原F'。同时,E“与原始E包含相同的内容,而F”与原始F包含相同的内容。

我如何做到这一点?

3 个答案:

答案 0 :(得分:2)

同样,有很多方法可以做到这一点。给定您所需的最终状态,这是我最喜欢使用的命令序列-最终与您绘制的头发完全不同:

  1. git checkout master(如果需要),然后git revert HEAD~2..HEAD可获得:

    A--B--C--D--E'--F'--RF'--RE'   <-- master (HEAD)
    

    请注意,具有后退范围的git revert的提交顺序相反。

  2. git checkout -b feature

    A--B--C--D--E'--F'--RF'--RE'  <-- master, feature (HEAD)
    
  3. git cherry-pick HEAD~4..HEAD~2,以再次复制E--F

    A--B--C--D--E'--F'--RF'--RE'       <-- master
                              \
                               E"--F"  <-- feature (HEAD)
    

如果有帮助(使用更长的提交链,则可能),可以将临时标签添加到各种提交中。例如,如果您以:

开头
A--B--C--D--E'--F'   <-- master

并运行:

git tag T1 HEAD~2; git tag T2 HEAD

您得到:

        T1     T2
         |      |
         v      v
A--B--C--D--E'--F'   <-- master

因此,现在您可以在任何地方使用T1..T2来表示“提交E'F',以便还原命令变为:

git revert T1..T2

然后樱桃签变成:

git cherry-pick T1..T2

完成后,您可以删除两个临时标签:

git tag -d T1 T2

,因为它们只是在记住两个特定提交的哈希ID,这些哈希ID界定了“有趣”提交的范围。相对名称(HEAD~2..HEADmaster~2..master)会在您添加更多提交并更改名称时更改其编号。

答案 1 :(得分:0)

我会

  1. 将还原提交添加到master
git checkout master
git revert HEAD~2..HEAD
git push
  1. 重新创建feature分支
git checkout -b feature
  1. 选择樱桃feature
git cherry-pick HEAD~4..HEAD~2
git push

答案 2 :(得分:0)

你可以做

# make sure you're working from master
git checkout master

# revert commits E and F
# (but in reverse chronological order is better to avoid unnecessary conflicts)
git revert F E

此时您的树看起来像

A---B---C---D---E---F---F'---E'        [master]

# then create your new branch
git checkout -b feature

# and here you might as well revert the reverts
git revert E' F'

最终获得

A---B---C---D---E---F---F'---E'        [master]
                              \
                               E''---F''   [feature]

但是我建议在第一次还原时使用EF-n进行分组(然后您必须随后进行提交),在下一次还原时会更容易还原还原的阶段,历史记录将更具可读性。像这样:

git checkout master
git revert -n F E
# (at this point, if you had to resolve conflicts, don't forget to add them)
git commit
git checkout -b feature
git revert E'

和最后一棵树:

A---B---C---D---E---F---E'        [master]
                         \
                          E''     [feature]

(其中最后一个模式E'E F的还原)

只有在对整体情况感到满意的情况下,才进行所有操作。