В настоящее время наша компания использует простую модель ветвления ствола / выпуска / исправления и хотела бы узнать, какие модели ветвления лучше всего подходят для вашей компании или процесса разработки.
Рабочие процессы / модели ветвления
Ниже приведены три основных описания этого, которые я видел, но они частично противоречат друг другу или не заходят достаточно далеко, чтобы разобраться с последующими проблемами, с которыми мы столкнулись (как описано ниже). Таким образом, наша команда пока что не так уж и хороша. Вы делаете что-то лучше?
Слияние с перебазированием (запутанный против последовательной истории)
Стоит ли
pull --rebase
ждать или ждать слияния с основной линией, пока ваша задача не будет завершена? Лично я склоняюсь к слиянию, поскольку это сохраняет наглядную иллюстрацию того, на каком основании задача была начата и завершена, и я даже предпочитаюmerge --no-ff
для этой цели. Однако у него есть и другие недостатки. Также многие не осознали полезного свойства слияния - то, что оно не коммутативно (слияние ветки темы в мастер не означает слияние мастера с веткой темы).Я ищу естественный рабочий процесс
Иногда ошибки случаются, потому что наши процедуры не фиксируют конкретную ситуацию с простыми правилами. Например, исправление, необходимое для более ранних выпусков, должно, конечно, базироваться достаточно нисходящим, чтобы можно было объединить восходящий поток со всеми необходимыми ветвями (достаточно ли ясно использование этих терминов?). Однако бывает, что исправление попадает в мастер до того, как разработчик поймет, что его следует поместить дальше вниз по течению, и, если оно уже выдвинуто (еще хуже, объединено или что-то на его основе), то оставшаяся опция - выбор вишни, с связанные с этим опасности. Какие простые правила, как такие, вы используете?Также сюда входит неловкость одной тематической ветви, обязательно исключая другие тематические ветви (при условии, что они разветвлены от общей базовой линии). Разработчики не хотят завершать функцию, чтобы начать еще одно чувство, будто только что написанного кода больше нет
Как избежать возникновения конфликтов слияния (из-за cherry-pick)?
Что похоже на верный способ создать конфликт слияния - это выбрать между ветвями вишню, они никогда не смогут снова слиться? Может ли применение одной и той же фиксации к возврату (как это сделать?) В любой из ветвей разрешить эту ситуацию? Это одна из причин, по которой я не осмелюсь настаивать на в значительной степени основанном на слиянии рабочем процессе.
Как разложить на актуальные ветки?
Мы понимаем, что было бы здорово собрать законченную интеграцию из веток тем, но часто работа наших разработчиков не была четко определена (иногда так просто, как "возиться"), и если какой-то код уже вошел в раздел "Разное", это не может быть удалено оттуда снова, согласно вопросу выше? Как вы работаете с определением / утверждением / окончанием / выпуском веток вашей темы?
Правильные процедуры, такие как проверка кода и выпуск , конечно, были бы хороши.
Но мы просто не можем держать вещи достаточно распутанными, чтобы справиться с этим - какие-либо предложения? интеграционные ветки, иллюстрации?
Ниже приведен список связанных вопросов:
- Каковы хорошие стратегии, позволяющие исправлять развернутые приложения?
- Описание рабочего процесса для использования Git для собственной разработки
- Git workflow для разработки корпоративного ядра Linux
- Как вы поддерживаете код разработки и производственный код? (спасибо за этот PDF!)
- управление релизами git
- Git Cherry-pick против Merge Workflow
- Как выбрать несколько коммитов
- Как вы объединяете отдельные файлы с помощью git-merge?
- Как черри выбрать диапазон коммитов и слить в другую ветку
- ReinH Git Рабочий процесс
- рабочий процесс git для внесения изменений, которые вы никогда не вернете к началу
- Вишневый пик слияния
- Правильный рабочий процесс Git для комбинированной ОС и частного кода?
- Ведение проекта с помощью Git
- Почему нельзя изменить файл слияния Git с измененным родителем / хозяином.
- Git ветвление / перебазирование хороших практик
- Когда "git pull --rebase" доставит мне неприятности?
- Как DVCS используется в больших командах?
Также посмотрите, что Plastic SCM пишет о разработке , ориентированной на задачи , и если Plastic не ваш выбор, изучите модель ветвления nvie и его вспомогательные сценарии .
Ответы:
Наиболее тревожная особенность, которую должны осознать новые разработчики DVCS, - это процесс публикации :
Исходя из этого, вы можете соблюдать несколько правил, чтобы облегчить ваши вопросы:
Сейчас же:
Рабочие процессы / модели ветвления :
каждый рабочий процесс предназначен для поддержки процесса управления выпусками , и он адаптирован для каждого проекта.
Что я могу добавить в рабочий процесс, о котором вы упомянули: каждый разработчик не должен создавать ветвь функций, а только ветку «текущего разработчика», потому что правда в том, что разработчик часто не знает, что именно его / ее ветка создаст: один особенность, несколько (потому что это оказалось слишком сложной функцией), ни одна (потому что не была готова вовремя к выпуску), другая особенность (потому что оригинальная «трансформировалась»), ...
Только «интегратор» должен создавать официальные ветви функций в «центральном» репо, которые затем могут быть выбраны разработчиками, чтобы перебазировать / объединить ту часть своей работы, которая соответствует этой функции.
Слияние с перебазированием (запутанный против последовательной истории) :
Мне нравится мой ответ, который вы упомянули (« Описание рабочего процесса для использования git для собственной разработки »)
Я ищу естественный рабочий процесс :
для исправлений это может помочь связать каждое исправление с заявкой на отслеживание ошибок, которая помогает разработчику помнить, где (т.е. в какой ветви, то есть в отдельной ветке «для исправлений») он / она должен зафиксировать такие изменения.
Тогда хуки могут помочь защитить центральное репо от толчков от неподтвержденных исправлений ошибок или от веток, из которых не следует выдвигать. (здесь нет конкретного решения, все это необходимо адаптировать к вашей среде)
Как избежать возникновения конфликтов слияния (из-за cherry-pick)?
Как заявил Якуб Наребски в своем ответе , сбор вишни следует проводить в редких случаях, когда это необходимо.
Если ваша настройка включает в себя много вишни (то есть «это не редкость»), то что-то не так.
git revert
следует позаботиться об этом, но это не идеально.Пока ветвь еще не была распространена повсеместно, разработчик должен реорганизовать свою историю коммитов (когда он / она наконец увидит, что разработка принимает более определенную и стабильную форму) в:
Правильные процедуры, такие как проверка кода и выпуск?
Интеграция веток (в выделенной интеграции) репо может помочь разработчику:
источник
rebase --interactive --autosquash
который автоматически перемещает все коммиты с тем же началом другого сообщения коммита. Если эти коммиты используют номер билета (например), даже если исправления, связанные с этим билетом, не были сделаны последовательно в то время, автоматическое сквош позволяет быстро изменить порядок этих коммитов.Я думаю, и я могу ошибаться, что одна из вещей, которые больше всего неправильно понимают в git, это его распределенная природа. Это сильно отличает способность говорить о подрывной деятельности, хотя вы можете имитировать поведение SVN, если хотите. Проблема в значительной степени подойдет любому рабочему процессу, который хорош, но также вводит в заблуждение.
Если у меня есть правильное понимание разработки ядра (я сосредоточусь на этом), у каждого есть свой собственный git-репозиторий для разработки ядра. Существует один репозиторий, linux-2.6.git, за которым следит Торвальдс, который действует как репозиторий релизов. Люди клонируют отсюда, если они хотят начать разработку функции против ветки «релиз».
Другие репозитории делают некоторые разработки. Идея состоит в том, чтобы клонировать из linux-2.6, разветвлять столько раз, сколько вам нужно, до того момента, пока у вас не появится рабочая «новая» функция. Затем, когда все будет готово, вы можете сделать его доступным для того, кто считается доверенным, кто перетянет эту ветку из вашего репозитория в свою и объединит ее с основным потоком. В ядре linux это происходит на нескольких уровнях (доверенные лейтенанты), пока не достигнет linux-2.6.git, после чего оно становится «ядром».
Теперь вот где это сбивает с толку. Имена ветвей вообще не должны быть одинаковыми в разных репозиториях. Так что я могу
git pull origin master:vanilla-code
и получить ветку отorigin
мастера в ветке в моем хранилище под названиемvanilla-code
. Если я знаю, что происходит, это на самом деле не имеет значения - оно распространяется в том смысле, что все репозитории являются одноранговыми, а не просто используются несколькими компьютерами, такими как SVN.Итак, имея в виду все это:
head
. Релизы могут быть тегами или ветвями, а исправления, вероятно, сами по себе являются ветвями. На самом деле, я бы сделал выпуски ветвями, чтобы вы могли их исправлять.origin
следует, в вашем хранилище, вероятно , сделать еще одну ветку и объединить последнююmaster
вyourbranch
так , что кто - то может тянуть изменения с минимальными усилиями возможный. По моему опыту, очень редко возникает необходимость по-настоящему перебазировать.git add .
а затемgit commit
.Надеюсь, это поможет. Я понимаю, что VonC только что опубликовал очень похожее объяснение ... Я не могу набрать достаточно быстро!
Отредактируйте некоторые дальнейшие мысли о том, как использовать git в коммерческих условиях, так как это кажется актуальным для OP из комментариев:
product.git
, доступен нескольким старшим программистам / техническим специалистам, ответственным за то, чтобы реально заботиться о самом продукте. Они аналогичны роли сопровождающих в OSS.Так что же происходит? Ну, все в начале каждого дня извлекают данные из «восходящего» источника, то есть из репозитория релизов (который также, вероятно, будет содержать последние материалы из предыдущих дней разработки). Каждый делает это напрямую. Это пойдет на ветку в их хранилище, возможно, под названием «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. По сути, каждый имеет доступ к коммитам, но только локально. Это доступ к репозиторию, и какой репозиторий вы определяете как репозиторий релиза, который позволяет вам использовать иерархию.
источник
Модель, которую я использовал с хорошими результатами, выглядит следующим образом:
«Благословенный» репо, который все толкают и тянут в / из, в основном топология клиент-сервер.
Там нет главной ветки, поэтому ни один разработчик не может вставить любой код в «mainline».
Все разработки происходят по тематическим веткам. Мы называем имена в пространстве имен, чтобы легко определить, кто за это отвечает: jn / newFeature или jn / issue-1234
Существует также соотношение между ветвями и канбан / скрам-картами на доске.
Чтобы освободить ветку, ее подталкивают к благословенному репо, и канбан-карта перемещается в готовое для просмотра.
Затем, если ветка принята рецензией, она является кандидатом на выпуск.
Выпуск происходит, когда набор принятых ветвей объединяется и помечается номером версии.
При добавлении нового тега в благословенное хранилище появляется новая возможная база для новых функций.
Чтобы избежать конфликтов слияния, разработчикам предлагается обновить (слить) свои невыпущенные ветви до последней версии выпуска.
источник
Лично я стараюсь хранить только готовый к выпуску код в основной ветке.
Когда я работаю над новой функцией или исправлением ошибки, я делаю это в ветке. Я тоже юнит-тест в ветке. Если все работает хорошо, только тогда я объединяю / перебазирую обратно в мастер.
Я также пытаюсь использовать общие правила именования веток, такие как:
источник