Rebase onto что это

Введение в Git Merge и Git Rebase: зачем и когда их использовать

Часто у разработчиков возникает выбор между Merge (слияние) и Rebase (перемещение). В Гугле вы увидите разное мнение, многие советуют не использовать Rebase, так как это может вызвать серьезные проблемы. В статье я объясню, что такое слияние и перемещение, почему вы должны (или не должны) использовать их и как это сделать.

Rebase onto что это. a1842bb5114cb6fdc85d29fa103a6a74. Rebase onto что это фото. Rebase onto что это-a1842bb5114cb6fdc85d29fa103a6a74. картинка Rebase onto что это. картинка a1842bb5114cb6fdc85d29fa103a6a74

Git Merge и Git Rebase преследуют одну и ту же цель. Они предназначены для интеграции изменений из одной ветки в другую. Хотя конечная цель одинаковая, принципы работы разные.

Некоторые считают, что вы всегда должны использовать Rebase, другие предпочитают Merge. В этом есть свои плюсы и минусы.

Git Merge

Слияние — обычная практика для разработчиков, использующих системы контроля версий. Независимо от того, созданы ли ветки для тестирования, исправления ошибок или по другим причинам, слияние фиксирует изменения в другом месте. Слияние принимает содержимое ветки источника и объединяет их с целевой веткой. В этом процессе изменяется только целевая ветка. История исходных веток остается неизменной.
Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader
Плюсы:

Слейте ветку master в ветку feature, используя команды checkout и merge.

Это создаст новый «Merge commit» в ветке feature, который содержит историю обеих веток.

Git Rebase

Rebase — еще один способ перенести изменения из одной ветки в другую. Rebase сжимает все изменения в один «патч». Затем он интегрирует патч в целевую ветку.

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

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

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

Это перемещает всю ветку функции в главную ветку. История проекта изменяется, создаются новые коммиты для каждого коммита в основной ветке.

Интерактивное перемещение

Это позволяет изменять коммиты при их перемещении в новую ветку. Это лучше, чем автоматическое перемещение, поскольку обеспечивает полный контроль над историей коммитов. Как правило, используется для очистки истории до слияния ветки feature в master.

Это откроет редактор, перечислив все коммиты, которые будут перемещены.

Это точно определяет, как будет выглядеть ветка после выполнения перемещения. Упорядочивая объекты, вы можете сделать историю такой, как захотите. Вы можете использовать команды fixup, squash, edit, и так далее.

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Какой из них использовать?

Так что же лучше? Что рекомендуют эксперты?

Трудно принять единственно правильное решение о том, что лучше использовать, поскольку все команды разные. Всё зависит от потребностей и традиций внутри команды.

Принимайте решения на основании компетенции команды в Git. Для вас важна простота или перезаписывание истории, а может быть что-то другое?

По мере роста команды становится сложно управлять или отслеживать изменения в разработке, применяя слияние. Чтобы иметь чистую и понятную историю коммитов, разумно использовать Rebase.

Источник

git rebase для начинающих

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

Итак git работает с комитами. Каждый комит — набор изменений. У каждого комита есть уникальный hash. Когда происходит слияние веток посредством merge:

то все комиты сохраняются — сохраняются комментарии комита, его hash + как правило добавляется еще один искусственный комит. При этом комиты могут чередоваться друг с другом. Это не всегда удобно. Допустим ваш комит решили откатить — выискивать в общем списке где ваш комит, а где не ваш не очень приятно. И вообще — в общей истории хочется видеть действительно важные изменения, а не «ой, я забыл поставить ;». Для того, чтобы несколько комитов склеивать в один можно использовать rebase. Хотя в интерфейсе GitHub есть кнопочка squash & commit — это когда вы создаете pull request (PR) из одной ветки в другую (как правило из вашей рабочей ветки в основную) и после прохождения всех формальностей можно нажать squash & commit, обновить комментарий и ваши изменения появятся в основной ветке как один комит.

Из плюсов — можно весь код, все изменения посмотреть в IDE. Иногда бывает удобнее, чем через web UI, который на GitHub.

Осторожно rebase может менять hash комита и приводить к конфликтам слияний, особенно если над одной веткой трудятся несколько человек.

Хочу написать о двух случаях использования rebase:

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

Вдогонку напишу что у меня получилось. Дано — 2 ветки — master и b1. В процессе работы мы сделали комиты:

Комиты в master и b1 были сделаны независимо. Написал в один список, чтобы был понятен порядок в котором все делалось. Вот список комитов в каждом бранче:

# git checkout master && git log
8dcef6c «+1»
b505f18 «master after b1.1»
2fbbe67 «Initial commit»

