Git rebase, пропустить слияние-коммиты

Начиная с

    hack---F1----M1----F2  (feature)
   /            /
  C1-----C2----C3  (master)

Я хотел бы закончить с

    hack---F1----M1----F2  (feature)
   /            /
  C1-----C2----C3---F1'---F2'  (master)

Пока лучшее, что у меня есть,

git checkout feature  
git checkout -b temp  
git rebase -i --onto master hack temp
   * Big drawback: manually remove the merged-in C2 and C3 from list of commits *
git checkout master  
git merge temp  
git branch -d temp  

Я надеюсь, что кто-то может ответить, хотя это непростой рабочий процесс.

Ответ 1

Простой случай

Если состояние вашего репо

  hack---F1----M1----F2 [feature]
 /            /
C1-----C2----C3 [master]

и вы хотите приехать в

  hack---F1----M1----F2 [feature]
 /            /
C1-----C2----C3----F1'----F2' [HEAD=master]

вам следует использовать git cherry-pick, а не git rebase -i (здесь не нужно манипулировать интерактивной перебазой):

git checkout master
git cherry-pick <commit-ID-of-F1> <commit-ID-of-F2>

Общий случай

Поправьте меня, если я ошибаюсь, но я понимаю, что вы подразумеваете под общим случаем как

cherry-pick, поверх master, все коммиты без слияния между hack (эксклюзивом) и кончиком feature (включительно).

Далее я предполагаю, что это действительно то, что вы имеете в виду.

Как вы справедливо заметили в своем комментарии, описанный выше подход не очень хорошо масштабируется, так как увеличивается количество коммитов на выборку вручную:

  hack---F1---F2--- .... --- F68--M1---F67---...---F99 [feature]
 /                               /
C1-------------C2---------------C3 [master]

Тем не менее, вы можете получить git rev-list для автоматической генерации списка ревизий, представляющих интерес, используя

git rev-list --reverse --no-merges --first-parent <commit-ID-of-hack>..feature

Редактировать: вам также нужен флаг --first-parent чтобы избежать сбора коммитов, таких как C1 и C2, и флаг --reverse, чтобы коммиты выбирались в выбранном порядке.

Вы можете передать вывод этой команды в git cherry-pick:

git checkout master
git cherry-pick 'git rev-list --reverse --no-merges --first-parent <commit-ID-of-hack>..feature'

который даст

  hack---F1---F2--- .... --- F68--M1---F67---...---F99 [feature]
 /                               /
C1-------------C2---------------C3---F1'---F2'---...---F99' [HEAD=master]