Понимание и запоминание параметров git rebase

12

Пока что самая запутанная часть git - это переход на другую ветку. В частности, это аргументы командной строки, которые сбивают с толку.

Каждый раз, когда я хочу переместить небольшой кусок одной ветви на кончик другой, мне приходится просматривать документацию git rebase, и мне требуется около 5-10 минут, чтобы понять, каким должен быть каждый из 3 основных аргументов.

git rebase <upstream> <branch> --onto <newbase>

Какое хорошее эмпирическое правило помогает мне запомнить, какой должен быть установлен каждый из этих трех параметров, учитывая какой-либо перебаз в другую ветку?

Имейте в виду, что я перебрал документацию git-rebase снова и снова, и снова, и снова (и снова), но это всегда трудно понять (как скучный научный документ или что-то в этом роде). Поэтому на данный момент я чувствую, что мне нужно привлечь других людей, чтобы помочь мне понять это.

Моя цель состоит в том, чтобы мне никогда не приходилось просматривать документацию по этим основным параметрам. Я не смог запомнить их до сих пор, и я уже сделал тонну перебазирования. Так что немного необычно, что я до сих пор запоминал каждую другую команду и ее параметры, но не перезагружал --onto.

void.pointer
источник
Вы можете либо определить псевдонимы git для своих общих случаев использования, либо запустить скрипт мастера, который напоминает вам, что означает каждый из параметров, перед выполнением команды.
Рори Хантер
4
Ах, эта ошеломляющая, чистая элегантность опций команды git. Так что интуитивно использовать. Всегда настоящее удовольствие.
JensG

Ответы:

10

Давайте пропустить --ontoна данный момент. upstreamи branchдовольно просты, и на самом деле имитируют checkoutи branch- второй аргумент является необязательным:

git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>

( За исключением, имена этих аргументов в rebase«вверх» и «ветви» не очень описательный IMO я обычно думаю о них , как peachoftree,. <start>И <end>, что , как я буду использовать их: git rebase <start> <end>)

Когда вторая ветвь опущена, результат почти такой же, как сначала проверить эту ветку, а затем сделать это так, как если бы вы не указали эту ветку. Исключением является то, branchчто не меняет вашу текущую ветку:

git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end>  && git rebase <start>

Что касается понимания того, что rebaseпроисходит при вызове, я сначала начал думать об этом как об особом типе слияния. Это не совсем так, но помогло, когда впервые начал понимать ребаз. Взять пример с peachoftree:

A--B--F--G master
    \
     C--D--E feature

А git merge masterрезультаты в этом:

A--B--F-----G master
    \        \
     C--D--E--H feature

Хотя git rebase master(в то время как на ветке feature!) Приводит к этому:

A--B--F--G master
          \
           C'--D'--E' feature

В обоих случаях featureтеперь содержит код от обоих masterи feature. Если вы не featureвключены, второй аргумент может быть использован для переключения на него в качестве ярлыка: git rebase master featureбудет сделано то же самое, что и выше.


Теперь для спец --onto. Важно помнить, что по умолчанию используется значение, <start>если оно не указано. Так что выше, если бы я указал --ontoконкретно, это привело бы к тому же:

git rebase --onto master master
git rebase --onto master master feature

(Я не использую, --ontoне указывая <end>просто, потому что мысленно разобрать легче, даже если они оба одинаковые, если они уже включены feature.)

Чтобы понять, почему --ontoэто полезно, вот другой пример. Допустим, я был включен featureи заметил ошибку, которую я затем начал исправлять, но featureвместо нее произошел ответвление вместо master:

A--B--F--G master
    \
     C--D--E feature
            \
             H--I bugfix

Я хочу «переместить» эти коммиты, bugfixчтобы они больше не зависели feature. Таким образом, любой вид слияния или перебазирования, показанный выше в этом ответе, примет три featureкоммита вместе с двумя bugfixкоммитами.

Например, git rebase master bugfixэто неправильно. Диапазон, <start>который <end>случается, включает все коммиты feature, которые воспроизводятся поверх master:

A--B--F--G master
    \     \
     \     C'--D'--E'--H'--I' bugfix
      \
       C--D--E feature

То , что мы на самом деле хотим диапазон коммитов от featureдо bugfixбыть переигран на вершине master. Вот для чего --onto- указание цели «воспроизведения», отличной от ветви «start»:

git rebase --onto master feature bugfix

A--B--F--G master
    \     \
     \     H'--I' bugfix
      \
       C--D--E feature
Izkata
источник
1

Просто переподготовка, перебазирование в основном для случаев, когда вы хотите, чтобы ваша история коммитов была линейной, если две ветви развивались независимо друг от друга, в основном она переписывает историю коммитов.

как мне нравится это git rebase --onto <target branch> <start branch> <end branch>

где <target branch>ветка, на которую вы перебазируете, <start branch>обычно ветвь, из которой вы делите, <end branch>и <end branch>ветка, на которую вы перебираете.

если вы начнете с

A--B--F--G master
    \
     C--D--E feature

и делать

git rebase --onto master master feature

ты получишь

A--B--F--G master
          \
           C'--D'--E' feature

еще одна полезная вещь, которую нужно знать, это то, что по <target branch>умолчанию <start branch>вы можете сделать то же

git rebase --onto master feature

если вам нужна дополнительная помощь, проверить перебазироваться без слез руководства

peachoftree
источник
Ваш результат выглядит обманчивым. rebase должен оставить masterсаму ветку без изменений. Вы просто получаете «особенность» , чтобы расшириться , как в G--C'--D'--E'то время masterвсе еще останавливается G.
Фрэнк
@ Франц, я сделал это, чтобы подчеркнуть всю линейную историю, но теперь я думаю, что ты лучше. фиксированный.
peachoftree
1
Можете ли вы показать пример, где <target branch>и <start branch>разные, чтобы помочь читателям понять наиболее общий случай?
Rufflewind