簡體   English   中英

Git 使用 rebase 重寫歷史記錄

[英]Git rewriting history with rebase

我目前正在一個看起來像這樣的分支上工作

--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)

請注意,現有提交無法更改,因此給出:

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

你將不可避免地從 rebase 中得到的是:

            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-γ>

之后,您需要從要pick的提交列表中刪除諸如αA之類的提交,因為這些提交當前都在feature_branchmaster ,通過合並提交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^將標識提交C並且master^2將標識提交D ,因此您可以使用它這兩個文字哈希 ID 中的一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM