На самом деле, то, что у вас есть пост-Rebase это (я по буквам их B'
и т.д., а не B*
и т.д., так что, как представляется, более обычным способом написания этих):
Z - A - B - C <-- master
\
A'- B'- C'- D'- E' <-- new-branch
Это потому что rebase должен скопировать каждый старый фиксатор (или, точнее, скопировать большую часть его, за исключением измененных битов), чтобы изменить что-либо в нем, а после изменения фиксации A
сделать A'
, он должен скопировать и изменить B
, потому что новый B'
отличается: B'
имеет A'
в качестве своего родителя, rath чем A
. (Все остальное одно и то же, но изменение родителя требует создания целого нового коммита. К счастью, коммиты довольно крошечные: у них просто есть родители, временные метки и т. Д., Сообщение commit и один SHA-1 для «дерева», связанного с фиксации и мерзавец может повторно использовать старое дерево.)
Если вы хотите сохранить A'
так, как это в настоящее время и он появится в истории для master
, вам придется заново точку в master
этикетка при фиксации C'
.Это будет «отказаться от» совершить C
(и ASCII искусство здесь теперь неуютно переполненный :-)):
Z - A - B - C [abandoned]
\ .---------- master
A'- B'- C'- D'- E' <-- new-branch
Это также означает, что кто-то, кто раньше видел, как вы «опубликовать» (или «рекламу "), что ваш master
имел в виду, что у SHA-1 есть C
, у вас будет« перезаписанная история »: commit C
больше не отображается, а не B
или A
. Вместо этого теперь master
указывает на C'
, что указывает на B'
, что указывает на A'
, что указывает на Z
.
Конечно, то же самое верно для new-branch
: вместо этого он указывал на E
, но теперь он указывает на E'
.
С другой стороны, возможно, вы действительно не хотите менять master
. В этом случае у вас есть только два варианта: полностью отказаться от A'
или с master
и new-branch
расходиться после совершения Z
.
Давайте перейдем к каждой группе (за исключением последней опции, это легко: ничего не делайте, вот что у вас есть!).
Для повторной точки master
, есть два простых (МОГ) пути:
Получить на ветке, а затем использовать git reset
, которые (в большинстве своих рабочих режимах) будет меняться фиксации, к которой точки ветвления:
git checkout master
git reset --hard new-branch~2 # point master to commit C'
(Как всегда с git reset --hard
, быть очень осторожным, прежде чем запустить его, что вы на ветке вы хотите повторно установлен, то . D уже не ООН сохраняемых в-работа-дерева данных)
While не на ветке, используйте git branch -f
принудительно переместить его:
git branch -f master new-branch~2 # point master to commit C'
Если вы дон Не хотите переместить master
и хотите отказаться от A'
и восстановить старый new-branch
, есть несколько способов. Предполагая, что вы сейчас на нем и ничего не сделали с момента переустановки, специальное ref-name 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
, как обычно.)
Если это слишком поздно для этого, вы можете найти совершить E
в ваших reflogs и git reset --hard
к сырому SHA-1, или с помощью reflog орфографии как [email protected]{yesterday}
или [email protected]{3}
или любых других.
Если вы не против копирования D'
и E'
пока-новая-копия, D''
и E''
, вы можете повторно перебазироваться new-branch
с более длинной формой перебазироваться с использованием --onto
(который я вижу в Magnus Bäck's answer, который получил до этого).
reflog сохранит фиксации C
на некоторое время, так что репо будет сохранять фиксации, пока запись reflog не истечет. Так что это не полностью заброшено или, по крайней мере, еще нет.
Это ORIG_HEAD
«специальный» ссылка устанавливается при запуске нового перебазироваться, но и такие вещи, как git merge
. Вы можете использовать git log ORIG_HEAD
или аналогично, чтобы увидеть, где он на самом деле указывает, если вы не уверены.
спасибо за подробный ответ, я, наконец, сделал 'git reset --hard new-branch ~ 2' – olanod