В Git, как я могу перебазировать + squa sh ветку, которая имеет несколько коммитов слияния в ее истории, не выбирая вишню на совершенно новую ветку - PullRequest
2 голосов
/ 03 августа 2020

Проблема

Я хочу иметь возможность взять ветку, изначально разветвленную от мастера, с несколькими слияниями от мастера, чтобы она отображалась как одна фиксация на мастере. Мы делаем это для того, чтобы взять ветку разработчика и создать чистую историю в мастере (после того, как он был протестирован).

Я знаю, как это сделать, создав новую ветку на кончике мастера (т.е. указатель "master") и выделение его (разрешение конфликтов по мере необходимости, но это должно быть возможно только с помощью команды rebase (не так ли?). Предполагается, что сам мастер не был перебазирован .

В качестве примера я хочу взять следующую историю, ниже с мастером ветки и каракули ветки:

Исходная история

  *  commit K, branch doodle, merge commit (conflicts)
 /|
* |  commit J, branch master, 
| |
| *  commit I, branch doodle
* |  commit H, branch master
| |
| *  commit G, branch doodle,merge commit (conflicts)
|/|
| *  commit F, branch doodle
* |  commit E, branch master
| |
| *  commit D, branch doodle,merge commit (no conflicts)
|/|
* |  commit C, branch master
| *  commit B, Branch doodle 
|/
*    commit A, Branch master

И превратите его в следующую историю на мастере, где вся цепочка коммитов на doodle сжимается и перебазируется на HEAD мастера, как показано ниже. Поскольку у главы ветви doodle есть коммит K, и все конфликты между мастером и doodle были решены, выполнение нижеприведенного должно быть таким же простым, как одна команда. Кроме того, это не влияет на историю мастера, который был опубликован.

Желаемая история

*    commit L, branch master,(squash commit B,D,F,G,I,K)
|
*    commit J, branch master
|
*    commit H, branch master
|
*    commit E, branch master
|
*    commit C, branch master
|
*    commit A, branch master

Альтернативой может быть создание истории, показанной ниже, а затем сквош фиксирует B ', F ', G' I ', J', K 'перед слиянием обратно в мастер. Однако этот подход, приведенный ниже, кажется, добавляет дополнительный шаг, который должен быть в состоянии обработать rebase (albiet с разрешением конфликтов).

Альтернативная история

| *  commit K', branch doodle (possible conflict resolution)
| |
| *  commit I', branch doodle (possible conflict resolution)
| |
| *  commit G', branch doodle (possible conflict resolution)
| |
| *  commit F', branch doodle (possible conflict resolution)
| | 
| *  commit B', branch doodle (possible conflict resolution)
|/
*    commit K, branch master
|
*    commit H, branch master
| 
*    commit E, branch master
|
*    commit C, branch master
| 
*    commit A, Branch master

То, что я пробовал

В настоящее время я создаю новую ветку от главного наконечника и выбираю на нем вишни B, F и I. Это работает, но это сложнее, чем я считаю необходимым, поскольку мне нужно повторно разрешать конфликты слияния. Теперь мне известно о флаге --rebase-merges для rebase. Однако по какой-то причине я не могу заставить --rebase-merges создать «историю желаний» или даже альтернативную историю. Скорее всего, я неправильно выбираю коммиты с rebase -i HEAD~N --rebase-merges.

Вопрос

Как легко можно go из исходной истории в желаемую историю?

Кроме того, если у мастера в исходной истории было несколько дополнительных коммитов после последнего слияния в каракули, позволит ли этот подход разрешить конфликт перед переходом в мастер?

1 Ответ

2 голосов
/ 03 августа 2020

Это легко сделать с помощью reset --soft

git checkout doodle
git reset --soft master
git commit -m "doodle, as a single commit"

Без проблем. Если в мастере есть больше коммитов, которые не являются частью doodle, то перед этим выполните слияние.

...