如何撤消git rebase并重做为git merge [英] How do I undo a git rebase and redo as a git merge

查看:83
本文介绍了如何撤消git rebase并重做为git merge的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在分支上运行了git rebase并修复了所有冲突,然后意识到对于这个特定的分支,我需要运行git merge来保留历史记录.有没有一种方法可以撤消"变基,但是在运行git merge时会自动重新应用我的修复程序?

I ran a git rebase on a branch and fixed all the conflicts, then realised for this particular branch I need to run git merge instead, to keep the history. Is there a way to "undo" the rebase but automatically reapply my fixes when running the git merge?

推荐答案

As Amber said in a comment, if you turned on rerere, git will have "re"corded your previous "re"solution (two of the three re's). Then if you reset things to pre-rebase state and "git merge" it should "re"use them (the last "re").

但如果没有,就不会.

那该怎么办?假设您对分辨率非常有信心:-)可以尝试一下.

What to do then? Assuming you're quite confident of your resolution :-) you could try this.

ORIG_HEAD 可能仍指向原始提交链(重新设置基准).如果不是,请在引用日志中找到旧的分支提示.给它加上标签(分支或标签名称),同时在重新定位后的链上保留标签.也就是说,我们要复活旧的分支尖端,并保留新的分支尖端.(一旦理解了其余内容,为什么就应该很明显.)

The original chain of commits (pre-rebase) is likely still pointed-to by ORIG_HEAD. If not, find the old branch-tip in the reflogs. Give it a label (branch or tag name), while also keeping a label on the post-rebase chain. That is, we want to resurrect the old branch tip, and also keep the new branch tip. (Exactly why should be obvious once you understand the rest of this.)

我假设在修改基准时,您完全提交了 C F 并完全放弃了 D E 不再需要.并不是说这真的很重要. F'是唯一关键的提交.关键是提交 F'捕获了工作树的最终的,完全解析的"版本:

I'll assume that in rebasing you modified commits C and F and dropped D and E entirely as no-longer needed. Not that this is really matters. F' is the only crucial commit. The point is that commit F' captures the "final, all-resolved" version of the work-tree:

        C - D - E - F   <-- feature_orig
      /
A - B - G - H - I - J   <-- mainline
                      \
                        C' - F'  <-- feature

上面是执行 git branch feature_orig ORIG_HEAD (或从reflog中恢复原始提示并使用它创建 feature_orig )后看到的内容.

The above is what you can see after you do git branch feature_orig ORIG_HEAD (or recover the original tip from reflogs and use that to create feature_orig).

您现在想要的(根据原始问题)是一个合并:将要素合并到主线中"或将主线合并到特征中".除此以外,您希望它在 feature_orig 上/与之一起发生,而不是重新基于其特征的 feature .

What you want now (per the original question) is a merge: either "merge feature into mainline" or "merge mainline into feature". Except, you want it to happen on/with feature_orig, rather than the rebased feature.

不过,还有一个问题:您想保留 features 分支吗?(如果您在此处将 mainline 合并到 feature 中,则可能会这样做.如果将功能合并到mainline中,则可能不会.但是最多,我怀疑您会希望保留 feature_orig ,而不是重新设置的行.)现在让我们再移动一个分支名称,以便(希望如此)使画面更清晰:

One other question though: do you want to keep the feature branch around? (If you're merging mainline into feature here, you probably do. If merging feature into mainline, maybe not. But at most, I suspect you will want to keep feature_orig, not the rebased line.) Let's move one more branch name around now, to—I hope—make the picture clearer:

$ git branch -m feature feature_rebased

现在我们有了这个

        C - D - E - F   <-- feature_orig
      /
A - B - G - H - I - J   <-- mainline
                      \
                        C' - F'  <-- feature_rebased

现在进行合并.进入要在其中显示合并提交的分支:

Now for the merge. Get onto the branch you want the merge commit to show up in:

$ git checkout ...

(我不知道这是哪个分支, feature_orig mainline !)

(I don't know which branch this is, feature_orig or mainline!)

然后进行合并,忽略结果而不提交:

Then do a merge, ignoring the result and not committing:

$ git merge --no-commit ...

(您要合并的分支).

现在只需将每个文件替换为提交 F'中的版本(请注意,我假设您位于此处的顶级工作目录中):

Now just replace every single file with the version taken from commit F' (note, I'm assuming you're in your top level work directory here):

$ git rm -rf .; git checkout feature_rebased -- .

rm 步骤完全清空了索引,包括所有冲突以及工作树.然后 checkout 步骤使用提交 F'中的所有内容(通过分支名称 feature_rebased 获得)完全重新填充索引和工作树.

The rm step completely empties out the index, including all conflicts, and also the work tree. Then the checkout step completely repopulates the index and work-tree using whatever is in commit F' (as obtained through the branch name feature_rebased).

您现在可以在所处的任何分支上提交合并.具体来说,假设您使用的是 feature_orig ,并要求git合并 mainline . git commit 之后,您应该将其作为提交图:

You may now commit the merge, on whichever branch you're on. For concreteness let's say you're on feature_orig and asked git to merge mainline. After you git commit you should have this as your commit graph:

        C - D - E - F - M  <-- feature_orig
      /               /
A - B - G - H - I - J   <-- mainline
                      \
                        C' - F'  <-- feature_rebased

我认为在这里值得一提的是,这只是提交图.的内容(当您进行 git checkout 任何这些提交时在工作目录中获取的文件)由索引/暂存区的内容确定在创建提交时.

I think it's worth mentioning here that this is just the commit graph. The contents of the tree—the files you get in your work-dir when you git checkout any of these commits—is determined by the contents of the index/staging-area at the time the commit was created.

这是为什么,我们可以 git rm 一切,然后 git checkout id -.合并提交的内容.提交合并时,我们要做的就是创建一个提交 M ,其父代为 F J ,其内容为无论现在在哪里索引".

That's why we can git rm everything and then git checkout id -- . to set up the contents of the merge commit. All we do when we commit the merge is create a commit M whose parents are F and J, and whose contents are "whatever is now in the index".

(由父代 F J order 以及新提交ID写入哪个分支名称,取决于当我们开始和完成 git merge 过程时,我们在哪个分支上.如果我们在分支 feature_orig 上,则 F 是第一个父级, M 位于分支 feature_orig 上.如果我们位于分支 mainline 上,则 J 是第一个父级和 M 进入分支 mainline "上,当然,准备好的提交文本(可以在提交发生之前进行编辑)也有些不同,但是您可以编辑该内容以阅读您喜欢的任何内容.)

(The order of the parents F and J, and to which branch-name the new commit ID is written, is determined by which branch we are on when we start and finish the git merge process. If we are "on branch feature_orig then F is the first parent and M goes "on branch feature_orig". If we are "on branch mainline, then J is the first parent and M goes "on branch mainline". Also, of course, the prepared commit text, that you can edit before the commit happens, is a bit different. But you can edit that to read whatever you like.)

在这一点上(甚至可能更早),如果您想保留名称,现在可以将 feature_orig 重命名为 feature .您也可以删除分支 feature_rebased ,因为不再需要保存提交 C' F'.实际上,我们只想挂在 F'上,以便我们可以 git checkout 它的树-一旦完成结帐.

At this point (or maybe even earlier) you can now rename feature_orig to feature, if you want to keep the name. You can also delete branch feature_rebased as there's no need to save commits C' and F' any more. In fact, we only really wanted to hang on to F' so that we could git checkout its tree—we could have deleted the branch as soon as we finished that checkout.

这篇关于如何撤消git rebase并重做为git merge的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