Git ребаз из одного родительского коммита поверх нового родительского коммита (у которого старый родительский коммит не является одним из его родителей) - PullRequest
1 голос
/ 31 января 2020

РЕДАКТИРОВАТЬ: Мы используем Геррит. Локальные изменения передаются в Gerrit, где они проверяются в go, а затем объединяются (Gerrit) с удаленной главной ветвью.

Несколько раз я сталкивался с указанным c проблема rebase, которая превышает мое ограниченное понимание того, как Git функционирует. Представьте себе следующий сценарий (пока все это происходит, никакие другие действия не выполняются на origin/master):

Вы создаете новый коммит A, который основан непосредственно на том, что в данный момент находится на origin/master. Еще до того, как A было даже объединено с origin/master, вы уже создали новый коммит B, который основан непосредственно на коммите A.

Теперь, когда коммит A находится на рассмотрении, он решил, что коммит A должен быть разбит на два отдельных коммита. Таким образом, вы создаете новый коммит A0, который основан непосредственно на origin/master, и перемещаете часть изменений в A во вновь созданный A0. Теперь A0 объединен, став новым origin/master. Затем исходный A (который теперь стал тоньше, поскольку в нем больше нет материала, который был перемещен в A0), перебазируется поверх A0 (то есть поверх origin/master) и затем объединяется в origin/master , Пока все хорошо.

Далее (чтобы подготовиться к объединению B в origin/master) вы пытаетесь перебазировать B поверх origin/master. И здесь все идет ужасно неправильно (во всяком случае, для меня).

Когда я выполняю шаги (в Git bash), я обычно делаю, чтобы отменить изменение:

  • git fetch --prune
  • git rebase origin / master

Git жалуется, что существует один конфликт, который необходимо разрешить вручную. В моем случае это файл changelog.txt. В исходной истории B этот файл changelog.txt содержал одну объединенную запись журнала изменений для ранее объединенных изменений A0 и A. В новом родительском элементе B перебазируется поверх этой объединенной записи в журнале изменений, теперь она разделена на 2 отдельные записи в журнале изменений, и, очевидно, это не то, что Git может разрешить автоматически.

I Я в порядке с этим. Решить это самому не должно быть особенно сложно, поэтому я запускаю свой графический инструмент слияния. ОДНАКО, хотя инструмент слияния позволяет мне выбирать между старой объединенной записью журнала изменений на одной стороне и новыми отдельными записями журнала изменений на другой стороне, я замечаю, что новая запись журнала изменений, предоставленная самой B, полностью отсутствует (независимо от того, какой выбор я делаю) !! Я не понимаю, почему Git забывает об этой части. Что я делаю не так?

1 Ответ

1 голос
/ 31 января 2020

Проблема в том, что B стоит поверх оригинального A .... вы можете сделать это:

git rebase --onto origin/master B~1 B

Таким образом, вы перемещаете только единственную ревизию, связанную с B, и ничего не получено из A. Если существует более одной ревизии, связанной с B, просто отрегулируйте количество ревизий в аргументе от второго до последнего (3 ревизии? B ~ 3).

...