2017-10-11 38 views

回答

2

I如果你想添加提交,但是使它對源代碼沒有任何影響,那麼是的,你確實需要一個不同於交互式底圖的路徑。

沒有什麼專門爲此設計的,但它是相對容易git replace做到:

  1. 退房承諾A(作爲一個分離的頭,或在一個新的分支,但新的分支將很快無用):git checkout <hash-of-A>
  2. 作出承諾X(但你希望它出現)。
  3. 運行git replace --graft <hash-of-B> HEAD

你現在有這個實際歷史:

X--B' <-- refs/replace/<hash-of-B> 
/
A--B--C <-- whatever-branch-this-is 

什麼特別的這些「替代」的對象是,每當Git是關於與做幾乎任何事情幾乎任何對象,包括「使用提交的任何目的「,例如,Git會查看是否存在帶對象哈希ID的refs/replace/名稱。由於替代B,所以Git現在將替代爲B'。因此,git log和其他Git命令將充當雖然歷史是:

A--X--B'--C 

注意,但是,真正的歷史是仍然存在於這個倉庫。當且僅當refs/replace/名稱在存儲庫中 - 當然這是這個存儲庫 - 和替換被啓用(其是默認情況下),使用替代歷史。但是,如果您在別處克隆或推送此存儲庫,則取或推過程通常不會傳輸任何名稱;因此該存儲庫的克隆將切換回舊的歷史記錄。 (您也可以通過禁用替換來查看原始歷史記錄,例如使用git --no-replace-objects log ...)。

如果您願意,現在可以運行git filter-branch,它僅僅複製提交。默認情況下,git filter-branch服從替換規則。這意味着當它複製分支上的提交時,它將以A開頭,然後複製X,然後複製B',然後複製C指向B'A,XB'的副本將與原件完全相同,因此實際上會重新使用原件;但C的副本會略有不同:它將使用B'作爲其真正的家長,而不是作爲替代嫁接的家長。所以提交C將被複制到新的提交C',並且分支名稱(無論它是什麼)將被指向新副本。

此過濾分支有實際(不只是移植)的歷史,穿越回過B'XA,所以現在如果你克隆過濾庫,在克隆看到的歷史將同樣從C'開始,然後其通過B'XA

相關問題