Гибкое vs статическое ветвление (Git vs Clearcase/Accurev)

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

Но в других системах, таких как Clearcase или Accurev, вы можете указать, как ветки заполняются каким-то механизмом наследования: я имею в виду, что с помощью Clearcase, используя config_spec, вы можете сказать: "Получить все файлы, измененные в ветки/основной/issue001, а затем продолжить работу с главными или с этой конкретной базой".

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

Не пропустите это при использовании Git? Можете ли вы перечислять сценарии, где это наследование является обязательным?

Спасибо

Обновить. Пожалуйста, прочитайте ответ VonC ниже, чтобы на самом деле сосредоточить мой вопрос. Как только мы согласны, что "линейное хранилище" и SCM на основе DAG имеют разные возможности, мой вопрос: , которые являются реальными сценариями жизни (особенно для компаний, превышающих OSS), где линейность может делать вещи, недоступные для DAG? Стоят ли они?

Ответы

Ответ 1

Чтобы понять, почему Git не предлагает своего рода "механизм наследования" (не связанный с фиксацией), вы должны сначала понять один из основные понятия этих SCM (Git по сравнению с ClearCase, например)

  • ClearCase использует хранилище линейной версии: каждая версия элемента (файла или каталога) связана в прямой линейной связи с предыдущей версией того же элемента.

  • Git использует DAG - Направленный ациклический график: каждая "версия" файл фактически является частью глобального набора изменений в дереве, которое является частью коммита. Предыдущая версия должна быть найдена в предыдущем коммите, доступном через один направленный путь ациклического графа.

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

Филиал fork в линейной истории заданная версия для данного правила выбора (все остальные правила выбора до этого один по-прежнему применяется, следовательно, эффект "наследования" )

В DAG коммит представляет все "наследование", которое вы когда-либо получите; нет "кумулятивного" выбора версий. На этом графике есть только один путь, чтобы выбрать все файлы, которые вы увидите в этой точке (фиксация).
В этом графе ветка - это просто новый путь.

