【问题标题】:Git rewriting history with rebaseGit 使用 rebase 重写历史
【发布时间】:2020-09-08 01:26:46
【问题描述】:

我目前正在开发一个看起来像这样的分支

--A------B (master)
        / \
----C--D   E--F (feature_branch, HEAD)

我一直在尽力修复它但没有成功:( git-rebase <A_SHA1> 似乎根本不起作用。目前只有两个分支:masterfeature_branch

有没有办法让它看起来像这样?

--A------B (master)
   \    / \
    C--D   E--F (feature_branch, HEAD)

【问题讨论】:

    标签: git workflow rebase


    【解决方案1】:

    请注意,现有的提交不能更改,所以给出:

    ...--α--A------B   <-- master
                  / \
     ....--γ--C--D   E--F   <-- feature_branch (HEAD)
    

    你将不可避免地从变基中得到的是:

                C'-D'  E'-F'  <-- feature_branch (HEAD)
               /    \ /
              /___---B'
             //
    ...--α--A------B   <-- master
                  / \
     ....--γ--C--D   E--F   [abandoned]
    

    然后你可以强制移动master 指向B' 而不是B,这样你就有了:

                C'-D'  E'-F'  <-- feature_branch (HEAD)
               /    \ /
              /___---B'  <-- master
             //
    ...--α--A------B
                  / \
     ....--γ--C--D   E--F   [abandoned]
    

    现在可以完全忽略BγC 等的存在,并假设C'C。请注意,除非 αγ 确实是同一个提交,否则提交 γ 已变得不可访问。

    为了实现这个使用 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-γ>
    

    之后,您将需要从提交列表中删除 αA 等提交,使其成为 pick-ed,因为这些提交目前都在 feature_branch 以及 master 上,通过合并提交B。 (请注意,-r 是 Git 2.18 中的新功能。-r 选项使用交互式机制来指示 Git 重新执行合并,这就是我们将在下面执行的操作。)

    不过,总体而言,使用单独的 git cherry-pickgit 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
    

    如果master~1 确实识别提交A,您可以使用它来代替此处的每个文字哈希,在这种情况下,master^2^ 将识别提交Cmaster^2 将识别提交D ,因此您可以使用它来代替这两个文字哈希 ID。

    【讨论】:

    • 确实不再那么“新奇”了:--rebase-merges 来自 Git 2.18 (Q2 2018),它所取代的旧选项 --preserve-merge 在 Git 2.22 中被正式弃用,2019 年第二季度。
    • 感谢您的解释 :) 我最终使用了--rebase-merges
    猜你喜欢
    • 2021-12-09
    • 2011-07-12
    • 2014-09-25
    • 2020-05-30
    • 2018-03-20
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多