У меня есть следующий макет хранилища:
- мастер филиал (производство)
- интеграция
- за работой
Чего я хочу добиться - это выбрать диапазон коммитов из рабочей ветви и объединить их с интеграцией. Я довольно новичок в git и не могу понять, как именно это сделать (выбор диапазонов коммитов за одну операцию, а не слияние), не испортив репозиторий. Любые указатели или мысли по этому поводу? Спасибо!
git
git-merge
git-cherry-pick
crazybyte
источник
источник
Ответы:
Когда дело доходит до ряда коммитов, сбор вишни
являетсябыло не практично.Как упомянуто ниже по Киту Киму , Гит 1.7.2+ появилась возможность производить выбор диапазона коммитов (но вы все равно должны быть осведомлены о результате вишневого выбора для будущего слияния )
Дамиан комментирует и предупреждает нас:
Если вы хотите , чтобы выбрать диапазон
B
черезD
(включительно) , что будетB^..D
.См. « Git create ветка из диапазона предыдущих коммитов? » В качестве иллюстрации.
Как Джубобс упоминает в комментариях :
Примечание: начиная с Git 2.9.x / 2.10 (3 квартал 2016 года), вы можете выбрать диапазон коммитов непосредственно для сиротской ветви (пустой заголовок): см. « Как сделать существующую ветку сиротой в git ».
Оригинальный ответ (январь 2010 г.)
Было
rebase --onto
бы лучше, если бы вы воспроизводили заданный диапазон коммитов поверх ветки интеграции, как здесь описал Чарльз Бэйли .(также посмотрите «Вот как вы могли бы перенести ветку темы на основе одной ветки в другую» на странице справки git rebase , чтобы увидеть практический пример
git rebase --onto
)Если ваша текущая ветвь является интеграцией:
Это будет воспроизводить все между:
first_SHA-1_of_working_branch_range
(отсюда и~1
): первый коммит, который вы хотите воспроизвестиintegration
" (указывает на последний коммит, который вы хотите воспроизвести, изworking
ветви)на "
tmp
" (который указывает на то, кудаintegration
указывал раньше)Если при воспроизведении одного из этих коммитов возникает конфликт:
git rebase --continue
".git rebase --skip
"git rebase --abort
" (и вернитеintegration
ветку наtmp
ветку)После этого
rebase --onto
,integration
будет обратно на последнюю фиксацию интеграционного ветви (то есть «tmp
» филиал + все записи составляют фиксации)При сборке вишни или
rebase --onto
не забывайте, что это имеет последствия при последующих слияниях, как описано здесь .Здесь обсуждается чистое «
cherry-pick
» решение , которое включает в себя что-то вроде:Но в любом случае, когда вам нужно «воспроизвести» ряд коммитов, слово «воспроизведение» должно подтолкнуть вас к использованию «
rebase
» функции Git.источник
-m
опция, как вы справляетесь с этими коммитами? Или есть способ отфильтровать эти коммиты?-m
должен обработать их для вас, выбрав основную линию, на которую ссылается-m
параметр, который вы выбрали для этого выбора вишни.-m
опцию, только когда он попадает в родительский коммит, когда диапазон коммитов вишневого выбора? Прямо сейчас, если я пройду,-m
какgit cherry-pick a87afaaf..asfa789 -m 1
это относится ко всем коммитам в пределах диапазона.error: Commit 8fcaf3b61823c14674c841ea88c6067dfda3af48 is a merge but no -m option was given.
я на самом деле понял , что вы могли бы просто ,git cherry-pick --continue
и это было бы хорошо (но это не будет включать родительские фиксации)Начиная с git v1.7.2 cherry pick может принимать различные коммиты:
источник
cherry-pick A..B
коммит А не получится (вам это понадобитсяA~1..B
), и если возникнут какие-либо конфликты, git не будет автоматически продолжаться, как ребаз (по крайней мере, с 1.7.3.1)git cherry-pick A..B C
это не работает так, как вы ожидаете, наивно. Он не будет выбирать все в диапазонеA..B
и совершатьC
! Для этого нужно сначала разбить на две строки,git cherry-pick A..B
а затемgit cherry-pick C
. Поэтому, когда у вас есть диапазон, вам нужно выполнить его отдельно.Предположим, что у вас есть 2 ветви,
«branchA»: включает коммиты, которые вы хотите скопировать (от «commitA» до «commitB»
"branchB": ветвь, в которую вы хотите передать коммиты из "branchA"
1)
2) получить идентификаторы "commitA" и "commitB"
3)
4)
5) Если у вас есть конфликт, решите его и введите
продолжить процесс выбора вишни.
источник
Вы уверены, что не хотите объединять ветви? Если у рабочей ветки есть некоторые недавние коммиты, которые вам не нужны, вы можете просто создать новую ветку с HEAD в нужной точке.
Теперь, если вы действительно хотите по-разному выбрать диапазон коммитов, по любой причине, элегантный способ сделать это - просто извлечь набор патчей и применить его к вашей новой ветви интеграции:
Это в основном то, что делает git-rebase, но без необходимости играть в игры. Вы можете добавить
--3way
к ,git-am
если вам необходимо объединить. Убедитесь, что в каталоге, где вы делаете это, нет других файлов * .patch, если вы будете дословно следовать инструкциям ...источник
A^
включитьA
.Я обернул код VonC в короткий скрипт bash
git-multi-cherry-pick
, для простоты запуска:В настоящее время я использую это, когда перестраиваю историю проекта, в котором сторонний код и настройки были смешаны в одной и той же стволе SVN. Теперь я разделю основной сторонний код, сторонние модули и настройки на свои собственные ветки git, чтобы лучше понять настройки в будущем.
git-cherry-pick
полезно в этой ситуации, так как у меня есть два дерева в одном хранилище, но без общего предка.источник
Все вышеперечисленные параметры предложат вам разрешить конфликты слияния. Если вы объединяете изменения, зафиксированные для команды, трудно разрешить конфликты объединения от разработчиков и продолжить. Однако «git merge» выполнит слияние за один выстрел, но вы не можете передать диапазон ревизий в качестве аргумента. мы должны использовать команды "git diff" и "git apply", чтобы сделать диапазон оборотов слияния. Я заметил, что «git apply» завершится ошибкой, если в файле патча есть diff для слишком большого количества файлов, поэтому мы должны создать патч для каждого файла, а затем применить. Обратите внимание, что скрипт не сможет удалить файлы, которые были удалены в исходной ветке. Это редкий случай, вы можете вручную удалить такие файлы из целевой ветки. Состояние выхода «git apply» не равно нулю, если он не может применить патч,
Ниже приведен сценарий.
источник
Я проверил это несколько дней назад после прочтения очень четкого объяснения Вонка.
Мои шаги
Начните
dev
: ABCDEFGHIJtarget
: ABCDE
ниH
Шаги для копирования функций без шага E и H в ветке
dev_feature_wo_E_H
git checkout dev
git checkout -b dev_feature_wo_E_H
git rebase --interactive --rebase-merges --no-ff D
где я ставлюdrop
передE
иH
в редакторе ребазcommit
Шаги для копирования ветви
dev_feature_wo_E_H
на цель.git checkout target
git merge --no-ff --no-commit dev_feature_wo_E_H
commit
Некоторые замечания
cherry-pick
в предыдущие дниgit cherry-pick
мощный и простой, ноmerge
мне нужно разрешить конфликты начальных коммитов и дублирующих коммитов, так что для одного или двухcherry-pick
, это нормально для «выбора вишни», но для большего это слишком многословно, и ветвь станет слишком сложнойgit rebase --onto
источник
Другим вариантом может быть слияние со стратегией нашей до фиксации перед диапазоном, а затем «нормальное» слияние с последней фиксацией этого диапазона (или ветвью, когда она является последней). Итак, предположим, что только 2345 и 3456 коммитов мастера будут объединены в ветку Feature:
в тематической ветке:
источник