其實,你所擁有的,重訂後是這樣的(我會拼他們B'
等,而不是B*
等,因爲這似乎是寫這些的更常見的方式):
Z - A - B - C <-- master
\
A'- B'- C'- D'- E' <-- new-branch
這是因爲必須複製複製每個舊提交(或更確切地說,複製大部分,除了已更改的位)以更改其中的任何內容,並且在修改提交A
以生成A'
之後,它必須複製和修改B
,因爲新B'
是不同的:B'
有A'
作爲它的父母,rath呃比A
。 (一切都是一樣的,但是改變父母需要做一個全新的提交,幸運的是提交非常小,他們只有父母,時間戳等等提交信息,並且一個SHA-1與「樹」關聯提交,和git可以重新使用舊樹。)
如果你想保持A'
現在和的方式有它出現在歷史master
,你必須重新點master
標籤在提交C'
。這將「拋棄」提交C
(這裏的ASCII藝術現在令人不安擁擠:-)):
Z - A - B - C [abandoned]
\ .---------- master
A'- B'- C'- D'- E' <-- new-branch
這也意味着,誰比誰此前見過你「發佈」(或「做廣告「)您的master
意味着無論SHA-1提交C
了什麼,都會看到您有」改寫歷史記錄「:提交C
已不在畫面中,也不是B
也不是A
。相反,現在master
點C'
,指向B'
,指向A'
,這點回Z
。
當然,對於new-branch
也是如此:它用於指向E
,但現在它指向E'
。
在另一方面,也許你並不真的想改變master
。在這種情況下,您只有兩種選擇:完全放棄A'
,或者在提交Z
後有master
和new-branch
分歧。
讓我們一起看看每個小組(除了最後一個選項,很簡單:什麼也不做,這就是你現在擁有的!)。
要重新點master
,有兩個簡單的(ISH)方法:
坐上分支,然後用git reset
,這(在大多數操作模式)將改變提交到分支點:
git checkout master
git reset --hard new-branch~2 # point master to commit C'
(像往常一樣與git reset --hard
,在運行之前非常小心,你是在樹枝上要重新設置,一。d都沒有在樹枝上未保存在工作樹數據)
雖然不,使用git branch -f
強行將其移動:
git branch -f master new-branch~2 # point master to commit C'
如果你不't想要移動master
並確實想放棄A'
並恢復舊的new-branch
,有很多方法。假設你在現在和自底墊沒有做任何事情,特別REF-名ORIG_HEAD
將指向原始提交E
。換句話說,我們可以得出這樣的原始底墊後情況更完整的畫面:
D - E <-- ORIG_HEAD (copied from new-branch before rebase)
/
Z - A - B - C <-- master
\
A'- B'- C'- D'- E' <-- new-branch
所以:
如果你在new-branch
想取消,你做rebase,git reset --hard ORIG_HEAD
將會訣竅。 (照常使用--hard
。)
如果它爲太晚了,你可以找到提交您的reflogs E
,並git reset --hard
到原SHA-1,或者使用引用日誌的拼寫類似[email protected]{yesterday}
或[email protected]{3}
或什麼的。
如果你不介意複製D'
和E'
又-新副本,D''
和E''
,您可以使用--onto
(這是我看到的是Magnus Bäck's answer底墊更長的形式,也得到了重新變基new-branch
在此之前)。
的引用日誌將保留提交C
了一段時間,所以回購將保留,直到引用日誌項過期提交。所以這完全不是放棄,或至少,還沒有。
這個ORIG_HEAD
「特殊」參考是在您開始新的rebase時設置的,也可以是git merge
之類的參數。如果您不確定,您可以使用git log ORIG_HEAD
或類似的字詞來查看它實際指向的位置。
感謝您的詳細解答,我終於'git reset --hard new-branch〜2' – olanod