Чтобы применить, в Git, некоторые другие версии, вы должны либо:

  • объедините в свою ветку какую-нибудь другую фиксацию (например, в Git pull ", указанную ответ stsquad) или
  • переустановите свою ветку (как Грег упоминает)

Но поскольку Git является SCM на основе DAG, он всегда будет приводить к новой фиксации.

То, что вы "теряете" с помощью Git, является своего рода "композицией" (когда вы выбираете разные версии с разными последовательными правилами выбора), но это не было бы практичным в D VCS (как в разделе "Distributed" ): при создании ветки с помощью Git вам нужно сделать это с начальной точкой и четко определенным контентом и легко реплицироваться в другие репозитории.

В чисто центральном VCS вы можете определить свое рабочее пространство (в ClearCase, ваше "представление", либо моментальный снимок, либо динамический) с любыми правилами, которые вы хотите.


unknown-google добавляет комментарий (и в его вопрос выше):

Итак, как только мы увидим, что две модели могут достигать разных целей (линейный против DAG), мой вопрос: каковы сценарии реальной жизни (особенно для компаний, которые больше, чем OSS), где линейные могут делать вещи, недоступные для DAG? Стоят ли они того?

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

Рассмотрим эту "конфигурационную спецификацию" (т.е. "спецификацию конфигурации" для правил выбора с помощью ClearCase):

element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch

Он выбирает все файлы с меткой "aLabel2" (и оттуда оттуда), за исключением тех, которые помечены как "aLabel3" - и оттуда оттуда - (поскольку это правило предшествует тому, что упоминается "aLabel2" ).

Стоит ли это?

Нет.

Собственно, UCM-вкус ClearCase (методология Унифицированное управление конфигурацией ", включенная в продукт ClearCase, и представляющая все" "лучшие практики", выведенные из базового использования ClearCase, не позволяют это по причинам простоты. Набор файлов называется "компонентом", и если вы хотите разветкиться для данной метки (известной как "базовая линия" ), это будет переведено следующим образом:

element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch

Вам нужно выбрать начальную точку one (здесь, 'aLabel3') и перейти оттуда. Если вы хотите также файлы из "aLabel2", вы сделаете слияние из всех файлов "aLabel2" с файлами в "myNewBranch".

Это "упрощение", которое вам не нужно делать с помощью DAG, где каждый node графа представляет собой уникальную "начальную точку" для ветки, независимо от того, что представляет собой набор файлов.

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

Общая цель состоит в обосновании "согласованных операций управления версиями, применяемых к когерентному компоненту". "Когерентный" набор файлов - один в четко определенном когерентном состоянии:

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

Это легко сделать в системе DAG; это может быть сложнее в линейной системе (особенно с "Base ClearCase", где "спецификация конфигурации" может быть сложной), но она применяется с помощью методологии UCM этого же линейного инструмента.

Вместо того, чтобы достичь этой "композиции" с помощью "трюка правила частного отбора" (с помощью ClearCase, некоторых правил выбора порядка), вы достигаете его только с помощью операций VCS (rebase или merge), которые оставляют четкую трассу для всех (в отличие от конфигурации конфигурации, частной для разработчика, или совместно используемой среди некоторых, но не всех разработчиков). Опять же, он обеспечивает чувство согласованности, , а не "динамическую гибкость", что вам может быть трудно воспроизвести позже.

Это позволяет вам покинуть область VCS (Система управления версиями) и войти в область SCM (Управление конфигурацией программного обеспечения), в основном касающийся " воспроизводимости". И это (возможности SCM) может быть достигнуто с помощью VCS на основе линейных или DAG.

Ответ 2

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

Ответ 3

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

git -t -b my_branch origin/master

И тогда будущий "git pull" будет автоматически объединять начало/мастер в ваш рабочая ветвь. Затем вы можете использовать "git cherry -v origin/master", чтобы увидеть какая разница. Вы можете использовать "git rebase", прежде чем публиковать свои изменения, чтобы очистить историю, но вы не должны использовать rebase один раз ваша история является общедоступной (т.е. другие люди следуют за этой веткой).

Ответ 4

Что касается схемы наследования, используемой accurev: GIT пользователи, вероятно, "получат" все это, когда посмотрите на git -flow (см. также: http://github.com/nvie/gitflow и http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/)

Эта GIT ветвящаяся модель более или менее (вручную/с помощью инструмента git -flow), который accurev делает из коробки автоматически и с большим графическим интерфейсом поддержка.

Итак, кажется, что GIT может делать то, что делает accurev. Поскольку я никогда не использовал git/git-flow изо дня в день, я не могу сказать, как это работает, но выглядит многообещающим. (Минимальная поддержка GUI: -)

Ответ 5

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

"Можете ли вы перечислить сценарии, где это наследование является обязательным?"

Я не буду говорить, что это необходимо, потому что вы можете решить проблему с помощью инструмента, который у вас есть, и может быть правильным решением для вашей среды. Я полагаю, что это скорее процесс, чем сам инструмент. Убедитесь, что ваш процесс согласован, а также позволяет вам вернуться во времени, чтобы воспроизвести любой промежуточный шаг/состояние - цель, а плюс заключается в том, что инструмент позволяет вам запускать ваш процесс и SCMP как можно более безболезненно

Один сценарий, который я вижу, удобен в том, чтобы иметь это поведение наследования и использовать силу спецификации конфигурации, когда вы хотите, чтобы ваш набор изменений " изолированный" сопоставлен с задачей (devtask, CR, SR или что-то другое определяет цель/область вашего набора изменений)

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

Будучи пуристом, которому нужно совершить/объединить/переустановить, чтобы иметь "определенную начальную точку", я предполагаю, что это будет " pollute" в вашей ветке, и в итоге вы измените свои изменения + другие изменения в ваш филиал/набор изменений.

Когда/Где эта изоляция полезна? Точки ниже могут иметь смысл только в контексте компаний, которые проводят CMM и некоторые сертификаты ISO, и могут не представлять интереса для других компаний или OSS

  • Будучи действительно придирчивым, вы можете точно подсчитать строки кода (добавленные/измененные/удаленные) набора изменений, соответствующие одному разработчику, который впоследствии используется как один вход для оценки кода и усилий.

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

В больших проектах с несколькими командами и разработчиками +500, активно работающими одновременно с одним и тем же базовым кодом (где графические деревья версий отдельных элементов выглядят как грязная запутанная сеть с несколькими линиями загрузки, по одному для каждого большого клиента или по одной для каждой технологии ) большие конфигурации конфигурации, используя состав нескольких градусов в глубину, сделали это количество людей без проблем, чтобы адаптировать один и тот же продукт/систему (базовый код) к разным целям. Используя эту конфигурационную спецификацию, динамически давали каждой команде или подразделению разные взгляды на то, что им нужно, и откуда они нуждаются в ветке (каскадирование в нескольких случаях) без необходимости создания промежуточных ветвей интеграции или постоянного слияния и перезагрузки всех бит, с которого вам нужно начать. Код из той же задачи/цели - разветвление разных ярлыков, но имело смысл. (Вы можете утверждать здесь "известную базовую линию" как принцип SCM, но простые ярлыки, предусмотренные в письменном плане SCM, сделали работу) Должно быть возможным решить эту проблему с помощью GIT (я думаю, что это не динамический способ), но я нахожу очень трудным изображение без этого поведения "наследования". Я думаю, что точка, упомянутая VonC, "если ветвь, все ее файлы будут отходить от одной и той же уникальной отправной точки", была нарушена здесь, но рядом с ней была хорошо документирована SCMP, я помню, что для этого были серьезные деловые причины.

Да, создание этих конфигурационных спецификаций, о которых я упоминал выше, не было бесплатным, вначале там, где 4-5 хорошо оплачиваемых людей за SCM, но позже были сокращены автоматическими сценариями, которые спрашивали вас, что вы хотите на условиях ярлыков/веток/функции и напишет CS для вас.

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

Таким образом, здесь может быть один вывод, только если ваш проект достаточно большой/достаточно сложный (и вы можете позволить себе SC Managers по жизни проекта:)), тогда вы только начнете думать, если вам нужно "наследование" "поведение или действительно универсальный инструмент, иначе вы перейдете непосредственно к свободному инструменту и уже позаботитесь о согласованности с вами SCM ... но в инструменте SCM могут быть другие факторы, которые могут заставить вас придерживаться одного или другого... читайте дальше..

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

Я должен добавить здесь, что мы используем "good-ol CC", а не UCM. Полностью согласен с VonC по хорошей методологии, позволяющей "направлять" гибкость в сторону более согласованной конфигурации. Хорошо, что CC довольно гибкий, и вы можете найти (не без каких-либо усилий) хороший способ иметь связную вещь, в то время как в других SCM у вас может быть это бесплатно. Но, например, здесь (и в других местах, которые я работал с CC) для проектов на C/С++ мы не можем позволить себе цену отсутствия функции winkin (повторное использование объектов Derive), которые сокращают время компиляции X раз. Можно утверждать, что, имея лучший дизайн, более развязанный код и оптимизируя Makefiles, можно уменьшить необходимость компиляции всего этого, но есть случаи, когда вам нужно собирать всего зверя много раз в день, и совместное использование DO сохраняет кучи времени/денег. Где я сейчас, мы стараемся использовать как можно больше свободного инструмента, и я думаю, что мы избавимся от CC, если найдем более дешевый или бесплатный инструмент, реализующий функцию winkin.

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

мои 2 цента

Ответ 6

Заметили ли вы, что вы можете проверить специфицированные версии файлов с помощью GIT тоже?

Просто используйте это:

git checkout [< tree-ish >] [--] < paths >

Как и в случае конфигурации, любая существующая версия файла (пути) может быть загружена в рабочую строку. Цитата из git -checkout docs:

Следующая последовательность проверяет основную ветвь, возвращает Makefile в две версии назад, удаляет hello.c по ошибке и возвращает ее из индекса:

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            

Ответ 7

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

Наследование (более поздние версии как дочерние элементы более ранних) позволяет изменять потоки дочерних элементов в дочерних потоках без каких-либо действий (если не требуется слияние, и в этом случае оно проявляется как глубокое перекрытие, что хорошо способный видеть).

Это звучит здорово, и на практике это происходит, когда все задействованные потоки относительно похожи. Мы используем эту модель для потоков уровня обновления и пакета обновления ниже определенного выпуска. (Это на самом деле немного сложнее, чем для нас, но это общая идея.)

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

Мы первоначально использовали модель наследования для всех выпусков, где позже были дочерними из ранних. Это хорошо работало некоторое время, но со временем стало неуправляемым. Основные архитектурные различия в выпусках, которые неизбежно наследуют, меняют плохую идею. Да, вы можете поместить моментальный снимок между блоками наследования, но затем все изменения нужно нажимать вручную, и единственное реальное различие между потоками parent-snapshot-child и параллельного ненаследуемого состоит в том, что весь графический просмотр потока постоянно толкает вниз и справа, что является PITA.

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

Ответ 8

ClearCase без MultiSite представляет собой единый репозиторий, но Git распространяется. ClearCase фиксируется на уровне файла, но Git фиксируется на уровне репозитория. (Это последнее различие означает, что исходный вопрос основан на недоразумении, как указано в других сообщениях здесь.)

Если это различия, о которых мы говорим, то я думаю, что "линейный" и "DAG" - это путаный способ отличить эти системы SCM. В ClearCase все версии для файла называются файловой версией "tree", но на самом деле это ориентированный ациклический граф! Реальная разница с Git заключается в том, что на каждый файл существуют ClearGase DAG. Поэтому я считаю ошибочным ссылаться на ClearCase как на не-DAG и Git как на DAG.

(BTW ClearCase обновляет свои каталоги аналогично своим файлам, но это другая история.)

Ответ 9

Я не уверен, что вы просите что-нибудь, но вы демонстрируете, что потоки Accurev - это разные инструменты, чем ветки Git (или SVN). (Я не знаю Clearcase.)

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

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

Различные инструменты хороши для разных целей; полезно спросить, для чего каждый подходит.