Перебазирования филиала после гитхаб "сквош и объединения" на мастер
Предположим, я разработал функцию на 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или подобным, чтобы выбрать коммиты. Реализации немного различаются в зависимости от конкретного вида ребаза.