Как делает Подвижную работу со многими разработчиками?

Я смотрю на Подвижные репозитории некоторых известных продуктов, как TortoiseHg и Python, и даже при том, что я вижу, что несколько человек фиксируют изменения, временная шкала всегда выглядит довольно чистой со всего одним продвижением ответвления.

Однако скажем, у Вас есть 14 человек, работающих над тем же продуктом, это быстро не войдет в кошмар ответвления с 14 параллельными ответвлениями в любой момент времени?

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

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

Или... Что я не вижу здесь? Возможно, это не действительно проблема?


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

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

Таким образом, это не это.

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

Таким образом, как они делают это?

Они "Повторно основывают" изменения так, чтобы они, казалось, следовали последнему совету ответвления даже при том, что они первоначально фиксировались немного назад в истории ответвления? Пересадка changesets, чтобы заставить их появиться к' тому, чтобы быть фиксировавшимся в основном ответвлении для начала?

Или проекты, я посмотрел на любого, таким образом, медленного (в данный момент, я не смотрел далекая спина в истории) при добавлении новых вещей, что в действительности они только работали один человек за один раз?

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

14
задан angry person 5 July 2010 в 10:03
поделиться

6 ответов

В вашем обновленном вопросе кажется, что вас больше интересуют способы приведения в порядок истории. Когда у вас есть история и вы хотите привести её в единый, аккуратный, прямой вид, вам нужно использовать rebase, transplant и/или mercurial queues. Проверьте документацию по этим трем функциям, и вы поймете, как это делается.

Редактировать: Поскольку я жду компиляции, вот конкретный пример того, что я имею в виду:

> hg init
> echo test > a.txt
> hg addremove && hg commit -m "added a.txt"
> echo test > b.txt
> hg addremove && hg commit -m "added b.txt"
> hg update 0 # go back to initial revision
> echo test > c.txt
> hg addremove && hg commit -m "added c.txt"

Запуск hg glog теперь показывает эту (расходящуюся) историю с двумя ветками:

@  changeset:   2:c79893255a0f
|  tag:         tip
|  parent:      0:7e1679006144
|  user:        mizipzor
|  date:        Mon Jul 05 12:20:37 2010 +0200
|  summary:     added c.txt
|
| o  changeset:   1:74f6483b38f4
|/   user:        mizipzor
|    date:        Mon Jul 05 12:20:07 2010 +0200
|    summary:     added b.txt
|
o  changeset:   0:7e1679006144
   user:        mizipzor
   date:        Mon Jul 05 12:19:41 2010 +0200
   summary:     added a.txt

Сделайте rebase, превратив changeset 1 в дочерний элемент 2, а не 0:

> hg rebase -s 1 -d 2

Теперь давайте проверим историю снова:

@  changeset:   2:ea0c9a705a70
|  tag:         tip
|  user:        mizipzor
|  date:        Mon Jul 05 12:20:07 2010 +0200
|  summary:     added b.txt
|
o  changeset:   1:c79893255a0f
|  user:        mizipzor
|  date:        Mon Jul 05 12:20:37 2010 +0200
|  summary:     added c.txt
|
o  changeset:   0:7e1679006144
   user:        mizipzor
   date:        Mon Jul 05 12:19:41 2010 +0200
   summary:     added a.txt

Presto! Одна строка. :)

Также обратите внимание, что я не делал слияние. Когда вы делаете ребазинг таким образом, вам придется иметь дело с конфликтами слияния и всем остальным, как если бы вы сделали слияние. Потому что это практически то, что происходит под капотом. Поэкспериментируйте с этим в небольшом тестовом репозитории. Например, попробуйте изменить файл, добавленный в ревизии 0, вместо того, чтобы просто добавить больше файлов.

5
ответ дан 1 December 2019 в 12:12
поделиться

Я не знаю, как команда TortoiseHg делает что-то, но вы можете использовать расширение Mercurial rebase , чтобы «отсоединить» ветку и поместить ее на верхушку кончика, создав единственную ветвь.

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

2
ответ дан 1 December 2019 в 12:12
поделиться

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

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

3
ответ дан 1 December 2019 в 12:12
поделиться

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

3
ответ дан 1 December 2019 в 12:12
поделиться

Я разработчик Mercurial, поэтому позвольте мне объяснить, как мы / я это делаем.

В проекте Mercurial мы принимаем взносы в виде исправлений, отправляемых в список рассылки. Когда мы применяем те, которые имеют hg import , мы выполняем неявную перебазировку в верхушку ветки, над которой мы работаем. Это очень помогает в сохранении чистоты истории.

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

hg push  # abort: creates new remote head
hg pull
hg rebase
hg push

Вы можете комбинировать извлечение и перебазирование, если хотите ( hg pull --rebase ), но мне всегда нравилось делать шаг за шагом.

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

5
ответ дан 1 December 2019 в 12:12
поделиться

Или ... Чего я здесь не вижу? Может быть, это не совсем проблема?

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

На практике это означает, что более 80% слияний может быть выполнено автоматически самим Mercurial.

Возьмем пример:

у вас есть:

[branch 1]  [branch2]
        \    /
         \  /
        [base]

Правка : для ясности, по ветке я имею в виду безымянные ветки.

Если у вас есть файл, измененный в ветке 1 , но тот же файл в ветке 2 такой же, как в base , то версия в ] ветвь 1 выбрана. Если файл изменен как в ветке 1 , так и в ветке 2 , файлы объединяются построчно с использованием одного и того же алгоритма: если строка 1 в файле1 в ветке 1 отличается от строки 1 в файле1 в base , но в ветке 2 и base строка 1 равна, строка 1 в ветке 1 равна выбрал (и тд и тп).

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

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

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

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

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

6
ответ дан 1 December 2019 в 12:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: