从Git中的单个分支中删除提交

And*_*rew 27 git branch

我有两个分支,master和feature1.当我意识到我需要处理其他不相关的东西时,我正在研究feature1.不幸的是,我忘了从master分支,而是从feature1创建了我的feature2分支.现在我想将feature2合并到master中,但不能,因为该分支中有feature1的部分内容.

如何从feature2分支中删除feature1提交?是否涉及变基?

我觉得如果我可以将feature2的起始参考点更改为master的位置,那可能有所帮助,但不知道如何.

编辑:

谢谢你的答案!我根据@ Mark的解决方案尝试了变基础,但意识到历史比我原先想象的要复杂得多.功能2已合并到其他功能分支中,并且master已在一个点合并到feature2中.master上还有其他与feature2无关的提交.一切仍然是本地的.

真的,我的历史更像是这样的:

A - B - C - D - - - - - - - - - - - - - L - M  master  
            |                          
            |               - I - J - K  feature2                  
            \              /           \
             - E - F - G - H - - - - - -N - O - P  feature1
Run Code Online (Sandbox Code Playgroud)

我想要的是这个:

A - B - C - D - - - - - - - - - -  L - M  master
            |\                          
            |  - - - - - I - J - K  feature2                  
            \                     \
              - E - F - G - H - - - N - O - P  feature1
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

git rebase --onto 1524b824cfce5856a49e feature1 feature2
// 1524b824cfce5856a49e == D
Run Code Online (Sandbox Code Playgroud)

但这只是将分支名称功能2设置为1524,并将I,J,K与其原始父项一起提交.

Mar*_*air 29

如果只是你在你的feature2分支上工作并且你还没有与其他人分享,那么在合并之前重新定义该分支是没关系的.您可以执行以下操作,例如:

git checkout feature2
git rebase --onto master feature1 feature2
Run Code Online (Sandbox Code Playgroud)

...它将重写你的feature2分支,留下它以便它包含所有提交,feature2因为它是分支的feature1,但重新应用到master.我建议您之后使用gitk --all或类似的git历史记录查看器来检查此操作的结果是否是您想要的.

顺便提一下,这正是用于--ontogit rebase文档中解释的场景- 请参阅段落开头:

以下是如何使用rebase --onto将基于一个分支的主题分支移植到另一个分支,假装您从后一个分支分叉主题分支.[...]


针对问题中的更多材料进行了更新:

从您的历史开始,如下所示:

A - B - C - D - - - - - - - - - - - - - L - M  master  
            |                          
            |               - I - J - K  feature2                  
            \              /           \
             - E - F - G - H - - - - - -N - O - P  feature1
Run Code Online (Sandbox Code Playgroud)

您可以通过执行以下操作获得所需内容:

git checkout feature2
git rebase --onto D H feature2
Run Code Online (Sandbox Code Playgroud)

这将为您留下如下历史记录:

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' J' K' feature2       I - J - K                    
            \                           /           \
             - - - - - - - E - F - G - H - - - - - -N - O - P  feature1
Run Code Online (Sandbox Code Playgroud)

创建要在合并之前feature1,您应该记下的SHA1SUM OP.(我假设N只是一个正常的合并,而不是"邪恶合并".)

然后执行硬重置以将feature1移回H:

git checkout feature1
git rest --hard H
Run Code Online (Sandbox Code Playgroud)

那你应该有历史:

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' J' K' feature2
            \
             - - - - - - - E - F - G - H feature1
Run Code Online (Sandbox Code Playgroud)

现在你显然想合并K'feature1:

git merge K'

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' - J' - - - - - - - K' feature2
            \                             \
             - - - - - - - E - F - G - H - Z feature1
Run Code Online (Sandbox Code Playgroud)

最后,你可以樱桃采摘老OPfeature1用:

git cherry-pick O
git cherry-pick P
Run Code Online (Sandbox Code Playgroud)

... 离开:

A - B - C - D - - - - - - - - - - - - - - - - - - - L - M  master  
            |\
            | \ - I' - J' - - - - - - - K' feature2
            \                            \
             - - - - - - - E - F - G - H - Z - - O' - P' feature1
Run Code Online (Sandbox Code Playgroud)