it-roy-ru.com

В чем разница между «git merge» и «git rebase»?

В чем разница между git merge и git rebase?

453
Daniel Peñalba

Предположим, что изначально было 3 коммита, A, B, C:

A-B-C

Затем разработчик Дэн создал коммит D, а разработчик Эд создал коммит E:

A-B-C-D-E

Очевидно, этот конфликт нужно как-то решить. Для этого есть 2 способа:

ОБЪЕДИНИТЬ:

A-B-C-D-E-M

Оба коммита D и E все еще здесь, но мы создаем коммит слияния M, который наследует изменения как D, так и E. Тем не менее, это создает ромбовидную форму, которая многих людей смущает.

REBASE:

A-B-C-D-E-R

Мы создаем коммит R, который фактически совпадает с содержимым коммита слияния M выше. Но мы избавляемся от коммита E, как будто его никогда не существовало (обозначено точками - исчезающая линия). Из-за этого уничтожения E должен быть локальным для разработчика Ed и никогда не должен передаваться в какой-либо другой репозиторий. Преимущество перебазирования в том, что форма в виде ромба исключается, а история остается хорошей прямой линией - большинству разработчиков это нравится!

797
mvp

Мне очень нравится этот отрывок из 10 вещей, которые я ненавижу в git (он дает краткое объяснение rebase во втором примере):

3. Дрянная документация

Страницы руководства - это одно всемогущее "f *** you"1, Они описывают команды с точки зрения ученого, а не пользователя. Дело в точке:

git-Push – Update remote refs along with associated objects

Вот описание для людей:

git-Push – Upload changes from your local repository into a remote repository

Обновление, другой пример: (спасибо CGD)

git-rebase – Forward-port local commits to the updated upstream head

Перевод:

git-rebase – Sequentially regenerate a series of commits so they can be 
             applied directly to the head node

И тогда у нас есть

git-merge - Join two or more development histories together

это хорошее описание.


1. без цензуры в оригинале

139
mvw

Лично я не нахожу стандартную технику построения диаграмм очень полезной - стрелки всегда, кажется, указывают неправильный путь для меня. (Они обычно указывают на "родителя" каждого коммита, который в конечном итоге оказывается назад во времени, что странно).

Чтобы объяснить это словами:

  • Когда вы перебазируете свою ветку на их ветку, вы говорите Git, чтобы она выглядела так, как будто вы аккуратно проверили их ветку, а затем выполнили всю свою работу, начиная с нее. Это делает чистый, концептуально простой пакет изменений, который кто-то может просмотреть. Вы можете повторить этот процесс еще раз, когда в их ветке появятся новые изменения, и у вас всегда будет чистый набор изменений "на кончике" их ветки.
  • Когда вы объединяете их ветвь в вашу ветвь, на этом этапе вы связываете две истории ветвей. Если вы сделаете это снова позже с большим количеством изменений, вы начнете создавать чередующийся поток историй: некоторые их изменения, некоторые мои изменения, некоторые их изменения. Некоторые люди считают это грязным или нежелательным.

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

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

Пример

Я попытаюсь объяснить это на примере только слова. Допустим, другие люди в вашем проекте работают над пользовательским интерфейсом, а вы пишете документацию. Без перебазирования ваша история может выглядеть примерно так:

Write tutorial
Merge remote-tracking branch 'Origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'Origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md

То есть слияния и пользовательский интерфейс фиксируются в середине вашей документации.

Если вы перенесете свой код на master вместо слияния, это будет выглядеть так:

Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger

Все ваши коммиты находятся вверху (самые новые), за ними следуют остальные ветви master.

( Отказ от ответственности: я являюсь автором поста "10 вещей, которые я ненавижу в Git", о котором говорится в другом ответе )

113
Steve Bennett

Хотя принятый и получивший наибольшее количество голосов большой ответ, я также считаю полезным пытаться объяснить разницу только словами:

слияния

  • "Хорошо, у нас есть два разных состояния нашего хранилища. Давайте объединим их вместе. Двое родителей, один ребёнок.

перебазирования

  • "Передать изменения основной ветви (независимо от ее имени) моей функциональной ветви. Сделайте так, притворившись, что моя работа с функциями началась позже, по сути, над текущим состоянием главной ветви ".
  • "Переписать историю моих изменений, чтобы отразить это". (нужно принудительно-толкать их, потому что обычно версионирование это все о не вмешательстве в данную историю)
  • "Вероятно - если изменения, которые я совершил, не имеют ничего общего с моей работой, - история на самом деле не сильно изменится, если я посмотрю на мои коммиты diff по diff (вы также можете подумать о" патчах ")".

summary: Когда это возможно, rebase почти всегда лучше. Упрощение реинтеграции в основную ветку.

Так как? Feature ваша функциональная работа может быть представлена ​​как один большой "файл патча" (он же diff) по отношению к основной ветке, без необходимости "объяснять" несколько родители: по крайней мере двое из одного слияния, но, вероятно, еще много, если было несколько слияний. В отличие от слияний, множественные ребазы не суммируются. (еще один большой плюс)

38
Frank Nocke

Git rebase ближе к слиянию. Разница в ребазе:

  • местные коммиты временно удаляются из ветви.
  • запустить мерзавец
  • вставьте снова все ваши локальные коммиты.

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

13
Willem Franco

Для легкого понимания можно увидеть мою фигуру.

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

enter image description here

5
Nhan Cao