Почему Git не сохраняет имя ветки как часть фиксации?

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

Было много дискуссий о том, как две системы управления версиями Git и Mercurial отличаются друг от друга с точки зрения пользователя (например, В чем разница между Mercurial и Git? и http://felipec.wordpress.com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/), и основное отличие заключается в обработке ветвей. Я прочитал многие из этих обсуждений, но я продолжаю задавать себе этот вопрос:

Почему Git не сохраняет имя ветки как часть фиксации?

Я действительно не вижу достаточной причины не делать этого; это означает, что данные не могут просто исчезнуть, потому что нет ссылки (тег, ветвь, что угодно) на нее.

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

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

Ответ 1

Один из окончательных источников о ветвях для Git и Mercurial - это вопрос SO:

"Git и Mercurial - Сравнить и Контраст"

В Git ссылки (ветки, ветки удаленных следов и теги) находятся вне DAG коммитов.

(Это позволяет управлять разными пространствами имен в отношении веток, для локальных и удаленных ветвей)

У вас есть аналогичное понятие с Mercurial с ветками закладок (которые можно нажать/вытащить).

Обратите внимание, что в Git данные не будут "исчезать", потому что ссылки отсутствуют: у вас все еще есть reflog, чтобы получить эти незарегистрированные коммиты.

Почему Git не сохраняет имя ветки как часть коммита?
Я действительно не вижу достаточной причины не делать этого.

Идея состоит в том, чтобы отделить , что изменил (коммит) от почему т, т.е. из контекста изменения (имя ветки).
Так как вы можете ускоренное слияние, ветвь, фиксация из одной ветки может быть частью другого в любое время.

Вот почему Jakub Narębski поставил под сомнение дизайн Mercurial "названных ветвей" (с именами ветвей, встроенными в метаданные метаданных), особенно с глобальным пространством имен, не очень подходящим для системы управления распределенной версией.

Вы создаете ветвь, чтобы изолировать усилия по разработке (см. "Когда вы должны вступить в ветвь?"), но с помощью DVCS это усилие разработки (набор коммитов ) должны быть опубликованы под любым именем ветки. Какой локальный контекст (название ветки), который вы определили, может быть недействительным после публикации в другом репозитории Git.

Ответ 2

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

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

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

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

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

Я думаю, вы могли бы сказать, что философская разница заключается в том, что Mercurial рассматривает названные ветки как постоянные метаданные, которые дают некоторую дополнительную информацию о линии коммитов, тогда как для ветвей Git - это система без управления версиями для разработчиков сверху DAG. Mercurial также имеет эти подзаголовки (кстати, начиная с версии 1.8), но они действительно больше относятся к инструменту отслеживания и обрабатываются как ярлыки вместо ветвей.