yse
@yse

Странное поведение git при слиянии

Приблизительная история разработки была следующая (уточню, разрабатывал не я — я только помогал «мёрджить»)

Человек работал в своей ветке, назовём её feature, отклонированной от master ещё при царе горохе. В какой-то момент он взял обновления из master посредством merge. Затем продолжил работу в своей ветке. Через некоторое непродолжительное время разработка фичи закончилась, и человек решил влить изменения в master. Вливать решил одним коммитом, т.е. с ключиком --squash. Естественно, возникли конфликты. Так вот, возник и ряд проблем:
  • Появились конфликты в файлах, которые даже не правились в ветке feature (за исключение коммита, порождённого merge`м). И вроде как это смущает разработчика ветки feature. Неужели git не учитывает предыдущие merge?
  • Ладно, те файлы, в которых не ковырялся разработчик в своей ветке feature, решили взять полностью из версии master (т.е. командой git checkout --ours -- some_files, находясь в master`e). И вот что самое странное, после этой команды c файлами ничего не происходит. Почему так?

Гуру git`a придите на помощь. Я понимаю, что я чего-то не понимаю, объясните, пожалуйста.
  • Вопрос задан
  • 2843 просмотра
Пригласить эксперта
Ответы на вопрос 3
sam002
@sam002
Линуксойд, кодер, немного физик.
Наверное, как обычно, пустые строку, пробелы и табы поизменялись.
Ответ написан
Комментировать
AgentSIB
@AgentSIB
Если вы хотите сделать одним коммитом, почему бы не слить ветку feature и master с параметром --no-commit? После проверки и решения конфликтов, делаете коммит в мастере и заливаете на сервер, а ветку feature удаляете (насколько я понял, история в ней не важна).
Ответ написан
Комментировать
Lobotomist
@Lobotomist
Software Developer
Наверное, уже не актуально, но так как вопрос в тостере есть и кто-то на него может наткнуться - думаю мой ответ не будет лишним.

Не могу точно сказать, как сделать так, чтобы git учитывал факт вливания master в feature. Но конкретно эту проблему можно было бы решить с помощью rebase.

Обозначим тегами следующие коммиты:
beforeMerge1M - коммит в ветке master непосредственно перед коммитом первого merge.
beforeMerge1F - коммит в ветке future непосредственно перед коммитом первого merge.

Сначала нужно заменить первый merge на rebase.
Для этого перебазируем последовательность коммитов с начала ветки future до вливания в нее мастера на тот коммит мастера, который предшествует вливанию:
git checkout beforeMerge1F
git branch tmpFeature
git rebase beforeMerge1M


Таким образом, в голове ветке tmpFeature будет как раз то же состояние, что и в результате первого слияния.

Теперь перебазируем остальную часть ветки на этот коммит:
git checkout feature
git rebase tmpFeature


Теперь состояние ветки feature осталось таким же как и было, но история изменилась - в ней нет коммита слияния и ответвляется от мастера она после коммита beforeMerge1M.

Можно делать слияние в master, которое планировалось, но, возможно, имеет смысл ее еще раз перебазировать на мастер, чтобы в процессе этого разрешить возникающие конфликты, если они будут и потом без рпоблем сделать merge.
git rebase master
git checkout master
git merge feature --squash


ps. Всё это умозрительные рассуждения и где-то я мог ошибиться, пишите мне в таком случае, помогу разобраться.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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