Какие модели веток Git работают для вас? - PullRequest
364 голосов
/ 12 апреля 2010

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

  1. Рабочие процессы / модели ветвления

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

  2. Слияние с перебазированием (запутанный против последовательной истории)

    Нужно ли pull --rebase или дождаться слияния с основной линией, пока ваша задача не будет завершена? Лично я склоняюсь к слиянию, поскольку это сохраняет наглядную иллюстрацию того, на каком основании задача была начата и завершена, и я даже предпочитаю merge --no-ff для этой цели. Однако у него есть и другие недостатки. Также многие не осознали полезного свойства слияния - то, что оно не является коммутативным (объединение ветки темы в мастер не означает слияние мастера в ветку темы).

  3. Я ищу естественный рабочий процесс

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

  4. Как избежать возникновения конфликтов слияния (из-за вишневого пика)?

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

  5. Как разложить на тематические ветки?

    Мы понимаем, что было бы замечательно собрать законченную интеграцию из веток тем, но часто работа наших разработчиков четко не определена (иногда так просто, как "возиться"), и если какой-то код уже вошел в "разное" "тема, это не может быть вынесено оттуда снова, в соответствии с вопросом выше? Как вы работаете с определением / утверждением / окончанием / выпуском тематических веток?

  6. Правильные процедуры, такие как проверка кода и выпуск , конечно, были бы хороши.

    Но мы просто не можем держать вещи достаточно распутанными, чтобы справиться с этим - какие-либо предложения? интеграционные ветки, иллюстрации?

Ниже приведен список связанных вопросов:

Также проверьте, что Plastic SCM пишет о управляемой задачами разработке , и если Plastic не ваш выбор, изучите модель ветвления nvie и его поддерживающие сценарии .

Ответы [ 4 ]

89 голосов
/ 12 апреля 2010

Самая тревожная особенность, которую должны осознать новые разработчики DVCS, - это процесс публикации :

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

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

  • перебазирует ветвь, только если она не была сдвинута (не сдвинута с момента последней перебазировки)
  • только толчок к голому репо (обязательно с Git1.7)
  • следуйте Советы Линуса по ребазам и слияниям

Сейчас:

Рабочие процессы / модели ветвления :

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

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

Слияние с перебазированием (запутанная и последовательная история) :

Мне нравится мой ответ, который вы упоминаете (" Описание рабочего процесса для использования git для собственной разработки ")

Я ищу естественный рабочий процесс :

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

Как избежать возникновения конфликтов слияния (из-за cherry-pick)?

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

Будет ли применяться тот же коммит в обратном порядке (как это сделать?)

git revert должны позаботиться об этом, но это не идеально.

Как разложить на тематические ветки?

Пока ветвь еще не была распространена повсеместно, разработчик должен реорганизовать свою историю коммитов (когда он / она наконец увидит, что разработка принимает более определенную и стабильную форму) в:

  • несколько веток, если необходимо (одна с четко определенной функцией)
  • согласованный набор коммитов в пределах одной ветви (см. Trimming Git Checkins )

Надлежащие процедуры, такие как проверка кода и выпуск?

Интеграция веток (в выделенной интеграции) репо может помочь разработчику:

  • перебазировать его / ее разработку поверх ветки удаленной интеграции (pull --rebase)
  • решить локально
  • подтолкнуть разработку к этому репо
  • уточните у интегратора, что не приводит к путанице;)
21 голосов
/ 12 апреля 2010

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

Если я правильно понимаю разработку ядра (я сосредоточусь на этом), у каждого есть свой собственный git-репозиторий для разработки ядра. Существует один репозиторий, linux-2.6.git, за которым следит Торвальдс, который действует как репозиторий релизов. Люди клонируют отсюда, если они хотят начать разработку функции против ветки "release".

Другие репозитории занимаются разработкой. Идея состоит в том, чтобы клонировать из linux-2.6, разветвлять столько раз, сколько захотите, до такой степени, что вы получите работающую «новую» функцию. Затем, когда все будет готово, вы можете сделать его доступным для кого-то, кому доверяют, который перетянет эту ветку из вашего хранилища в свои и объединит ее с основным потоком. В ядре linux это происходит на нескольких уровнях (доверенные лейтенанты), пока не достигнет linux-2.6.git, после чего оно становится «ядром».

Теперь вот где это сбивает с толку. Имена ветвей вообще не должны быть одинаковыми для всех репозиториев. Поэтому я могу git pull origin master:vanilla-code и получить ветку от мастера origin в ветке в моем хранилище под названием vanilla-code. Если я знаю, что происходит, это на самом деле не имеет значения - оно распространяется в том смысле, что все репозитории являются одноранговыми, а не просто используются несколькими компьютерами, такими как SVN.

