Как сделать backport (rebase / cherry-pick) уже слитой веткой
В нашем Git-процессе "мастер" является веткой интеграции веток тем и исправлений для текущего цикла выпуска, но мы также поддерживаем "стабильный» ветвь, в которой мы должны тщательно зарегистрировать некоторые из наших исправлений, уже успешно протестированных на master.
Вся сложность в том, что ветка уже слита обратно в "мастер" (иначе это легко сделать с rebase --onto)
Мы нене хочу изменить процесс в другую сторону, потому что а) мы нене хочу все исправить в "стабильный» ветка, и б) нам иногда приходится вносить некоторые изменения встабильный» филиал, который мы нене хочу сливаться в "мастер".Ясно, что мы не можем объединить исправление сстабильный» ветвь, потому что это будет бэкпорт многих нежелательных функций.График исходной ситуации, которую я описываю:
I--J (stable)
/
/
/
- A - B - C - D - E - F - G (master)
\ /
X -- Y (fix/123)
График ситуации, которую мы хотим достичь:
I--J (stable)
/ \
/ X'- Y' (fix/123-stable)
/
- A - B - C - D - E - F - G (master)
\ /
X -- Y (fix/123)
Возможны более сложные случаи, такие как множественное слияние для завершения исправления:
- A - B - C - D - E - F - G - H (master)
\ / /
X - Y ----- Z (fix/123)
Но мы неt разрешить объединение в ветку исправления, поэтому у нас никогда не будет ничего подобного:
- A - B - C - D - E - F - G (master)
\ \ /
X - Y - Z (fix/123)
Чтобы достичь этого, мы можем выбрать или исправить ветку fix:
1) вишня (обычноКак мне перенести коммит в git?):
git checkout -b fix/123-stable stable
git cherry-pick X Y
Это кажется легким, но это не так, когда мы имеем дело с примерами из реальной жизни; всегда есть риск забыть некоторые коммиты или выбрать неправильные!
2) rebase --onto (https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html):
2.а)не работает" путь :
git rebase --onto stable master fix/123
Это ничего не делает, так как fix / 123 уже объединен с master! 2.b)не намного лучше, чем вишня " путь :
git rebase --onto stable D fix/123
Это все еще довольно рискованно, потому что вам нужно взять SHA D (а не X, например).
2.c)использовать временный стартовый реф путь :
git tag begin D
git rebase --onto stable begin fix/123
git tag -d begin
Это улучшит предыдущую ситуацию, так как тег облегчает это делать или изображает его в графическом инструменте, но это все еще большая ручная работа.
3.d)сбросить хард мастер перед слиянием (к первой точке ветвления) Хум, кажется, трудно описать и сделать.
Итак, что я ищу, это мерзавецпортативный (без bash / grep / cut / sed подразумевается) способ либо;
1) перечислить все коммиты, сделанные на уже слитой ветви "мастер" (здесь X и Y, а также Z вмульти-слиты» случай) легко их подбирать
2) получить коммит первой точки ветвления ветки, уже слитой обратно в "мастер"
2.a) это не может быть сделаноGit Merge-Base " команда, потому что слияние уже сделано (даже несколько раз)
2.б) Ямы нашли здесьНайти точку ветвления с помощью Git? следующую команду bash я немного подправил:
git rev-list --boundary --date-order --reverse fix/123..master | grep -m 1 - | cut -c2-
но это не простая и не переносимая команда (т.е. не работает без инструментов Bash или Cygwin)