从 Git 中的单个分支中删除提交
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7259472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove commits from a single branch in Git
提问by Andrew
I have two branches, master and feature1. I was working on feature1 when I realized that I needed to work on something else unrelated. Unfortunately, I forgot to branch from the master, and instead created my feature2 branch from feature1. Now I want to merge feature2 into master, but cannot because there are parts of feature1 in that branch.
我有两个分支,master 和 feature1。当我意识到我需要做其他不相关的事情时,我正在研究 feature1。不幸的是,我忘记从 master 分支,而是从 feature1 创建了我的 feature2 分支。现在我想将 feature2 合并到 master 中,但不能,因为该分支中有 feature1 的一部分。
How do I remove the feature1 commits from the feature2 branch? Does it involve rebasing?
如何从 feature2 分支中删除 feature1 提交?是否涉及变基?
I feel that if I could change the starting reference point of feature2 to be where master is, that might help, but have no idea how.
我觉得如果我可以将 feature2 的起始参考点更改为 master 所在的位置,那可能会有所帮助,但不知道如何。
EDIT:
编辑:
Thank you for the answers! I tried rebasing according to @Mark's solution, but realized that the history is more complicated than I originally thought. feature 2 has been merged into other feature branches, and master was merged into feature2 at one point. There are also additional commits on master that are not related to feature2 Everything is still local.
谢谢你的回答!我尝试根据@Mark 的解决方案重新定位,但意识到历史比我原先想象的要复杂。feature 2 已经合并到其他 feature 分支,master 一度合并到 feature2。master 上还有其他与 feature2 无关的提交,一切仍然是本地的。
Really, my history is more like this:
真的,我的历史更像是这样:
A - B - C - D - - - - - - - - - - - - - L - M master
|
| - I - J - K feature2
\ / \
- E - F - G - H - - - - - -N - O - P feature1
And what I want is this:
而我想要的是:
A - B - C - D - - - - - - - - - - L - M master
|\
| - - - - - I - J - K feature2
\ \
- E - F - G - H - - - N - O - P feature1
I have also tried:
我也试过:
git rebase --onto 1524b824cfce5856a49e feature1 feature2
// 1524b824cfce5856a49e == D
But this just sets the branch name feature 2 pointing at 1524, and leaves commits I, J, K with their original parents.
但这只是将分支名称特征 2 设置为指向 1524,并将 I、J、K 提交给它们的原始父代。
回答by Mark Longair
If it's only you working on your feature2
branch and you haven't shared it with other people, it's fine to rebase that branch before merging. You could do the following, for example:
如果只有你在你的feature2
分支上工作并且你没有与其他人共享它,那么在合并之前重新设置该分支是可以的。例如,您可以执行以下操作:
git checkout feature2
git rebase --onto master feature1 feature2
... which will rewrite your feature2
branch, leaving it so that it consists of all the commits in feature2
since it was branched from feature1
, but reapplied onto master
. I suggest you use gitk --all
or a similar git history viewer afterwards to check that the result of this operation is what you want.
... 这将重写您的feature2
分支,使其包含feature2
自 分支以来的所有提交feature1
,但重新应用到master
. 我建议您之后使用gitk --all
或类似的 git 历史查看器来检查此操作的结果是否是您想要的。
Incidentally, this is exactly the scenario used to explain --onto
in the git rebase
documentation- see the paragraph beginning:
顺便说一句,这正是用来解释场景--onto
中git rebase
的文档-查看段落开头:
Here is how you would transplant a topic branch based on one branch to another, to pretend that you forked the topic branch from the latter branch, using rebase --onto. [...]
以下是将基于一个分支的主题分支移植到另一个分支的方法,假设您使用 rebase --onto 从后一个分支分叉了主题分支。[...]
Updated in response to more material in the question:
更新以回应问题中的更多材料:
Starting with your history, which looks like this:
从你的历史开始,它看起来像这样:
A - B - C - D - - - - - - - - - - - - - L - M master
|
| - I - J - K feature2
\ / \
- E - F - G - H - - - - - -N - O - P feature1
You can get what you want by doing the following:
您可以通过执行以下操作来获得您想要的:
git checkout feature2
git rebase --onto D H feature2
This will leave you with history that looks like:
这会给你留下看起来像这样的历史:
A - B - C - D - - - - - - - - - - - - - - - - - - - L - M master
|\
| \ - I' J' K' feature2 I - J - K
\ / \
- - - - - - - E - F - G - H - - - - - -N - O - P feature1
Before creating the merge that you want in feature1
, you should note down the SHA1sum of O
and P
. (I'm assuming N
is just a normal merge, and not an "evil merge".)
创建要在合并之前feature1
,您应该记下的SHA1SUMO
和P
。(我假设N
这只是一个正常的合并,而不是一个“邪恶的合并”。)
Then do a hard reset to move feature1 back to H
:
然后进行硬重置以将 feature1 移回H
:
git checkout feature1
git rest --hard H
Then you should have the history:
那么你应该有历史:
A - B - C - D - - - - - - - - - - - - - - - - - - - L - M master
|\
| \ - I' J' K' feature2
\
- - - - - - - E - F - G - H feature1
Now you apparently want to merge K'
into feature1
:
现在你显然想合并K'
到feature1
:
git merge K'
A - B - C - D - - - - - - - - - - - - - - - - - - - L - M master
|\
| \ - I' - J' - - - - - - - K' feature2
\ \
- - - - - - - E - F - G - H - Z feature1
And finally you can cherry-pick the old O
and P
onto feature1
with:
最后,你可以樱桃采摘老O
和P
在feature1
用:
git cherry-pick O
git cherry-pick P
... to leave:
... 离开:
A - B - C - D - - - - - - - - - - - - - - - - - - - L - M master
|\
| \ - I' - J' - - - - - - - K' feature2
\ \
- - - - - - - E - F - G - H - Z - - O' - P' feature1
回答by Andy
If you don't mind that feature2is merged back in on P
instead of M
, here is a relatively simple solution.
如果您不介意将feature2合并回 onP
而不是 M
,这里有一个相对简单的解决方案。
- RebaseI-J-K onto D, look at the section title "more interesting rebases
- Rebase O-P onto H. same way as done in step 1
- Finally merge feature2 into feature1with
git merge feature2
while having feature1checked out.
- RebaseIJK to D,看章节标题“更有趣的rebases
- 以与步骤 1 中相同的方式将OP 重新设置为 H。
- 最后将 feature2 合并到feature1 中,
git merge feature2
同时检出 feature1。
If you want K
merged into a particular commits, the rebasing gets a little trickier.
如果你想K
合并到一个特定的提交中,rebase 会变得有点棘手。