Как выбрать несколько коммитов
У меня есть две ветви. совершить a
является главой одного, в то время как другой имеет b
, c
, d
, e
а также f
на вершине a
, Я хочу переехать c
, d
, e
а также f
на первую ветку без коммита b
, С помощью вишневого кирки это легко: оформить первую ветку вишневого кирка по одному c
в f
и перебазировать вторую ветку на первую. Но есть ли способ черри все c
-f
в одной команде?
Вот визуальное описание сценария (спасибо JJD):
17 ответов
В Git 1.7.2 появилась возможность черпать ряд коммитов. Из примечаний к выпуску:
git cherry-pick "научился выбирать диапазон коммитов (например,"cherry-pick A..B"и"cherry-pick --stdin"), поэтому сделал"git revert"; они не поддерживают более приятный контроль последовательности" но "rebase [-i]" имеет.
Включая важные комментарии (благодарности соответствующим авторам)
Примечание 1: В форме "cherry-pick A..B" A должно быть старше, чем B. Если они в неправильном порядке, команда молча завершится ошибкой. - Дамиан
Примечание 2: Кроме того, это будет не вишня А, а скорее все после А до B. Включая Б. - Д.Б. Рейнсбергер
Примечание 3: Для включения просто наберите git cherry-pick A^..B - sschaef
Если у вас есть выборочные ревизии для объединения, скажем, A, C, F, J из коммитов A,B,C,D,E,F,G,H,I,J, просто используйте команду ниже:
мерзкая вишня A C F J
Самый простой способ сделать это с 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
Как выбрать одну фиксацию, несколько коммитов или диапазон коммитов
1. выбрать одну ветку или зафиксировать с именем
git cherry-pick commit
Примеры:
git cherry-pick my_branch # by branch name
git cherry-pick 1e038f108a130831f108329b1083a8139813fabc # by full hash
git cherry-pick 1e038f10 # by partial hash
2. выбрать несколько коммитов
Обратите внимание, что вы можете выбрать любое количество хэшей фиксации одновременно и в любом порядке. Они будут просто применяться по очереди и в указанном вами порядке. Если возникнут какие-либо конфликты, вам придется разрешать их по очереди, а затем использовать
git add my_file
тогда
git cherry-pick --continue
когда закончите, чтобы продолжить процесс выбора вишни.
git cherry-pick commit1 commit2 commit3 commit4 commit5
3. выбрать диапазон коммитов
Изначально я изучил основы этого стиля из ответа @Eric Darchis, получившего наибольшее количество голосов.
Обратите внимание, что для выбора диапазона коммитов вы должны указать начальный и конечный хеш фиксации с помощью
..
между ними. Однако в ряд коммитов начальная фиксация НЕ включается. Следовательно, чтобы включить его, вы должны указать фиксацию перед началом фиксации. Синтаксис для указания предыдущей фиксации:
~
,
~1
, или
^
сразу после вашего коммита, как в:
beginning_commit~
, что означает: "фиксация прямо перед
beginning_commit
".
# A. INCLUDING the beginning_commit
git cherry-pick beginning_commit~..ending_commit
# OR (same as above)
git cherry-pick beginning_commit~1..ending_commit
# OR (same as above)
git cherry-pick beginning_commit^..ending_commit
# B. NOT including the beginning_commit
git cherry-pick beginning_commit..ending_commit
Примечание:
commit~
,
commit~1
, а также
commit^
все означают «одна фиксация до » или иначе сказано: «фиксация до».
Чтобы указать два коммита до, вы можете использовать такой синтаксис:
commit~~
commit~2 # my preferred syntax
commit^^
Чтобы указать три коммита до
commit
, ты можешь сделать это:
commit~~~
commit~3 # my preferred syntax
commit^^^
Это не работает:
commit^3 # INVALID syntax
Чтобы самостоятельно проверить приведенные выше концепции "синтаксиса предыдущей фиксации", проще всего использовать
git log
команда. Бывший:
git log commit
git log commit~
git log commit~1
git log commit^
git log commit~~
git log commit~5
# etc.
Вы можете использовать последовательную комбинацию git rebase
а также git branch
применить группу коммитов к другой ветке. Как уже сообщал wolfc, первая команда фактически копирует коммиты. Однако это изменение не будет отображаться до тех пор, пока вы не добавите имя ветви в самый верхний коммит группы.
Пожалуйста, откройте картинку в новой вкладке...
Чтобы суммировать команды в текстовом виде:
- Откройте gitk как самостоятельный процесс с помощью команды:
gitk --all &
, - Бежать
git rebase --onto a b f
, - Нажмите F5 в Gitk. Ничего не меняется Но нет
HEAD
помечен. - Бежать
git branch selection
- Нажмите F5 в Gitk. Появляется новая ветка с ее коммитами.
Это должно прояснить вещи:
- совершить
a
является новым корневым назначением группы. - совершить
b
является коммитом перед первым коммитом группы (эксклюзив). - совершить
f
последний коммит группы (включительно).
После этого вы можете использовать git checkout feature && git reset --hard b
удалить коммиты c
до f
от feature
ветка.
В дополнение к этому ответу я написал сообщение в блоге, в котором описываются команды в другом сценарии, которые должны помочь в общем его использовании.
Чтобы применить комментарии JB Rainsberger и sschaef, чтобы конкретно ответить на вопрос... Чтобы использовать диапазон выбора вишни в этом примере:
git checkout a
git cherry-pick b..f
или же
git checkout a
git cherry-pick c^..f
Чтобы выбрать вишневый код от идентификатора фиксации до конца ветки, вы можете использовать:
git cherry-pick commit_id^..branch_name
Другой вариант, о котором стоит упомянуть, - если вы хотите, чтобы последний n
совершает из ветки, ~
синтаксис может быть полезен:
git cherry-pick some-branch~4..some-branch
В этом случае приведенная выше команда выберет последние 4 коммита из ветки с именем some-branch
(хотя вы также можете использовать хеш фиксации вместо имени ветки)
Выберите несколько коммитов:
Перейдите в свою ветку, где вы хотите выбрать вишневые коммиты.
Используйте эту команду: (частичным хешем)
git вишневый выбор 1e038f10 1e038f11 1e038f12 ...
git format-patch --full-index --binary --stdout range... | git am -3
На самом деле, самый простой способ сделать это может быть:
- запишите базу слияния между двумя ветвями:
MERGE_BASE=$(git merge-base branch-a branch-b)
- перемотка вперед или перебазирование старой ветви на новую.
перебазировать полученную ветвь на себя, начиная с базы слияния с шага 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 (и любые другие, которые вы хотите)
Мне нужно выбрать фиксацию из одной ветки в другую по приоритету, но коммиты здесь было трудно понять, надеюсь, ниже поможет с простым:
Порядок действий ниже:
- Получите 1 коммит с именем ("Удалить поле Фамилия") из ветки "dev"
- Закоммитить в ветке "hotfix1"
1 . Получить информацию о коммите из ветки "dev"
// Go to "dev" branch
git checkout dev
// Get the commit id (1e2e3e4e1 here)
git log --oneline
> ...
> ...
> 1e2e3e4e1 Remove Last Name field
> ...
> ...
2 . Вставьте фиксацию в ветку "hotfix1"
// Go to "hotfix1" branch
git checkout hotfix1
// Get the commit (1e2e3e4e1) from "dev" branch to "hotfix1" branch
git cherry-pick 1e2e3e4e1
// verify changes are correct
gitk
// push to "hotfix1" branch
git push
Чтобы сделать несколько сразу, только 1 изменение в приведенном выше, укажите все идентификаторы коммитов последовательно:
git cherry-pick 1e2e3e4e1 1e2e3e4e2 1e2e3e4e3
В дополнение к commit-ish вы можете передать список SHA из stdin.
git rev-list --reverse ..main -- path/ | git cherry-pick --stdin
rev-list
по сути, это команда сантехников («уродливая», но скорая родственница)
git-log
Обратите внимание , что
--reverse
нужно.
Таким образом вы можете делать более продвинутые вещи, а не просто диапазон коммитов.
Вот скрипт, который позволит вам выбрать несколько коммитов подряд, просто сообщив скрипту, какие исходные и целевые ветви для выбора вишни и количество коммитов:
https://gist.github.com/nickboldt/99ac1dc4eb4c9ff003a1effef2eb2d81
Чтобы выбрать вишню из вашей ветки к мастеру (в качестве источника используется текущая ветка):
./gcpl.sh -m
Чтобы выбрать последние 5 коммитов из вашей ветки 6.19.x, выполните следующие действия:
./gcpl.sh -c 5 -s 6.19.x -t master
В качестве альтернативы можно использовать настольное приложение GitHub ,
Вы можете выбрать несколько коммитов на вкладке истории исходной ветки, а затем щелкнуть правой кнопкой мыши, чтобы получить опцию «Cherry-Pick Selected Commits».