Гибкое и статическое ветвление (Git против Clearcase / Accurev) - PullRequest
31 голосов
/ 18 апреля 2009

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

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

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

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

Спасибо

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

Ответы [ 9 ]

30 голосов
/ 19 апреля 2009

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

Стоит ли оно того?

номер

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

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

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

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

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

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

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

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

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

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

3 голосов
/ 18 апреля 2009

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

git -t -b my_branch origin / master

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

3 голосов
/ 18 апреля 2009

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

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

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

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

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

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

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

2 голосов
/ 11 ноября 2010

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

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

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

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

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

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            
2 голосов
/ 19 октября 2010

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

мои 2 цента

2 голосов
/ 10 сентября 2010

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

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

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

1 голос
/ 30 ноября 2009

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

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

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

0 голосов
/ 18 апреля 2009

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

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

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

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

...