Итак, учитывая все это:

  1. Я думаю, что каждый программист должен делать то, что они делают. Все, что вам нужно, это центральный репозиторий для управления выпусками и т. Д. Магистраль может быть head. Релизы могут быть тегами или ветвями, а исправления, вероятно, сами по себе являются ветвями. На самом деле, я бы, вероятно, делал релизы как ветки, чтобы вы могли их исправлять.
  2. Я бы слился, а не перебазировал. Если, например, вы берете репозиторий, клонируете его, разветвляетесь и делаете какое-то dev, затем извлекаете из своего origin, который вы должны, в своем репозитории, вероятно, сделайте еще одну ветку и объедините последнюю master в yourbranch, чтобы кто-то еще может потянуть ваши изменения с минимальными усилиями, насколько это возможно. По моему опыту, очень редко возникает необходимость по-настоящему перебазировать.
  3. Я думаю, что это случай понимания того, как работает Git и что он может делать. Это требует времени и много хорошего общения - я действительно начал понимать, что происходит, когда начал использовать git с другими разработчиками и даже сейчас, в некоторых вещах, в которых я не уверен.
  4. Конфликты слияния полезны. Я знаю, я знаю, вы хотите, чтобы все это работало, но факт - изменения кода, и вам нужно объединить результаты во что-то, что работает. Конфликты слияний на самом деле просто больше программирования. Я никогда не находил простого объяснения, что с ними делать, поэтому вот оно: обратите внимание на файлы, которые имеют конфликты слияния, перейдите и измените их на то, что они должны быть, git add ., а затем git commit.
  5. Однако это устраивает. Как я уже сказал, каждый пользовательский репозиторий git является своим собственным, и имена веток не обязательно должны быть одинаковыми . Например, если у вас был промежуточный репозиторий, вы могли бы применить схему именования, но это не требуется для каждого разработчика, только в репозитории релизов.
  6. Это стадия слияния. Вы объединяетесь только с ветвями релиза и т. Д., Если считаете, что код проверяется / проходит проверку качества.

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

Редактировать некоторые дальнейшие мысли о том, как использовать git в коммерческих условиях, поскольку это представляется актуальным для ФП из комментариев:

  • Репозиторий релизов, назовем его product.git, доступен нескольким старшим программистам / техническим специалистам, ответственным за фактическое наблюдение за самим продуктом.Они аналогичны роли сопровождающих в OSS.
  • Эти программисты, вероятно, также частично ведут разработку новых версий, поэтому они могут также кодировать себя и поддерживать репозитории varios.Они могут управлять промежуточными репозиториями для действительно новых функций, а также могут иметь свои собственные репозитории.
  • Ниже находятся программисты, отвечающие за разработку отдельных битов.Например, кто-то может нести ответственность за работу интерфейса.Поэтому они управляют репозиторием UI.git.
  • Ниже приведены настоящие программисты, которые разрабатывают эти функции в качестве своей повседневной работы.

Так что же происходит?Ну, все в начале каждого дня извлекают данные из «восходящего» источника, то есть из репозитория релизов (который также, вероятно, будет содержать последние материалы из предыдущих дней разработки).Каждый делает это напрямую.Это пойдет на ветку в их хранилище, возможно, под названием «master» или, может быть, если вы меня назвали «последним».Затем программист выполнит некоторую работу.Эта работа может быть чем-то, в чем они не уверены, поэтому они делают ветку, делают работу.Если это не работает, они могут удалить ветку и вернуться назад.Если это произойдет, им придется объединиться с основной ветвью, над которой они сейчас работают.Мы скажем, что это программист пользовательского интерфейса, работающий над latest-ui, поэтому он делает git checkout latest-ui, а затем git merge abc-ui-mywhizzynewfeature.Затем он говорит своему техническому руководителю (руководству по пользовательскому интерфейсу): «Я выполнил такую ​​задачу, вытащил меня».Таким образом, пользовательский интерфейс делает git pull user-repo lastest-ui:lastest-ui-suchafeature-abc.Затем ведущий пользовательского интерфейса смотрит на него в этой ветке и говорит, что на самом деле это очень хорошо, я объединю его с ui-latest.Затем он может сказать всем, кто ниже его, чтобы он брал у него ветки ui-latest или любое другое имя, которое они им дали, и разработчики изучают эту функцию.Если команда довольна, лидер UI может попросить, чтобы лидер тестирования вытащил его и объединил изменения.Это распространяется на всех (ниже по течению от изменений), которые тестируют его и представляют отчеты об ошибках и т. Д. Наконец, если функция проходит тестирование и т. Д., Один из главных технических руководителей может объединить ее с текущей рабочей копией программы, и в этот моментвсе изменения затем распространяются обратно вниз.И так далее.

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

9 голосов
/ 11 октября 2011

Модель, которую я использовал с хорошими результатами, выглядит следующим образом:

«Благословенное» репо, которое все толкают и тянут в / из, в основном топология клиент-сервер.

Там нет главной ветки, поэтому ни один разработчик не может вставить любой код в "mainline".

Все события происходят по тематическим веткам. Мы называем имена в пространстве имен, чтобы легко определить, кто за это отвечает: jn / newFeature или jn / issue-1234

Существует также соотношение «один к одному» между ветками и канбан / скрам-картами на доске.

Чтобы освободить ветку, ее подталкивают к благословенному репо, и канбан-карта перемещается в готовое для просмотра.

Тогда, если ветка принята рецензией, она является кандидатом на выпуск.

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

При добавлении нового тега в благословенное хранилище появляется новая возможная база для новых функций.

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

2 голосов
/ 21 декабря 2012

Лично я стараюсь хранить только готовый к выпуску код в основной ветке.

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

Я также пытаюсь использовать общие правила именования ветвей, такие как:

  • багфикс / recursive_loop
  • багфикс / sql_timeout
  • функция / new_layout
  • функция / расширенный_поиск
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...