Розуміння та запам'ятовування параметрів відновлення git


12

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

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

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

Що є хорошим правилом, яке допоможе мені запам'ятати, для чого слід встановити кожен із цих 3 параметрів, враховуючи будь-який вид перезавантаження на іншу гілку?

Майте на увазі, що я переглянув документацію на git-rebase знову, і знову, і знову, і знову (і знову), але це завжди важко зрозуміти (як нудна наукова довідка чи щось). Тож у цей момент я відчуваю, що мені потрібно залучити інших людей, щоб допомогти мені зрозуміти це.

Моя мета - я ніколи не повинен переглядати документацію для цих основних параметрів. Я до цих пір не змогла їх запам'ятати, і я вже зробила безліч знижок. Тому трохи незвично, що я досі мав змогу запам'ятати кожну іншу команду та її параметри, але не перезавантажуватися --onto.


Ви можете або визначити деякі псевдоніми 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робить, коли викликається, я спершу почав думати про це як про особливий тип злиття. Це насправді не так, але це допомогло, коли вперше почали розуміти базу даних. Позичити приклад гороху:

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потрібно вказати іншу ціль "повтор", ніж гілка "пуск":

git rebase --onto master feature bugfix

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

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

якщо вам потрібна додаткова допомога, ознайомтеся з посібником Rebase без сліз


Ваш результат виглядає оманливим. Rebase повинен залишити саму masterгілку без змін. Ви просто отримаєте "функцію", щоб розгалужуватись, G--C'--D'--E'поки masterвсе ще зупиняється на G.
Френк

@Frank, я зробив це, щоб підкреслити всю лінійну історію, але тепер я думаю, що ти краще. фіксований.
peachoftree

1
Чи можете ви показати приклад, де <target branch>і чим <start branch>відрізняються, щоб допомогти читачам зрозуміти найзагальніший випадок?
Rufflewind
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.