Интерактивный ребаз при коммите после ветвления

У меня есть следующий (упрощенный) сценарий в моем репозитории git:

A-B-C-F
     \
      D-E

Коммит F - это исправление для C, и он должен стать единым коммитом. Я попробовал интерактивную ребазу в "основной" ветке, используя git rebase -i HEAD~2, но это приводит к следующему:

A-B-CF
   \
    C-D-E

тогда как я хочу, чтобы это было так:

A-B-CF
      \
       D-E

Кто-нибудь знает, как этого добиться? Я еще ничего не толкнул.

2 ответа

Решение

Я собираюсь добавить некоторые детали здесь для ясности.

A-B-C-F    (master)
     \
      D-E  (featureA)

Я приписываю названия веток этим, потому что это сбивает с толку, когда речь идет о перебазировании. Имена не имеют значения, я предполагаю, что когда вы говорили "основной", вы имели в виду верхний ряд, который я назвал мастером.

Ваша проблема на самом деле довольно сложная, потому что вы уже "поделились" C совершить с другой веткой. Теперь вы хотите изменить этот коммит - это означает, что вам нужно изменить историю всей ветви featureA.

Справедливое предупреждение. Если вы опубликовали эти ветки, включая либо C, F, D, или же E, с любыми другими разработчиками, они будут иметь серьезные проблемы после того, как вы перебазируете.

git checkout master
git rebase -i HEAD~2

Как вы знаете, тогда вам просто нужно исправить или раздавить последний коммит в предыдущий. Теперь у вас действительно будет это (при условии, что символ "CF" представляет объединенные коммиты C и F).

A-B-CF   (master)
   \
    C-D-E  (featureA)

Это произошло потому что C больше не в master, но это в featureA, Самый последний общий предок двух ветвей B, Теперь вам нужно получить C наша история featureA, Как следствие, все SHA1 фиксирует после C также изменится.

Теперь вам нужно оформить заказ и перебазировать мастер.

git checkout featureA
git rebase -i master

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

A-B-CF   (master)
     \
      D-E  (featureA)

Примечание

Если вы не удалите это C совершите должным образом во время перебазирования, вы получите следующее.

A-B-CF   (master)
     \
      C-D-E  (featureA)

Вот чем я закончил. Начальный сценарий:

A-B-C-F (develop)
     \
      D-E (feature)

Интерактивный ребаз по разработке с git checkout develop; git rebase -i HEAD~2, раздавив F в C:

A-B-CF (develop)
   \
    C-D-E (feature)

Интерактивный ребаз на функцию с git checkout feature; git rebase -i HEAD~3, удалив C:

A-B-CF (develop)
   \
    D-E (feature)

И наконец нормальный ребаз на ветке git rebase CF-hash, перемещая начало ветки:

A-B-CF (develop)
      \
       D-E (feature)

Не уверен, что это лучший способ, но, похоже, он мне подходит.

Другие вопросы по тегам