Перебазирования филиала после гитхаб "сквош и объединения" на мастер
Предположим, я разработал функцию на branch1
и отправил ее на проверку кода с помощью запроса на вытягивание GitHub. Пока он пересматривается, я делаю некоторые последующие работы над branch2
.
branch2 -> D --> E --> F
/
branch1 -> A --> B --> C
/
master M
Мой рецензент любит мою работу! Никаких изменений не требуется. Я объединяю запрос pull для branch1
с помощью функции GitHub Squash и merge.
После запуска git pull
на master
и удаления branch1
, я остаюсь с этой ситуацией:
branch2 -> A --> B --> C -> D --> E --> F
/
master M --> S
Чтобы отправить чистый пиар для branch2
, я бы например, чтобы мое дерево фиксации выглядело так:
branch2 -> D' --> E' --> F'
/
master M --> S
Код в S
(фиксация, сгенерированная "сквошем и слиянием" для branch1
) идентичен C
, так как это просто раздавленная версия A --> B --> C
.
Один из способов достичь этого-запустить последовательность, подобную этой, на branch2
:
git reset --hard S
git cherry-pick D E F
Но перечисление всех коммитов таким образом становится утомительным, и это действительно похоже на перебазирование. git rebase master
не будет работать, конечно, так как совершает A
, B
и C
нужно исчезнуть.
Как лучше всего перебазировать ветвь от раздавленной версии одного из ее предковых коммитов?
1 ответ:
Используйте
Я думаю, что лучше, кстати, нарисовать эти графики с именами ветвей в правой части , указывая на один конкретный коммит. Это происходит потому, что в Git коммиты находятся на нескольких ветвях, а имена ветвей действительно делают просто указывают на один конкретный коммит. Также стоит обратить вспять внутренние стрелки (потому что Git действительно хранит их таким образом) или просто используя соединительные линии, чтобы не подразумевать неправильное направление.git rebase
с--onto
. Это все еще немного сложно, поэтому, чтобы сделать его легким, вы захотите сделать одну вещь по-другому, раньше.Отсюда:
D--E--F <-- branch2 / A--B--C <-- branch1 / M <-- master
Коммиты
A
черезC
действительно находятся на обоихbranch1
и ещеbranch2
, в то время как коммитыD
черезF
являются только наbranch2
. (КоммитыM
и ранее находятся на всех трех ветвях.)Что
git rebase upstream
делает, это выбирает все1 коммиты достижимы из текущей ветви, но недостижимы из текущей ветви.upstream
затем скопируйте их (сgit cherry-pick
или эквивалентом) так, чтобы они шли сразу после аргумента.upstream
совершить.После сквоша - "слияние" (не совсем слияние), если вы запустите
git fetch
, а затем перемотаете вперед вашmaster
, у вас будет то же самое, что вы нарисовали, но я оставляюbranch1
и ставлю метки слева и добавляюorigin/master
здесь:D--E--F <-- branch2 / A--B--C <-- branch1 / M--S <-- master, origin/master
(или, если вы еще не перемотали свой
master
, толькоorigin/master
указывает на фиксациюS
).Теперь вы хотите рассказать Git чтобы скопировать
D-E-F
с помощью cherry-pick, затем переместите меткуbranch2
, чтобы указать на последний скопированный коммит. Вы не хотите копироватьA-B-C
, поскольку они включены вS
. Вы хотите, чтобы копии шли послеS
, на чтоorigin/master
теперь указывает-обновили выmaster
или нет. Отсюда:git checkout branch2 git rebase --onto origin/master branch1
upstream
Теперьbranch1
вместоmaster
, но--onto
говорит Git, где разместить копии:branch1
служит только для разграничения того, что не копировать . Так что теперь git копируетD-E-F
и изменяетbranch2
, чтобы указать туда:D--E--F [abandoned] / A--B--C <-- branch1 / M--S <-- master?, origin/master \ D'-E'-F' <-- branch2
И теперь Вы можете удалить имя
branch1
. (И теперь вы можете перемотать впередmaster
, Если вы этого еще не сделали-на самом деле не имеет значения, когда вы это сделаете, и на самом деле вам вообще не нужна ваша собственнаяmaster
.)
1точнее, rebase выбирает коммиты, которые (а) не являются коммитами слияния и (б) не имеют того же
git patch-id
, что и некоторые коммиты в исключенном множестве, используя симметричную разницу. То есть, скорее, чемupstream..HEAD
, Git фактически запускаетgit rev-list
наupstream...HEAD
, с--cherry-mark
или подобным, чтобы выбрать коммиты. Реализации немного различаются в зависимости от конкретного вида ребаза.