Github: выборка и перебазирование форка на разветвленном мастере
Я создал форк проекта и добавил ~40 коммитов в наш master
, В какой-то момент я бездумно переписал историю с принудительным толчком, потому что я не мог толкать "без всякой причины", а иногда вы просто хотите увидеть, как мир горит.
Сейчас все хорошо, но последние ~100 фиксируются на upstream
которые также находятся в моем репо, больше не считаются одинаковыми: я вижу "240 коммитов вперед" вместо "40 коммитов вперед".
Можно ли извлечь вышестоящий мастер и повторно зафиксировать на нем коммиты нашего мастера и принудительно вернуть его нашему мастеру так, чтобы наши и их синхронизировались для всех предыдущих коммитов, кроме моего? Если так, то как? Пожалуйста, будьте конкретны.
1 ответ
Я полагаю, у вас есть чистая песочница, где origin
указывает на ваш форк, и у вас есть доступ к репозиторию восходящего направления по другому URL. Я также предполагаю origin/master
а также master
в вашей песочнице синхронизируются.
С этими допущениями это должно работать:
git remote add upstream <upstream_url>
git fetch upstream
git checkout master
git rebase upstream/master
Надеемся, что ребаз будет работать и не будет вводить повторяющиеся коммиты. Если этого не произойдет, это может даже подчеркнуть, почему вы должны были принудительно толкать в первую очередь.
Прежде чем начать ребаз, git log --graph --decorate --all
(или же gitk -all
или любая другая визуальная замена журнала Git, которая показывает полный график) может показать вам, почему у вас возникли проблемы.
РЕДАКТИРОВАТЬ: альтернативный и более консервативный подход заключается в использовании git cherry-pick
, Решение rebase опирается на то, что Git признает, что история, которая должна быть общей, состоит из коммитов, уже присутствующих на upstream/master
, Но вместо перебазировки вы можете определить родителя 1-го коммита, который вы хотите сохранить, скажем, origin/master~40
если у вас действительно есть 40 фиксированных коммитов, и добавьте их в конце upstream/master
:
git remote add upstream <upstream_url>
git fetch upstream
git checkout master
git reset --hard upstream/master
git cherry-pick origin/master~40..origin/master
Это дает вам новый master
который явно начинается в upstream/master
и добавляет только новую историю, которую вы хотите.
Обратите внимание --hard
в git reset --hard upstream/master
: как указано OP в комментариях, это необходимо, чтобы убедиться, что вы начинаете с чистого состояния перед сбором вишни. Но сначала убедитесь, что у вас не было ничего незафиксированного, что вы хотели сохранить.
Проверка работоспособности: после вишни (или перебазировки), git diff master origin/master
ничего не должен возвращать или снова указывать на другие проблемы, с которыми вам нужно справиться. КОНЕЦ РЕДАКТИРОВАНИЯ
После того, как перебазирование или выбор вишни будет завершен, и вы полностью убедите себя в том, что вы хотите сохранить эту новую историю:
git push -f origin master
следует вернуть вилку к тому, чтобы всего 40 коммитов впереди upstream
,
Предостережение: я не тестировал решение для rebase, но я вполне уверен, что оно должно работать, основываясь на вашем описании ситуации. Однако я с успехом использовал решение "вишневый пик" в подобных ситуациях. Если вы попробуете любой из этих методов, пожалуйста, сообщите о своем успехе или что-то не так, что потребует корректировки.