Какая разница между git mergeа git rebase?
Какая разница между git mergeа git rebase?
Ответы:
Предположим , что первоначально было 3 фиксаций, A, B, C:

Затем разработчик Dan создал commit D, а разработчик Ed создал commit E:

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

Оба коммита Dи Eвсе еще здесь, но мы создаем коммит слияния, Mкоторый наследует изменения от обоих Dи E. Тем не менее, это создает форму ромба , что многие люди находят очень запутанным.
ПЕРЕПИСКА :

Мы создаем коммит R, фактическое содержимое файла которого совпадает с Mвышеизложенным коммитом . Но мы избавляемся от коммита E, как будто его никогда не существовало (обозначено точками - линия исчезновения). Из-за этого уничтожения он Eдолжен быть локальным для разработчика Ed и никогда не должен передаваться в какой-либо другой репозиторий. Преимущество перебазирования в том, что форма ромба избегается, а история остается красивой прямой - большинству разработчиков это нравится!
git mergeне перемежает коммиты (но это может выглядеть так, глядя на них git log). Вместо этого git mergeсохраняет обе истории развития Дэна и Эда в неизменном виде, как это было видно с каждой точки зрения за раз. git rebaseПохоже, что Дэн работал над этим первым, а Эд последовал за ним. В обоих случаях (слияние и перебазирование) фактическое результирующее дерево файлов абсолютно идентично.
Мне очень нравится этот отрывок из 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. без цензуры в оригинале
Лично я не нахожу стандартную технику построения диаграмм очень полезной - стрелки всегда, кажется, указывают неправильный путь для меня. (Они обычно указывают на «родителя» каждого коммита, который в конечном итоге оказывается назад во времени, что странно).
Чтобы объяснить это словами:
По причинам, которые я не понимаю, инструменты 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», о котором говорится в другом ответе )
Хотя принятый и получивший наибольшее количество голосов отличный ответ, я также считаю полезным попытаться объяснить разницу только словами:
слияние
перебазироваться
Резюме: когда это возможно, ребаз почти всегда лучше. Упрощение реинтеграции в основную ветку.
Потому что? Feature ваша функциональная работа может быть представлена в виде одного большого «файла патча» (он же diff) по отношению к основной ветке, без необходимости «объяснять» нескольких родителей: по крайней мере, два из одного слияния, но, вероятно, еще много, если есть было несколько слияний. В отличие от слияний, множественные ребазы не суммируются. (еще один большой плюс)
Git rebase ближе к слиянию. Разница в ребазе:
Это означает, что все ваши локальные коммиты перемещаются в конец после всех удаленных коммитов. Если у вас есть конфликт слияния, вы должны решить его тоже.
Я нашел одну действительно интересную статью о git rebase vs merge , думал поделиться ею здесь