# git checkout b1 && git log
2d7d4ea «b1.2»
85eac43 «b1.1»
2fbbe67 «Initial commit»

Делаем git merge master в b1

# git checkout b1 && git merge master && git log
5383781 «Merge branch ‘master’ into b1»
8dcef6c «+1»
2d7d4ea «b1.2»
b505f18 «master after b1.1»
85eac43 «b1.1»
2fbbe67 «Initial commit»

Добавился новый синтетический комит

Теперь делаем rebase

# git checkout b1 && git rebase master && git log
7f18e47 «b1.2»
6fb80cb «b1.1»
8dcef6c «+1»
b505f18 «master after b1.1»
2fbbe67 «Initial commit»

Обратите внимание — наши локальные комиты встали в конец списка, номера комитов изменились, синтетический комит исчез.

Ну и напоследок склеиваем наши комиты в один

pick 6fb80cb b1.1
pick 7f18e47 b1.2

Файл стало после нашего редактирования

pick 6fb80cb b1.1
fixup 7f18e47 b1.2

# git checkout b1 && git log
9062cd7 «b1.1»
8dcef6c «+1»
b505f18 «master after b1.1»
2fbbe67 «Initial commit»

Такие дела

Источник

Руководство по Git. Часть №2: золотое правило и другие основы rebase

Посмотрим, что происходит, когда вы выполняете git rebase и почему нужно быть внимательным.

Это вторая и третья части гайда по Git из блога Pierre de Wulf в переводе команды Mail.ru Cloud Solutions. Первую часть можно почитать тут.

Суть rebase

Как именно происходит rebase:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Можно сказать, что rebase — это открепить ветку (branch), которую вы хотите переместить, и подключить ее к другой ветке. Такое определение соответствует действительности, но попробуем заглянуть чуть глубже. Если вы посмотрите документацию, вот что там написано относительно rebase: «Применить коммиты к другой ветке (Reapply commits on top of another base tip)».

Главное слово здесь — применить, потому что rebase — это не просто копипаст ветки в другую ветку. Rebase последовательно берет все коммиты из выбранной ветки и заново применяет их к новой ветке.

Такое поведение приводит к двум моментам:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Как видите, ветка feature содержит абсолютно новые коммиты. Как было сказано ранее, тот же самый набор изменений, но абсолютно новые объекты с точки зрения Git.

Это также означает, что старые коммиты не уничтожаются. Они становятся просто недоступными напрямую. Если вы помните, ветка — всего лишь ссылка на коммит. Таким образом, если ни ветка, ни тег не ссылаются на коммит, к нему невозможно получить доступ средствами Git, хотя на диске он продолжает присутствовать.

Теперь давайте обсудим «Золотое правило».

Золотое правило rebase

Золотое правило rebase звучит так — «НИКОГДА не выполняйте rebase расшаренной ветки!». Под расшаренной веткой понимается ветка, которая существует в сетевом репозитории и с которой могут работать другие люди, кроме вас.

Часто это правило применяют без должного понимания, поэтому разберем, почему оно появилось, тем более что это поможет лучше понять работу Git.

Давайте рассмотрим ситуацию, когда разработчик нарушает золотое правило, и что происходит в этом случае.

Предположим, Боб и Анна вместе работают над проектом. Ниже представлено, как выглядят репозитории Боба и Анны и исходный репозиторий на GitHub:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

У всех пользователей репозитории синхронизируются с GitHub.

Теперь Боб, нарушая золотое правило, выполняет rebase, и в это же время Анна, работая в ветке feature, создает новый коммит:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Вы видите, что произойдет?

Боб пытается выполнить пуш коммита, ему приходит отказ примерно такого содержания:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Выполнение Git не было успешным, потому что Git не знает, как объединить feature ветку Боба с feature веткой GitHub.

Единственным решением, позволяющим Бобу выполнить push, станет использование ключа force, который говорит GitHub-репозиторию удалить у себя ветку feature и принять за эту ветку ту, которая пушится Бобом. После этого мы получим следующую ситуацию:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Теперь Анна хочет запушить свои изменения, и вот что будет:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Это нормально, Git сказал Анне, что у нее нет синхронизированной версии ветки feature, то есть ее версия ветки и версия ветки в GitHub — разные. Анна должна выполнить pull. Точно таким же образом, как Git сливает локальную ветку с веткой в репозитории, когда вы выполняете push, Git пытается слить ветку в репозитории с локальной веткой, когда вы выполняете pull.

Перед выполнением pull коммиты в локальной и GitHub-ветках выглядят так:

