Восстановление 'старых фиксаций' с нескольких перебаз мерзавцев

Я знаю об этом вопросе, но не к верному, как отобразить его на мою текущую ситуацию. (Переоснова страшна, отменение переосновы дважды страшно!)

Я начал с несколькими различными ответвлениями функции моего ведущего устройства:

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?

5
задан Community 23 May 2017 в 11:43
поделиться

3 ответа

Это мое понимание ответа, основанное на комментариях:

Когда вы выполняете перебазирование, коммиты в вашей текущей ветке отменяются ', затем' повторно ', но на самом деле они не отменяются, они' запоминаются '* и повторно применяются с новыми идентификаторами, поэтому, например, если я посмотрю в 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 ).

5
ответ дан 14 December 2019 в 08:45
поделиться

Если все остальное не помогло, вы можете перезапустить с главного сервера, и git cherry-pick все B или C обязуется воссоздать эти ветки. Я надеюсь, что кто-то уже написал сценарий, если это единственное решение ...

1
ответ дан 14 December 2019 в 08:45
поделиться

вы можете использовать git rebase --onto AC , чтобы перебазировать все от 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 )

1
ответ дан 14 December 2019 в 08:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: