Исправление запутанной истории ветвей

#git #merge

#git #слияние

Вопрос:

Всем экспертам по Git,

в настоящее время у меня возникли некоторые проблемы с объединением долгоживущей ветви функций. При этом Git отменяет многие изменения, внесенные в главную ветку за последний год. Поскольку я совсем новичок в этом проекте и все бывшие сотрудники ушли, я провел некоторое исследование о том, что пошло не так в истории Git. Вот упрощенная история нашего проекта:

          o---.....---o---...---D             (Feature-Branch)
        /           /           
---o---A---.....---B---.......---C---o       (Master-Branch) 
  

В истории проекта я вижу, что фиксация «B» объединена в функциональную ветку. Однако в этой фиксации слияния изменения из фиксации «B», похоже, отбрасываются, и вместо них вносятся некоторые другие изменения. Но реальное слияние не выполняется. Когда я пытаюсь объединить фиксацию «D» обратно в главную ветвь, Git выполняет 3-стороннее слияние с общим предком «B». Таким образом, сравнивая фиксации «C» и «D» с фиксацией «B», изменения вносятся только в фиксации «D». Git правильно использует эти изменения для результирующей фиксации слияния.

Прямо сейчас я понятия не имею, как решить этот «конфликт слияния». Насколько я знаю, невозможно заставить Git выбрать общего предка по моему выбору. Также возврат всех ошибочных коммитов слияния на самом деле не вариант, поскольку их довольно много.

У кого-нибудь есть идея, как это исправить, не выбирая все правильные изменения вручную?

Комментарии:

1. Что ж…. вы могли заставить git делать то, что вам нравится, с помощью нескольких трюков. Каким бы вы хотели видеть своего «общего предка»?

Ответ №1:

Вы можете принудительно использовать общего предка… допустим, вы хотели бы, чтобы A был принудительным общим предком. Вы можете сделать это:

 git checkout --detach D
git reset --soft A
git commit -m "new D"
git merge C
  

Этого было бы достаточно. Если вы не возражаете потерять исходную историю D, вы можете сохранить ее в таком виде (после завершения слияния). Если вы хотите сохранить исходную историю D, то вы должны сделать это (после завершения слияния)

 git commit-tree -p D -p C -m "blahblah" HEAD^{tree}
  

Это выведет идентификатор, создайте ветку, используя этот идентификатор, и там у вас будет ваша редакция слияния.