Когда вы выполняете pull, Git выполняет слияние для устранения разности репозиториев. И вот, к чему это приводит:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Коммит M — это коммит слияния (merge commit). Наконец, ветки feature Анны и GitHub полностью объединены. Анна вздохнула с облегчением, все конфликты устранены, она может выполнить push.

Боб выполняет pull, теперь все синхронизированы:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

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

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

Также учтите, что появляются дубликаты коммитов в сетевом репозитории. В нашем случае — D и D’, содержащие одни и те же данные. По сути, количество дублированных коммитов может быть таким же большим, как и количество коммитов в вашей rebased ветке.

Если вы все еще не убеждены, давайте представим Эмму — третью разработчицу. Она работает в ветке feature перед тем, как Боб совершает свою ошибку, и в настоящий момент хочет выполнить push. Предположим, что к моменту ее push наш маленький предыдущий сценарий уже завершился. Вот что выйдет:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

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

Красота pull rebase

Как вы видели выше, проблем Анны можно было избежать, если бы она использовала pull rebase. Рассмотрим этот вопрос подробнее.

Допустим, Боб работает в ветке, отходящей от мастера, тогда его история может выглядеть вот так:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Боб решает, что настало время выполнить pull, что, как вы уже поняли, приведет к некоторым неясностям. Поскольку репозиторий Боба отходил от GitHub, Git спросит делать ли объединение, и результат будет таким:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Это решение подходит и работает нормально, однако, вам может быть полезно знать, что есть другие варианты решения проблемы. Одним из них является pull-rebase.

Когда вы делаете pull-rebase, Git пытается выяснить, какие коммиты есть только в вашей ветке, а какие — в сетевом репозитории. Затем Git объединяет коммиты из сетевого репозитория с самым свежим коммитом, присутствующим и в локальном, и в сетевом репозитории. После чего выполняет rebase ваших локальных коммитов в конец ветки.

Звучит сложно, поэтому проиллюстрируем:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Как вы помните, при rebase Git применяет коммиты один за одним, то есть в данном случаем применяет в конец ветки master коммит E, потом F. Получился rebase сам в себя. Выглядит неплохо, но возникает вопрос — зачем так делать?

По моему мнению, самая большая проблема с объединением веток в том, что загрязняется история коммитов. Поэтому pull-rebase — более элегантное решение. Я бы даже пошел дальше и сказал, что когда нужно скачать последние изменения в вашу ветку, вы всегда должны использовать pull-rebase. Но нужно помнить: поскольку rebase применяет все коммиты по очереди, то когда вы делаете rebase 20 коммитов, вам, возможно, придется решать один за другим 20 конфликтов.

Как правило, можно использовать следующий подход: одно большое изменение, сделанное давно — merge, два маленьких изменения, сделанных недавно — pull-rebase.

Сила rebase onto

Предположим, история ваших коммитов выглядит так:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Итак, вы хотите выполнить rebase ветки feature 2 в ветку master. Если вы выполните обычный rebase в ветку master, получите это:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Нелогично выглядит то, что коммит D существует в обоих ветках: в feature 1 и feature 2. Если вы переместите ветку feature 1 в конец ветки мастер, получится, что коммит D будет применен два раза.

Предположим, что вам нужно получить другой результат:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Для реализации подобного сценария как раз и предназначен git rebase onto.

Сначала прочтем документацию:

Нас интересует вот это:

С помощью этой опции указывается, в какой точке создавать новые коммиты.

Если эта опция не указана, то стартовой точкой станет upstream.

Для понимания приведу еще один рисунок:

То есть ветка master — это newbase, а ветка feature 1 — upstream.

Источник

Руководство по Git. Часть №2: золотое правило и другие основы rebase

Посмотрим, что происходит, когда вы выполняете git rebase и почему нужно быть внимательным.

Суть rebase

Как именно происходит rebase:

Rebase onto что это. git1. Rebase onto что это фото. Rebase onto что это-git1. картинка Rebase onto что это. картинка git1

Можно сказать, что rebase — это открепить ветку (branch), которую вы хотите переместить, и подключить ее к другой ветке. Такое определение соответствует действительности, но попробуем заглянуть чуть глубже. Если вы посмотрите документацию, вот что там написано относительно rebase: «Применить коммиты к другой ветке (Reapply commits on top of another base tip)».

Главное слово здесь — применить, потому что rebase — это не просто копипаст ветки в другую ветку. Rebase последовательно берет все коммиты из выбранной ветки и заново применяет их к новой ветке.

Такое поведение приводит к двум моментам:

Вот более правильная интерпретация того, что происходит при rebase:

Rebase onto что это. git2. Rebase onto что это фото. Rebase onto что это-git2. картинка Rebase onto что это. картинка git2

