Как чередовать несколько коммитов

У меня две ветки. Commit a является главой одного, а другой имеет b, c, d, e и f поверх a. Я хочу переместить c, d, e и f в первую ветвь без commit b. Использование вишневого подбора легко: checkout первая ветка вишни выберите один за другим c до f и сначала переформатируйте вторую ветвь. Но есть ли какой-либо способ вишни - выбрать все c - f в одной команде?

Вот визуальное описание сценария (спасибо JJD):

enter image description here

Ответ 1

Git 1.7.2 введена способность черви совершать ряд коммитов. Из примечания к выпуску:

Git cherry-pick "научился выбирать диапазон коммитов (например," вишня-выбор A..B "и" cherry-pick -stdin "), так же" gitrevert ", они не поддерживают более хороший контроль последовательности" rebase [-i] ", однако.


Включая важные комментарии (кредиты соответствующим авторам)

Примечание 1: В форме "вишневый выбор A..B" A должен быть старше B. Если это неправильный порядок, команда будет терпеть неудачу. - damian

Примечание 2: Кроме того, это не будет использовать вишневый выбор A, а скорее все после A вплоть до B. - J. B. Rainsberger

Примечание 3: Чтобы включить только тип git вишневый выбор A ^.. B - sschaef

Ответ 2

Самый простой способ сделать это - с опцией onto на rebase. Предположим, что ветвь, конец которой заканчивается на a, называется mybranch, и это ветка, которую вы хотите переместить c - f на.

# checkout mybranch
git checkout mybranch

# reset it to f (currently includes a)
git reset --hard f

# rebase every commit after b and transplant it onto a
git rebase --onto a b

Ответ 3

Или запрошенный однострочный:

git rebase --onto a b f

Ответ 4

Вы можете использовать последовательную комбинацию git rebase и git branch чтобы применить группу коммитов к другой ветке. Как уже сообщал wolfc, первая команда фактически копирует коммиты. Тем не менее, изменение не будет видно, пока вы не добавите имя ветки в самый верхний коммит группы.

Пожалуйста, откройте картинку в новой вкладке...

Workflow

Чтобы суммировать команды в текстовом виде:

  1. Откройте gitk как самостоятельный процесс с помощью команды: gitk --all &.
  2. Запустите git rebase --onto abf.
  3. Нажмите F5 в Gitk. Ничего не меняется Но HEAD не отмечена.
  4. Запустите git branch selection
  5. Нажмите F5 в Gitk. Появляется новая ветка с ее коммитами.

Это должно прояснить вещи:

  • Фиксировать является новым корневым целевой группой. a
  • Commit b - это коммит до первого коммита группы (исключая).
  • Commit f - последний коммит группы (включительно).

После этого вы можете использовать git checkout feature && git reset --hard b чтобы удалить коммиты c до f из ветки feature.

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

Ответ 5

Чтобы применить комментарии Дж. Б. Рэйнсбергера и sschaef, чтобы конкретно ответить на вопрос... Использовать диапазон вишни в этом примере:

git checkout a
git cherry-pick b..f

или

git checkout a
git cherry-pick c^..f

Ответ 6

git rev-list --reverse b..f | xargs -n 1 git cherry-pick

Ответ 7

Если у вас есть выборочные ревизии для объединения, скажем, A, C, F, J из коммитов A, B, C, D, E, F, G, H, I, J, просто используйте следующую команду:

мерзкая вишня ACFJ

Ответ 8

git format-patch --full-index --binary --stdout range... | git am -3

Ответ 9

На самом деле, самый простой способ сделать это может быть:

  1. запишите базу слияния между двумя ветвями: MERGE_BASE=$(git merge-base branch-a branch-b)
  2. перемотка вперед или перебазирование старой ветки на новую.
  3. перебазировать полученную ветвь на себя, начиная с базы слияния с шага 1, и вручную удалить коммиты, которые не нужны:

    git rebase ${SAVED_MERGE_BASE} -i
    

    В качестве альтернативы, если есть только несколько новых коммитов, пропустите шаг 1 и просто используйте

    git rebase HEAD^^^^^^^ -i
    

    на первом шаге, используя достаточно ^ чтобы пройти мимо базы слияния.

Вы увидите нечто подобное в интерактивной перебазе:

pick 3139276 commit a
pick c1b421d commit b
pick 7204ee5 commit c
pick 6ae9419 commit d
pick 0152077 commit e
pick 2656623 commit f

Затем удалите строки b (и любые другие, которые вы хотите)

Ответ 10

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

https://gist.github.com/nickboldt/99ac1dc4eb4c9ff003a1effef2eb2d81

Чтобы выбрать вишню из вашей ветки к мастеру (в качестве источника используется текущая ветка):

./gcpl.sh -m

Чтобы выбрать последние 5 коммитов из вашей ветки 6.19.x, выполните следующие действия:

./gcpl.sh -c 5 -s 6.19.x -t master

Ответ 11

Чтобы выбрать вишню от идентификатора коммита до кончика ветки, вы можете использовать:

git cherry-pick commit_id^..branch_name