[英]git: Reset previous commits with parent branch
Suppose I've a parent
branch in my repository and I make another branch named derived
from it. 假设我在存储库中有一个
parent
分支,并创建了另一个derived
自该分支的分支。
git checkout -b derived
Now the derived
branch contains all the commits of my parent
branch. 现在,
derived
分支包含parent
分支的所有提交。 I add two more commits (commit D1 and D2) to my derived
branch. 我向
derived
分支添加了另外两个提交(提交D1和D2)。 My derived
branch is two commits ahead of parent
branch. 我的
derived
分支是parent
分支之前的两个提交。
Now I amend some previous commits in the parent branch and add new commit "Pn". 现在,我在父分支中修改了一些先前的提交,并添加了新的提交“ Pn”。 After this, for some reason I want my derived branch to exactly look like this
之后,由于某种原因,我希望派生分支完全像这样
Amended commits from parent branch ---> Pn ---> D1 ----> D2
I tried git rebase parent
from my derived
branch but it is giving a lot of merge conflicts. 我从
derived
分支尝试了git rebase parent
,但是它给了很多合并冲突。 Is there any easier way to just reset all the commits before D1 and D2 exactly as the parent
branch. 有没有更简单的方法可以将D1和D2之前的所有提交完全重置
parent
分支。
You do want to use git rebase
, you just want it to stop at the point where you used to share commits with the other branch. 您确实想使用
git rebase
,只是希望它停止在您以前与另一个分支共享提交的位置。
That is, you had: 也就是说,您有:
...--Pl--Pm--Pn <-- parent
\
D1--D2 <-- derived
Since both amending and git rebase
work by copying commits, what you have now is: 由于修订和
git rebase
都通过复制提交来工作,因此您现在拥有的是:
Pn'--Po--Pp <-- parent
/
---Pl--Pm--Pn <-- parent@{some-number}
\
D1--D2 <-- derived
where the memory that parent
used to contain original commit Pn
is in the reflog for parent
(and probably in the reflog for HEAD
). 其中,所述存储器
parent
用于包含原始提交Pn
是在引用日志为parent
(和可能是在引用日志为HEAD
)。
You can manually specify that git rebase
should stop at Pn
by using: 您可以使用以下方式手动指定
git rebase
应该在Pn
停止:
git rebase --onto parent <hash-of-Pn>
(ie, specify the stopping point for the <upstream>
as a commit hash, and use --onto
to make the copies go after the new tip of parent
). (即,将
<upstream>
的停止点指定为提交哈希,并使用--onto
使副本位于新的parent
后面)。 You can also use commit-relative syntax ( derived~ number
) as in jpaugh's answer to identify Pn
. 您还可以使用提交相对语法(
derived~ number
)在jpaugh的答案 ,以确定Pn
。 See the gitrevisions documentation for details. 有关详细信息,请参见gitrevisions文档 。
Git also now has --fork-point
. Git现在也有
--fork-point
。 Using --fork-point
, you can have Git automatically root around through the reflog for parent
to attempt to locate Pn
. 使用
--fork-point
,您可以让git 自动从reflog到根目录,让parent
尝试定位Pn
。 Here you would run: 在这里,您将运行:
git rebase --fork-point parent
which tells Git to do this rooting-around, and rebase onto parent
but drop commit Pn
. 它告诉Git进行这种生根处理,并以
parent
但放弃 commit Pn
。
Exactly when and whether --fork-point
works is a bit tricky since reflog entries expire (after 30 or 90 days by default). --fork-point
确切时间和是否--fork-point
有点棘手,因为reflog条目会过期(默认为30天或90天)。
Not as such. 不是这样的。 The commits D1 and D2 rely on every commit before them, including the ones you don't want.
提交D1和D2依赖于它们之前的每个提交,包括不需要的提交。 But, here are things you can try:
但是,您可以尝试以下操作:
git rebase --onto parent derived~3 derived
Rebase derived onto the new parent. 重新派生到新的父级上。 This sets the merge base explicitly to
derived~3
, the commit that was the HEAD of parent when you created the derived branch. 这明确地设置合并基础来
derived~3
,提交,这是家长的头,当你创建的衍生分支。 This will reduce the conflicts, and will avoid reintroducing the old changes. 这将减少冲突,并避免重新引入旧的更改。
Normally, git figures this out automatically, but since you've amended these commits, git can't tell that any relationship exists between them — it can't tell that commit A'
is an amended variant of commit A
. 通常情况下,git的数字了这一点自动,但由于你已经修改这些提交,Git不能告诉它们之间存在任何关系-它不能告诉提交
A'
是提交的修订变种A
。
Cherry pick D1 and D2 onto a new branch 樱桃选择D1和D2到新分支
git branch derived-new parent git checkout derived-new git cherry-pick D1 D2 git branch -m derived derived-old # Save the old branch until you're ready to delete it git branch -m derived-new derived
Do an interactive rebase of the derived branch, removing the earlier commits that you don't want, and then seeing what happens. 对派生的分支进行交互式变基,删除不需要的早期提交,然后查看会发生什么。 This may also generate a lot of extra conflicts, and force you to
git rebase --abort
, but if it doesn't, you're scott free... Just rebase onto the new parent again, as above 这可能还会产生很多额外的冲突,并迫使您
git rebase --abort
,但是如果不这样做,那么您就可以自由了……只需重新建立新的父级,如上所述
You should be able to follow these steps: 您应该能够按照以下步骤操作:
parent
branch parent
git checkout parent
parent
branch parent
分支创建并签出新分支
git checkout -b derived-modified
git cherry-pick
with derived-modified
checked out to move the new commits from derived
to derived-modified
(this will use the modified parent branch with the commits you have modified/added) git cherry-pick
带有签出derived-modified
签出,将新提交从derived
移动到derived-modified
(这将对您修改/添加的提交使用修改后的父分支)
git cherry-pick 000aaaa
git cherry-pick 000bbbb
git cherry-pick 000cccc
This will take, for example, the 3 commits you've made to derived
and move them to derived-modified
, which contains the modified parent
branch. 例如,这将花费您对
derived
的3次提交,并将它们移到derived-modified
,其中包含已修改的parent
分支。 Once you've verified the commits are on derived-modified
, you can delete derived
and rename derived-modified
. 一旦确认提交是在
derived-modified
,就可以删除derived
,并重命名derived-modified
。
More information on git cherry-pick
is available here . 有关
git cherry-pick
更多信息,请参见此处 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.