Как видите, ветка feature содержит абсолютно новые коммиты. Как было сказано ранее, тот же самый набор изменений, но абсолютно новые объекты с точки зрения Git.

Теперь давайте обсудим «Золотое правило».

Золотое правило rebase

Золотое правило rebase звучит так — «НИКОГДА не выполняйте rebase расшаренной ветки!». Под расшаренной веткой понимается ветка, которая существует в сетевом репозитории и с которой могут работать другие люди, кроме вас.

Часто это правило применяют без должного понимания, поэтому разберем, почему оно появилось, тем более что это поможет лучше понять работу Git.

Давайте рассмотрим ситуацию, когда разработчик нарушает золотое правило, и что происходит в этом случае.

Предположим, Боб и Анна вместе работают над проектом. Ниже представлено, как выглядят репозитории Боба и Анны и исходный репозиторий на GitHub:

Rebase onto что это. git3. Rebase onto что это фото. Rebase onto что это-git3. картинка Rebase onto что это. картинка git3

У всех пользователей репозитории синхронизируются с GitHub.

Теперь Боб, нарушая золотое правило, выполняет rebase, и в это же время Анна, работая в ветке feature, создает новый коммит:

Rebase onto что это. git4. Rebase onto что это фото. Rebase onto что это-git4. картинка Rebase onto что это. картинка git4

Вы видите, что произойдет?

Боб пытается выполнить пуш коммита, ему приходит отказ примерно такого содержания:

Rebase onto что это. git5. Rebase onto что это фото. Rebase onto что это-git5. картинка Rebase onto что это. картинка git5

Выполнение Git не было успешным, потому что Git не знает, как объединить feature ветку Боба с feature веткой GitHub.

Единственным решением, позволяющим Бобу выполнить push, станет использование ключа force, который говорит GitHub-репозиторию удалить у себя ветку feature и принять за эту ветку ту, которая пушится Бобом. После этого мы получим следующую ситуацию:

Rebase onto что это. git6. Rebase onto что это фото. Rebase onto что это-git6. картинка Rebase onto что это. картинка git6

Теперь Анна хочет запушить свои изменения, и вот что будет:

Источник

Руководство по Git. Часть №2: золотое правило и другие основы rebase

Посмотрим, что происходит, когда вы выполняете git rebase и почему нужно быть внимательным.

Это вторая и третья части гайда по Git из блога Pierre de Wulf в переводе команды Mail.ru Cloud Solutions. Первую часть можно почитать тут.

Суть rebase

Как именно происходит rebase:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Можно сказать, что rebase — это открепить ветку (branch), которую вы хотите переместить, и подключить ее к другой ветке. Такое определение соответствует действительности, но попробуем заглянуть чуть глубже. Если вы посмотрите документацию, вот что там написано относительно rebase: «Применить коммиты к другой ветке (Reapply commits on top of another base tip)».

Главное слово здесь — применить, потому что rebase — это не просто копипаст ветки в другую ветку. Rebase последовательно берет все коммиты из выбранной ветки и заново применяет их к новой ветке.

Такое поведение приводит к двум моментам:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Как видите, ветка feature содержит абсолютно новые коммиты. Как было сказано ранее, тот же самый набор изменений, но абсолютно новые объекты с точки зрения Git.

Это также означает, что старые коммиты не уничтожаются. Они становятся просто недоступными напрямую. Если вы помните, ветка — всего лишь ссылка на коммит. Таким образом, если ни ветка, ни тег не ссылаются на коммит, к нему невозможно получить доступ средствами Git, хотя на диске он продолжает присутствовать.

Теперь давайте обсудим «Золотое правило».

Золотое правило rebase

Золотое правило rebase звучит так — «НИКОГДА не выполняйте rebase расшаренной ветки!». Под расшаренной веткой понимается ветка, которая существует в сетевом репозитории и с которой могут работать другие люди, кроме вас.

Часто это правило применяют без должного понимания, поэтому разберем, почему оно появилось, тем более что это поможет лучше понять работу Git.

Давайте рассмотрим ситуацию, когда разработчик нарушает золотое правило, и что происходит в этом случае.

Предположим, Боб и Анна вместе работают над проектом. Ниже представлено, как выглядят репозитории Боба и Анны и исходный репозиторий на GitHub:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

У всех пользователей репозитории синхронизируются с GitHub.

Теперь Боб, нарушая золотое правило, выполняет rebase, и в это же время Анна, работая в ветке feature, создает новый коммит:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Вы видите, что произойдет?

