[英]Git rewriting history with rebase
I am currently working on a branch that looks like this我目前正在一个看起来像这样的分支上工作
--A------B (master)
/ \
----C--D E--F (feature_branch, HEAD)
I've been trying my best to fix it without success :( git-rebase <A_SHA1>
doesn't seem to work at all. There are currently only two branches: master
and feature_branch
.我一直在尽力修复它但没有成功:(
git-rebase <A_SHA1>
似乎根本不起作用。目前只有两个分支: master
和feature_branch
。
Is there even a way to make it look like this?有没有办法让它看起来像这样?
--A------B (master)
\ / \
C--D E--F (feature_branch, HEAD)
Note that existing commits cannot be changed, so given:请注意,现有提交无法更改,因此给出:
...--α--A------B <-- master
/ \
....--γ--C--D E--F <-- feature_branch (HEAD)
what you'll inevitably get from a rebase is, instead:你将不可避免地从 rebase 中得到的是:
C'-D' E'-F' <-- feature_branch (HEAD)
/ \ /
/___---B'
//
...--α--A------B <-- master
/ \
....--γ--C--D E--F [abandoned]
You can then forcibly move master
to point to B'
instead of B
so that you have:然后,您可以强制移动
master
指向B'
而不是B
这样您就可以:
C'-D' E'-F' <-- feature_branch (HEAD)
/ \ /
/___---B' <-- master
//
...--α--A------B
/ \
....--γ--C--D E--F [abandoned]
It's now possible to ignore the presence of B
, γ
, C
, and so on entirely and pretend that C'
is C
, for instance.例如,现在可以完全忽略
B
、 γ
、 C
的存在并假装C'
是C
。 Note that commit γ
has become unreachable unless α
and γ
are really the same commit.请注意,除非
α
和γ
确实是同一个提交,否则提交γ
已变得无法访问。
To achieve this using git rebase
, you will want the somewhat-newfangled -r
or --rebase-merges
option:要使用
git rebase
实现这一点,您将需要有点新奇的-r
或--rebase-merges
选项:
git checkout feature_branch # if needed - you've drawn a detached HEAD
git rebase -i -r --onto master <hash-of-γ>
after which you will need to delete commits such as α
and A
from the list of commits to be pick
-ed, as these commits are all currently on feature_branch
as well as on master
, through merge commit B
.之后,您需要从要
pick
的提交列表中删除诸如α
和A
之类的提交,因为这些提交当前都在feature_branch
和master
,通过合并提交B
。 (Note that -r
was new in Git 2.18. The -r
option uses the interactive machinery to instruct Git to re-perform merges, which is what we will do below.) (请注意,
-r
是 Git 2.18 中的新选项。 -r
选项使用交互式机制来指示 Git重新执行合并,这就是我们将在下面执行的操作。)
Overall, though, it's probably easier to achieve this using separate git cherry-pick
and git merge
commands:不过,总的来说,使用单独的
git cherry-pick
和git merge
命令可能更容易实现这一点:
git checkout --detach <hash-of-A> # note: master~1 probably finds commit A
git cherry-pick <hash-of-C> # make C'
git cherry-pick <hash-of-D> # make D'
git merge --no-ff <hash-of-A> # make new merge B'
git branch -f master HEAD # forcibly update master now
git cherry-pick feature_branch~2 # make E'
git cherry-pick feature_branch~1 # make F'
git checkout -B feature_branch # forcibly move feature_branch and re-attach HEAD
If master~1
does identify commit A
, you can use that in place of each literal hash here, and in that case, master^2^
will identify commit C
and master^2
will identify commit D
, so you can use that in place of those two literal hash IDs.如果
master~1
确实标识了提交A
,您可以使用它代替此处的每个文字哈希,在这种情况下, master^2^
将标识提交C
并且master^2
将标识提交D
,因此您可以使用它这两个文字哈希 ID 中的一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.