Я пересмотрел это на основе отредактированного вопроса.Конечно, это можно сделать, и вы можете немного упростить автоматическую сборку вишни, но вы столкнетесь со случайным камнем преткновения, где слияние будет лучше.
Сначала давайте посмотримкак автоматизировать процесс сбора вишни.В предположении, что OR
репозиторий только когда-либо добавляет коммитов - как на рисунках в обновленном вопросе - нам нужен какой-то маркер, чтобы мы знали, какой коммит является последний , который мы выбрали ранее.
Этот маркер может принимать любую форму, и есть встроенный, который может служить, в частности, reflog для самого OR/master
.Но для иллюстрации, если ничего другого - и для большей гибкости при наличии истечения срока действия рефлога или чего-либо еще, что может вызвать проблемы - мы можем использовать явное имя ветви или тега.Имя ветки является наиболее подходящим, поскольку мы будем перемещать его обычным образом, так как Git ожидает перемещения имен ветвей.
Возьмем, к примеру, этот этап:
A--B--C--G <-- OR/master
\
D--E--F--G' <-- master
(после одной вишни).Чтобы помнить, что мы специально остановились на G
, нам просто нужно установить имя ветви, чтобы указать G
:
A--B--C--G <-- marker, OR/master
\
D--E--F--G' <-- master
Когда мы доберемся до следующего обновления,не имеет значения, сколько коммитов мы добавили в наш собственный `master, так как у нас будет:
I <-- OR/master
/
A--B--C--G <-- marker
\
...
Поэтому коммиты для копирования просто marker..OR/master
, и мы можем запустить:
git checkout master # if needed
git cherry-pick marker..OR/master # copy the new commits
и когда это удастся, перемотайте наши marker
до OR/master
любым удобным для нас способом, включая довольно умный (если немного страшный):
git push . OR/master:marker
(который откажется делать что-либоесли обновление до marker
не является операцией ускоренной перемотки вперед.
Но это может пойти не так
Для иллюстрации , когда идет не так, рассмотрите, что происходитесли OR/master
получает серию коммитов, включающую слияние:
...--L
\
I--M--N <-- OR/master
/
A--B--C--G <-- marker
\
...
Теперь диапазон коммитов, marker..OR/master
, включает в себя коммит M
и его второго родителя L
и все, что идет раньшеL
это недоступно с G
.Какие коммиты должны скопировать?Мы можем буквально выбрать вишню M
, пока мы делаем это отдельно с аргументом -m
- который всегда будет -m 1
- и это может работать длятвоя ситуация.Но это проблема, и вы должны знать об этом (и знать, что вы планируете делать с этим).Если вы используете git merge
, как в моем первоначальном предложении ниже, это не проблема: все просто работает так, как должно, автоматически.
(Исходный ответ находится ниже разделительной линии.)
Все, что git rebase
делает, это копирует коммиты (как будто git cherry-pick
- иногда буквально * git cherry-pick
), затем перемещает имя ветви.
Вы всегда можете скопировать любой коммит, который у вас есть, так что да, вы можете перебазировать коммиты, которые вы получили из какого-то другого Git-репозитория.Это не поможет вам в достижении вашей настоящей цели.То, что вы должны делать, это использовать git merge
.
Посмотрите на это так: ваша вилка - просто клон, а ваш клон вашей вилки - клон вашего клона.За исключением того, что у вас всегда есть онлайн место для хранения вашего собственного клона (вашей вилки), вы по сути просто клонируете оригинальный клон.Поэтому мы можем пометить материал в вашем локальном репозитории следующим образом:
...--F--G--H <-- OR/master, origin/master, master
, где каждая заглавная буква представляет уникальный идентификатор хеша фиксации.(Мы выберемся после 26 коммитов, поэтому вы можете понять, почему фактические хэш-идентификаторы Git такие большие и уродливые - они должны быть уникальными навсегда , для каждого коммита, который каждый когда-либо делал в этих репозиториях, в прошлом илибудущее.)
Теперь, в какой-то момент, вы сделали свои собственные коммиты и подтолкнули их к origin
(свой собственный форк), так что теперь у вас есть:
...--F--G--H <-- OR/master
\
I--J <-- master, origin/master
Ваш origin/master
всегда будет соответствовать вашему master
после вас git push origin master
, поэтому нам даже не нужно беспокоиться об этом здесь.
Между тем,тем не менее, люди, которые владеют репозиторием OR, делают свои собственные коммиты, так что после git fetch OR
вы получаете:
...--F--G--H--K--L <-- OR/master
\
I--J <-- master
Вы можете копировать свои коммитыK
и L
на ваши K'
и L'
, чтобы у вас было:
...--F--G--H--K--L <-- OR/master
\
I--J <-- master
\
K'-L' <-- dev
, а затем вы можете быстро перемотать вперед master
, чтобы у вас было:
...--F--G--H--K--L <-- OR/master
\
I--J--K'-L' <-- dev, master
В конце концов они сделают больше коммитов:
...--F--G--H--K--L--N--O <-- OR/master
\
I--J--K'-L' <-- dev, master
(я пропустил M
, чтобы зарезервировать его), и, возможно, у вас также есть:
...--F--G--H--K--L--N--O <-- OR/master
\
I--J--K'-L' <-- dev
\
P--Q <-- master
но если вы сейчас git checkout dev
и git rebase OR/master
, то просто скопируйте ваши I
и J
в I'
и J'
и скопируйте K'
, то есть копию их K
, в новыйK"
и так далее:
I'-J'-K"-L" <-- dev
/
...--F--G--H--K--L--N--O <-- OR/master
\
I--J--K'-L'
\
P--Q <-- master
Это действительно никуда вас не приведет.
Если вы объедините , вы получите следующее:
...--F--G--H--K--L <-- OR/master
\ \
I--J--M <-- master
Теперь они делают свои коммиты, а вы делаете свои:
...--F--G--H--K--L----N---O <-- OR/master
\ \
I--J--M--P--Q <-- master
и еще раз вы просто git merge OR/master
включаете их работу в вашу работу:
...--F--G--H--K--L----N---O <-- OR/master
\ \ \
I--J--M--P--Q--R <-- master
Когда вы делаете это слияние, вы должны разрешитьve любые конфликты слияний один раз .Если вы сделаете ребазинг, вам придется заново разрешить все прошлые конфликты слияний .(Использование git rerere
может помочь в этом, но есть предел того, насколько это полезно.) Причина, по которой вам нужно решить их только один раз, двойная:
- Вы делаете одинновый коммит, поэтому есть только одно место, где возникают конфликты.
- После того, как вы сделали коммит слияния
M
, а позже R
, слияние next начинается с общего слиянияbase, то есть L
, а затем O
: вам нужно только посмотреть на то, что они сделали с момента последнего общего коммита .
Это сам коммит слиянияэто устанавливает обновленную базу слияния с общим коммитом.Без фиксации слияния вы не получите обновленную базу слияния.Коммиты слияния хороши;обними их.: -)