Боб пытается выполнить пуш коммита, ему приходит отказ примерно такого содержания:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Выполнение Git не было успешным, потому что Git не знает, как объединить feature ветку Боба с feature веткой GitHub.

Единственным решением, позволяющим Бобу выполнить push, станет использование ключа force, который говорит GitHub-репозиторию удалить у себя ветку feature и принять за эту ветку ту, которая пушится Бобом. После этого мы получим следующую ситуацию:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Теперь Анна хочет запушить свои изменения, и вот что будет:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Это нормально, Git сказал Анне, что у нее нет синхронизированной версии ветки feature, то есть ее версия ветки и версия ветки в GitHub — разные. Анна должна выполнить pull. Точно таким же образом, как Git сливает локальную ветку с веткой в репозитории, когда вы выполняете push, Git пытается слить ветку в репозитории с локальной веткой, когда вы выполняете pull.

Перед выполнением pull коммиты в локальной и GitHub-ветках выглядят так:

Когда вы выполняете pull, Git выполняет слияние для устранения разности репозиториев. И вот, к чему это приводит:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Коммит M — это коммит слияния (merge commit). Наконец, ветки feature Анны и GitHub полностью объединены. Анна вздохнула с облегчением, все конфликты устранены, она может выполнить push.

Боб выполняет pull, теперь все синхронизированы:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

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

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

Также учтите, что появляются дубликаты коммитов в сетевом репозитории. В нашем случае — D и D’, содержащие одни и те же данные. По сути, количество дублированных коммитов может быть таким же большим, как и количество коммитов в вашей rebased ветке.

Если вы все еще не убеждены, давайте представим Эмму — третью разработчицу. Она работает в ветке feature перед тем, как Боб совершает свою ошибку, и в настоящий момент хочет выполнить push. Предположим, что к моменту ее push наш маленький предыдущий сценарий уже завершился. Вот что выйдет:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

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

Красота pull rebase

Как вы видели выше, проблем Анны можно было избежать, если бы она использовала pull rebase. Рассмотрим этот вопрос подробнее.

Допустим, Боб работает в ветке, отходящей от мастера, тогда его история может выглядеть вот так:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Боб решает, что настало время выполнить pull, что, как вы уже поняли, приведет к некоторым неясностям. Поскольку репозиторий Боба отходил от GitHub, Git спросит делать ли объединение, и результат будет таким:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Это решение подходит и работает нормально, однако, вам может быть полезно знать, что есть другие варианты решения проблемы. Одним из них является pull-rebase.

Когда вы делаете pull-rebase, Git пытается выяснить, какие коммиты есть только в вашей ветке, а какие — в сетевом репозитории. Затем Git объединяет коммиты из сетевого репозитория с самым свежим коммитом, присутствующим и в локальном, и в сетевом репозитории. После чего выполняет rebase ваших локальных коммитов в конец ветки.

Звучит сложно, поэтому проиллюстрируем:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Как вы помните, при rebase Git применяет коммиты один за одним, то есть в данном случаем применяет в конец ветки master коммит E, потом F. Получился rebase сам в себя. Выглядит неплохо, но возникает вопрос — зачем так делать?

По моему мнению, самая большая проблема с объединением веток в том, что загрязняется история коммитов. Поэтому pull-rebase — более элегантное решение. Я бы даже пошел дальше и сказал, что когда нужно скачать последние изменения в вашу ветку, вы всегда должны использовать pull-rebase. Но нужно помнить: поскольку rebase применяет все коммиты по очереди, то когда вы делаете rebase 20 коммитов, вам, возможно, придется решать один за другим 20 конфликтов.

Как правило, можно использовать следующий подход: одно большое изменение, сделанное давно — merge, два маленьких изменения, сделанных недавно — pull-rebase.

Сила rebase onto

Предположим, история ваших коммитов выглядит так:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Итак, вы хотите выполнить rebase ветки feature 2 в ветку master. Если вы выполните обычный rebase в ветку master, получите это:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Нелогично выглядит то, что коммит D существует в обоих ветках: в feature 1 и feature 2. Если вы переместите ветку feature 1 в конец ветки мастер, получится, что коммит D будет применен два раза.

Предположим, что вам нужно получить другой результат:

Rebase onto что это. image loader. Rebase onto что это фото. Rebase onto что это-image loader. картинка Rebase onto что это. картинка image loader

Для реализации подобного сценария как раз и предназначен git rebase onto.

Сначала прочтем документацию:

Нас интересует вот это:

С помощью этой опции указывается, в какой точке создавать новые коммиты.

Если эта опция не указана, то стартовой точкой станет upstream.

Для понимания приведу еще один рисунок:

То есть ветка master — это newbase, а ветка feature 1 — upstream.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *