Почему git выполняет ускоренное слияние по умолчанию? - PullRequest
628 голосов
/ 17 мая 2010

Исходя из Mercurial, я использую ветки для организации функций. Естественно, я хочу видеть этот рабочий процесс и в моей истории.

Я начал свой новый проект, используя git, и закончил свою первую функцию. При объединении этой функции я понял, что git использует ускоренную перемотку вперед, т. Е. Он применяет мои изменения непосредственно к основной ветви, если это возможно, и забывает о моей ветви.

Так что думать о будущем: я единственный, кто работает над этим проектом. Если я использую подход по умолчанию в git (ускоренное слияние), моя история приведет к созданию одной гигантской основной ветви. Никто не знает, что я использовал отдельную ветку для каждой функции, потому что в итоге у меня будет только эта гигантская основная ветка. Разве это не выглядит непрофессионально?

По этой причине я не хочу быстрого слияния и не могу понять, почему это по умолчанию. Что в этом хорошего?

Ответы [ 2 ]

707 голосов
/ 17 мая 2010

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

Предупреждение : Не ускоренная перемотка также имеет потенциальные побочные эффекты. Пожалуйста, просмотрите https://sandofsky.com/blog/git-workflow.html, избегайте 'no-ff' с его "фиксацией контрольной точки", которая нарушает пополам или вину, и тщательно продумайте, должен ли это быть подход по умолчанию для master.

alt text
(от nvie.com , Винсент Дриссен , сообщение " Успешная модель ветвления Git ")

Включение готовой функции при разработке

Готовые функции могут быть объединены в ветку разработки, чтобы добавить их в следующий выпуск:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

Флаг --no-ff заставляет объединение всегда создавать новый объект фиксации, даже если объединение может быть выполнено с ускоренной перемоткой вперед. Это позволяет избежать потери информации об историческом существовании ветви компонента и объединяет все коммиты, которые вместе добавили функцию.

Якуб Наребски также упоминает config merge.ff:

По умолчанию Git не создает дополнительный коммит слияния при слиянии коммита, который является потомком текущего коммита. Вместо этого верхушка текущей ветви быстро передается.
Когда установлено значение false, эта переменная указывает Git создать дополнительный коммит слияния в таком случае (эквивалентно предоставлению опции --no-ff из командной строки).
При значении «only» разрешены только такие ускоренные слияния (эквивалентно предоставлению опции --ff-only из командной строки).


Быстрая перемотка вперед по умолчанию, потому что:

  • недолговечные ветки очень легко создавать и использовать в Git
  • краткосрочные ветви часто изолируют много коммитов, которые могут быть свободно реорганизованы в этой ветви
  • эти коммиты на самом деле являются частью основной ветви: после реорганизации основная ветвь быстро перенаправляется для их включения.

Но если вы ожидаете итеративный рабочий процесс в одной ветви темы / компонента (т. Е. Я объединяю, затем я возвращаюсь к этой ветви функции и добавляю еще несколько коммитов), тогда полезно включить только объединение в основную ветку вместо всех промежуточных коммитов ветви возможностей.

В этом случае вы можете настроить этот тип конфигурационного файла :

[branch "master"]
# This is the list of cmdline options that should be added to git-merge 
# when I merge commits into the master branch.

# The option --no-commit instructs git not to commit the merge
# by default. This allows me to do some final adjustment to the commit log
# message before it gets commited. I often use this to add extra info to
# the merge message or rewrite my local branch names in the commit message
# to branch names that are more understandable to the casual reader of the git log.

# Option --no-ff instructs git to always record a merge commit, even if
# the branch being merged into can be fast-forwarded. This is often the
# case when you create a short-lived topic branch which tracks master, do
# some changes on the topic branch and then merge the changes into the
# master which remained unchanged while you were doing your work on the
# topic branch. In this case the master branch can be fast-forwarded (that
# is the tip of the master branch can be updated to point to the tip of
# the topic branch) and this is what git does by default. With --no-ff
# option set, git creates a real merge commit which records the fact that
# another branch was merged. I find this easier to understand and read in
# the log.

mergeoptions = --no-commit --no-ff

ОП добавляет в комментариях:

Я вижу некоторый смысл в перемотке вперед для [недолговечных] ветвей, но если сделать это действием по умолчанию, это означает, что git предполагает, что вы ... часто имеете [недолговечные] ветки. Разумные

Jefromi отвечает:

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

Для меня короткоживущая ветвь - это ветвь, которую я создаю, чтобы упростить определенную операцию (перебазирование, скорее всего, или быстрое исправление и тестирование), а затем сразу же удалить, как только я сделано.
Это означает, что вероятно должно быть включено в ветку темы, которую она разветвляет из , и ветка темы будет объединена в одну ветку Никто не должен знать, что я сделал внутри, чтобы создать серию коммитов, реализующих данную функцию.

В общем, я добавляю:

это действительно зависит от вашего рабочего процесса разработки :

  • если он линейный, имеет смысл одна ветвь.
  • Если вам необходимо изолировать объекты и работать с ними в течение длительного периода времени и многократно объединять их, несколько ветвей имеют смысл.

См. " Когда следует переходить? "

На самом деле, когда вы рассматриваете модель ветки Mercurial, в ее основе лежит одна ветка на репозиторий (даже если вы можете создать анонимные главы, закладки и даже именованные ветви )
См. «Мерзавец и мерзавец - сравнение и контраст» .

Mercurial, по умолчанию, использует анонимные легкие кодовые строки, которые в своей терминологии называются «заголовками».
Git использует легкие именованные ветви с инъективным отображением для отображения имен ветвей в удаленном репозитории на имена ветвей удаленного отслеживания.
Git «вынуждает» вас называть ветви (ну, за исключением одной неназванной ветви, которая называется « detached HEAD »), но я думаю, что это работает лучше с такими тяжелыми ветвями, как как рабочий процесс ветки темы, означающий несколько ветвей в одной парадигме репозитория.

41 голосов
/ 31 мая 2013

Позвольте мне немного подробнее рассказать о VonC очень подробном ответе :


Во-первых, если я правильно помню, тот факт, что Git по умолчанию не создает коммитов слияния в случае ускоренная перемотка вперед , произошел из-за того, что одно-ветвление "равно" репозитории ", где взаимное извлечение используется для синхронизации этих двух репозиториев (рабочий процесс, который вы можете найти в качестве первого примера в документации большинства пользователей, включая" ​​Руководство пользователя Git "и" Контроль версий по примеру "). В этом случае вы не используете pull для объединения полностью реализованной ветви, вы используете ее, чтобы не отставать от другой работы. Вы не хотите иметь эфемерный и неважный факт, когда вы делаете синхронизацию, сохраненную и сохраненную в репозитории, сохраненную для будущего.

Обратите внимание, что полезность ветвей функций и наличия нескольких ветвей в одном репозитории появилась позже, с более широким использованием VCS с хорошей поддержкой слияний и с попыткой различных рабочих процессов на основе слияний. Вот почему, например, Mercurial изначально поддерживал только одну ветвь для каждого хранилища (плюс анонимные советы для отслеживания удаленных веток), как это было видно в более старых редакциях «Mercurial: Полное руководство».


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

НТН

...