Следует отметить, что очень легко определить ваши собственные тривиальные обертки для добавления контейнеризованных версий.
Например:
template<typename Container, typename Func>
Func for_each(Container& c, Func f) {
return std::for_each(c.begin(), c.end(), f);
}
Теперь вы можете сделать простой вызов вы хотите. Нет никакой двусмысленности, потому что ваши обертки не находятся в пространстве имен std. Вы можете определить перегрузки, которые принимают const Container & amp ;. Если вам нужны версии, которые вызывают методы итератора C ++-11 const (например, cbegin ()), я думаю, вам нужно будет назвать оболочку по-разному. Я использую for_each_const.
Самая тревожная особенность, которую должны осознать новые разработчики DVCS, касается процесса публикации:
Исходя из этого, вы можете соблюдать несколько правил, чтобы облегчить ваши вопросы:
Теперь:
Рабочие процессы / модели ветвления:
каждый рабочий процесс существует для поддержки процесса управления релизами, и это индивидуально для каждого проекта.
Что я могу добавить к упомянутому вами рабочему процессу: каждый разработчик не должен создавать ветку фич, только ветку "current dev", потому что правда в том, что разработчик часто не знает, что именно произведет его/ее ветка: одну фичу, несколько (потому что она оказалась слишком сложной), ни одной (потому что не готова к релизу), еще одну фичу (потому что первоначальная "переродилась"),...
Только "интегратор" должен создавать официальные ветки фич в "центральном" репозитории, которые затем могут быть доступны разработчикам для переделки/слияния той части их работы, которая соответствует этой фиче.
Слияние vs ребазинг (запутанная vs последовательная история):
Мне нравится мой ответ, который вы упомянули ("Описание рабочего процесса использования git для внутренней разработки")
Я ищу естественный рабочий процесс:
для исправлений, это может помочь связать каждое исправление с тикетом из баг-трекинга, что поможет разработчику помнить, где (т.е. на какой ветке, т.е. выделенной ветке "для исправлений") он/она должен зафиксировать такие изменения.
Затем хуки могут помочь защитить центральное репо от проталкивания из непроверенных баг-фиксов или из веток, из которых не следует проталкивать. (здесь нет конкретного решения, всё это нужно адаптировать к вашей среде)
Как избежать создания конфликтов слияния (из-за cherry-pick)?
Как сказал Jakub Narębski в своём ответе, cherry-picking следует зарезервировать для редких ситуаций, когда это необходимо.
Если ваша установка включает в себя много вишневых косточек (т.е. "это не редкость"), значит, что-то не так.
Применение того же коммита в revert (как это сделать?)
git revert
должен позаботиться об этом, но это не идеально.
Как декомпозировать на тематические ветки?
Пока ветка ещё не вытеснена повсюду, разработчик должен реорганизовать свою историю коммитов (как только он/она наконец увидит, что разработка принимает более определённую и стабильную форму) в:
Надлежащие процедуры, такие как ревью кода и грейдинг?
Интеграционные ветки (в выделенном интеграционном репо) могут помочь разработчику:
Я думаю, и могу ошибаться, что одна из вещей, которые больше всего неправильно понимают в 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.
Итак, имея в виду все это:
головой
. Релизы могут быть тегами или ветвями, а исправления, вероятно, сами по себе являются ветвями. На самом деле, я бы, вероятно, делал выпуски в виде веток, чтобы вы могли их исправлять. источника
, вам следует в своем репозитории, вероятно, создать другую ветку и объединить последнюю мастер
в yourbranch
, чтобы кто-то другой мог внести ваши изменения с минимальными усилиями. По моему опыту, очень редко возникает необходимость по-настоящему перебазировать. git add.
, а затем git commit
. Надеюсь, это поможет. Я понимаю, что VonC только что опубликовал очень похожее объяснение ... Я не могу печатать достаточно быстро!
Отредактируйте некоторые дальнейшие мысли о том, как использовать git в коммерческих целях, поскольку это кажется относящимся к OP из комментариев:
product.git
, доступен ряду старших программистов / технических специалистов, отвечающих за фактический уход за самим продуктом. Они аналогичны роли сопровождающих в OSS. Так что же происходит? Что ж, все в начале каждого дня берут исходный код из «апстрима», то есть из репозитория релизов (который, вероятно, также будет содержать последние материалы о разработке за предыдущие дни). Все делают это напрямую. Это будет ветка в их репозитории,вероятно, называется "хозяином" или, может быть, если вы меня называете "последним". Затем программист выполнит некоторую работу. Возможно, они не уверены в этой работе, поэтому они создают ветку и выполняют эту работу. Если это не сработает, они могут удалить ветку и вернуться. Если это произойдет, им придется объединиться в основную ветку, над которой они сейчас работают. Мы скажем, что это UI-программист, работающий над 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
ветки или любое другое имя, которое они им дали, и таким образом эта функция будет исследована разработчиками. Если команда довольна, руководитель пользовательского интерфейса может попросить лидера тестирования вытащить его и объединить изменения. Это распространяется на всех (ниже по течению изменения), кто тестирует и отправляет отчеты об ошибках и т. Д. Наконец, если функция проходит тестирование и т. Д., Один из ведущих технических руководителей может объединить ее с текущей рабочей копией программы, после чего все изменения затем распространяются обратно вниз. И так далее.
Это не «традиционный» способ работы, и он разработан для «однорангового управления», а не «иерархического», как SVN / CVS. По сути, у всех есть доступ к фиксации, но только локально. Это доступ к репозиторию и репозиторию, который вы назначаете как репозиторий выпуска, который позволяет вам использовать иерархию.