Я знаю об этом вопросе, но не к верному, как отобразить его на мою текущую ситуацию. (Переоснова страшна, отменение переосновы дважды страшно!)
Я начал с несколькими различными ответвлениями функции моего ведущего устройства:
master x-x-x-x-x-x-x-x-x-x
\ \ \
FeatureA 1-2-3 \ \
FeatureB A-B \
FeatureC X-Y-Z
Я хотел объединить их всех вместе и проверить, что они работали прежде, чем объединиться назад на вершину ведущего устройства, таким образом, я сделал a:
git checkout FeatureB
git rebase FeatureA
git mergetool //etc
git rebase --continue
Затем
git checkout FeatureC
git rebase FeatureB
git mergetool //hack hack
git rebase --continue
Который оставляет меня с
master x-x-x-x-x-x-x-x-x-x
\
FeatureA 1-2-3
\
FeatureB A'-B'
\
FeatureC X'-Y'-Z'
Затем я исправил некоторые биты, которые не скомпилировали правильно и получили целый набор функций к приемлемому состоянию:
master x-x-x-x-x-x-x-x-x-x
\
FeatureA 1-2-3
\
FeatureB A'-B'
\
FeatureC X'-Y'-Z'-W
Моя проблема состоит в том, что мои коллеги говорят мне, что мы не готовы к FeatureA.
Есть ли какой-либо способ для меня сохранить всю мою работу, но также и вернуться к ситуации, где я могу просто повторно основывать FeatureC на Функции B?
Это мое понимание ответа, основанное на комментариях:
Когда вы выполняете перебазирование, коммиты в вашей текущей ветке отменяются ', затем' повторно ', но на самом деле они не отменяются, они' запоминаются '* и повторно применяются с новыми идентификаторами, поэтому, например, если я посмотрю в git reflog show FeatureB
, я кое-что получу вот так:
7832f89 FeatureB@{0} rebase finished: refs/heads/FeatureB onto f4df3
efd3fed FeatureB@{1} commit: B
f3f3d43 FeatureB@{2} commit: A
2f32fed FeatureB@{3} branch: Created from HEAD
Итак, как сказал @Jefromi, оригиналы все еще там (SHA коммитов A и B в reflog не такие же, как те, что в git log, которые соответствуют A 'и B').
Точно так же git reflog show FeatureC
выглядит так
32873ef FeatureC@{0} commit: W
17dafb3 FeatureC@{1} rebase finished: refs/heads/FeatureC onto 89289fe
893eb78 FeatureC@{2} commit: Z
a78b873 FeatureC@{3} commit: Y
e78b873 FeatureC@{4} commit: X
378cbe3 FeatureC@{5} branch: Created from HEAD
Опять же, исходные коммиты Z, Y и X все еще там
Итак, решение моей проблемы - создать новую ветку Отключите BC
от HEAD мастера (например), затем выберите коммиты FeatureB {2 & 1}, а затем FeatureC {4, 3, 2} и (возможно) W:
git checkout master
git checkout -b FeaturesBC
git cherry-pick f3f3d43
git cherry-pick efd3fed
//etc...
(Кажется, это сработало, мне пришлось переделать некоторые из тех же слияний, но это было не так уж плохо)
Править, от Джефроми:
Сбор вишни, возможно, не понадобился. Вы также можете просто воссоздать ветки, в которых ветки были до перебазирования:
git branch FeatureB-old efd3fed
git branch FeatureC-old 893eb78
Или, если вы хотите отбросить перебазированную позицию FeatureB и FeatureC, вернувшись туда, где они были раньше:
git branch -f FeatureB efd3fed
git branch -f FeatureC 893eb78
Наконец, обратите внимание, что если вы как и вы, можете использовать другие обозначения, представленные в журналах рефлогов - например, FeatureC @ {2}
вместо 893eb78
. Это означает «вторая предыдущая позиция FeatureC».Однако будьте осторожны, используйте это только сразу после просмотра журнала ссылок, потому что, как только вы снова обновите ветку (переместите ее, зафиксируйте ее ...), FeatureC @ {2}
будет ссылаться на 17dafb3 вместо.
Как @Jefromi прокомментировал мой вопрос:
Вам, вероятно, следовало создать новую ветку на основе master или featureC (например, featuresABC) и объединить каждую из них, оставив ветки функций нетронутыми. Хорошо сохранять независимую историю различных ветвей функций.
* Если быть точным, старые объекты фиксации просто остаются в репозитории. В конечном итоге они будут обрезаны, поскольку вы не хотите, чтобы репо был заполнен старыми болтающимися коммитами; это произойдет при первом запуске git gc
и сделке коммитов не менее двух недель (настроено с помощью gc.pruneExpire
).
Если все остальное не помогло, вы можете перезапустить с главного сервера, и git cherry-pick
все B или C обязуется воссоздать эти ветки. Я надеюсь, что кто-то уже написал сценарий, если это единственное решение ...
вы можете использовать git rebase --onto
, чтобы перебазировать все от C до A на точку на хозяине. он оставит вас с:
master x-x-x-x-x-x-x-x-x-x
\ \
FeatureA 1-2-3 \
\
FeatureB A'-B'
\
FeatureC X'-Y'-Z'-W
, чтобы найти точку, в которую вы хотите выполнить перебазировку, вы можете использовать комбинацию git reflog и git merge-base
- но вы также можете переустановить базу слияния A, чтобы иметь историю, подобную следующей:
master x-x-x-x-x-x-x-x-x-x
|\
FeatureA | 1-2-3
\
FeatureB A'-B'
\
FeatureC X'-Y'-Z'-W
( git rebase --onto $ (git merge-base A master) AC
)