简体   繁体   English

git:使用父分支重置先前的提交

[英]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: 您应该能够按照以下步骤操作:

  1. Check out your parent branch 签出您的parent
    • git checkout parent
  2. Create and check out new branch based off the parent branch 根据parent分支创建并签出新分支
    • git checkout -b derived-modified
  3. Use 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM