Рабочий механизм 'git rebase' в git - PullRequest
1 голос
/ 04 сентября 2010

Это отрывок из Visual Git Reference , который объясняет идею перебазирования.

http://a.imageshack.us/img339/4264/screenshot20100903at102.png

Мое понимание таково.

  • git отслеживает изменения, поэтому 169a6 и 2c33a имеют (отслеживает) изменения от фиксацииa47c3.
  • ребаз означает применение изменений к da985.В результате f7e63 имеет (отслеживает) все изменения с b325c на e57cf.

Вопросы.

  • Правильно ли мое понимание?
  • Если это так, как мы можем быть уверены, что изменения в 169a6 и 2c33a могут быть (безопасно)применяется к коммиту da985?
  • Если нет, не могли бы вы объяснить, что делает ребаз?

1 Ответ

5 голосов
/ 04 сентября 2010

То, как вы выразили свое понимание, немного смутило меня.Я думаю, что вы можете сделать это правильно, но на случай, если вы этого не сделаете, вот как я обычно думаю об этом.Когда вы перебазируете, git берет эти два коммита и пытается применить их к новой базе.e57cf является результатом применения diff 169a6, то есть в простых идеальных случаях git diff a46c3 169a6 и git diff da985 e57cf должны давать одинаковый результат.Аналогично, f7e63 должен содержать те же изменения, что и 2c33a.Вы можете думать о «rebase» как о синониме «трансплантат», если это помогает.

Теперь изменения не обязательно могут быть применены корректно.Когда rebase сталкивается с коммитом, патч которого не применяется, вы получите конфликты, как при слиянии, и он попросит вас разрешить их, а затем запустит git rebase --continue, чтобы переместить их.

Надеюсь, есть смысл, что это действительно операция слияния.Здесь есть некоторые детали реализации, но в итоге git использует все возможности слияния всякий раз, когда это возможно.Хотя конечным результатом является пересадка 169a6 так, что она становится e57cf, содержимое коммита e57cf может быть создано путем слияния 169a6 с da985 - со знанием того, что у них есть общий предок a47c3, так что триСлияние возможно.Это позволяет перебазировкам избегать конфликтов в некоторых случаях, когда вы ожидаете их возникновения.

Подробности реализации, если вам интересно: по умолчанию перебазировка использует git-format-patch для создания различийи затем применяет их с помощью git-am, с опцией --3way, предписывающей ему «отступить при трехстороннем слиянии, если патч записывает идентичность BLOB-объектов, к которым он должен применяться, и мы имеемэти капли доступны локально. "Также возможно сказать, что rebase использует внутренние стратегии слияния, и в этом случае он напрямую вызывает стратегию слияния (по умолчанию рекурсивно).В любом случае, это более изощренно, чем просто сбросить патч и наивно применить его.

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

...