Как я могу предотвратить распространение некоторых модификаций в Mercurial? - PullRequest
2 голосов
/ 04 марта 2012

Я занимаюсь разработкой веб-базы данных, которая уже используется для примерно десятка отдельных установок, большинством из которых я также управляю.Каждая установка имеет достаточное количество локальных настроек и настроек.Просто переключившись на Mercurial с SVN, я хотел бы воспользоваться его распределенным характером для отслеживания локальных изменений.Я установил каждый установленный сервер как свое собственное хранилище (и настроил apache, чтобы он не обслуживал каталоги .hg).

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

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

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

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

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

Ответы [ 4 ]

2 голосов
/ 04 марта 2012

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

Но так как вы не довольны этим решением, вот еще одно, которое вы можете попробовать:

В Mercurial 2.1 введено понятие Фазы . Этап - это метаданные набора изменений, помечающие его как «секретный», «черновой» или «общедоступный». Обычно эти метаданные используются и обрабатываются автоматически Mercurial и его расширениями, при этом пользователю не нужно знать об этом.

Однако, если вы сделали набор изменений 1234, который вы никогда не хотите передавать в другие репозитории, вы можете принудительно применить это, пометив его как секретный как:

hg phase --force --secret -r 1234

Если вы затем попытаетесь отправить его в другое хранилище, оно будет проигнорировано с таким предупреждением:

pushing to http://example.com/some/other/repository
searching for changes
no changes found (ignored 1 secret changesets)

Это решение позволяет вам

  1. версия изменений локальной конфигурации
  2. предотвратить случайное изменение этих изменений
  3. объединяет ваши локальные изменения с другими изменениями, которые вы вносите

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

1 голос
/ 03 апреля 2012

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

Я использую ветку local для информации о конфигурации. Когда все мои репозитории поддерживают фазы, я отмечу локальную ветку secret; но метод работает без него. local зависит от default, но значение по умолчанию не зависит от local, поэтому его можно нажимать независимо (с hg push -r default). Вот как это работает:

  1. Предположим, что основная линия разработки находится в ветви default. (Вы можете иметь больше ветвей; это для конкретности). Существует главное (стабильное) репо, которое не содержит паролей и т. Д. :

    ---o--o--o   (default)
    
  2. В каждом развернутом (не разработанном) клоне я создаю ветку local и фиксирую в ней все локальные состояния.

    ...o--o--o   (default)
              \
               L--L    (local)
    
  3. Обновления из апстрима всегда будут по умолчанию. Всякий раз, когда я получаю обновления, я объединяю их в local (n - это последовательность новых обновлений):

    ...o--o--o--n--n    (default)
              \     \
               L--L--N     (local)
    

    Локальная ветвь отслеживает эволюцию default, и я все еще могу вернуться к старым конфигурациям, если что-то пойдет не так.

  4. На сервере разработки я начинаю с той же настройки: ветка local с настройками конфигурации, как указано выше. Это никогда не будет подталкивать. Но на кончике local я создаю третью ветку, dev. Здесь происходит новая разработка.

    ...o--o   (default)
           \
            L--L    (local)
                \
                 d--d--d     (dev)
    
  5. Когда я готов опубликовать некоторые функции в основном репозитории, я сначала перебрасываю всю ветку dev на кончик default:

    hg rebase --source "min(branch('dev'))" --dest default --detach
    

    Предыдущее дерево становится:

    ...o--o--d--d--d   (default)
           \
            L--L    (local)
    

    Перебазированные наборы изменений теперь принадлежат ветви default. (С функциональными ветвями добавьте --keepbranches к команде rebase, чтобы сохранить имя ветви). У новых функций больше нет предков в local, и я могу опубликовать их с push -r default, не перетаскивая локальные ревизии. (Никогда не сливайтесь с local в default; только наоборот). Если вы забыли сказать -r default при нажатии, нет проблем: ваш толчок отклоняется, так как это добавит новую головку.

  6. На сервере разработки я объединяю перебазированные обороты в local, как если бы я их только что вытащил:

    ...o--o--d--d--d   (default)
           \        \
            L--L-----N    (local)
    
  7. Теперь я могу создать новую ветку dev поверх local и продолжить разработку.

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

1 голос
/ 04 марта 2012

Если проблема с версионным шаблоном и неверсированной локальной копией заключается в том, что изменения в шаблоне не превращают его в локальные копии, как насчет модификации вашего приложения для использования неверсированной localconfig.ini и откат к версионной config.ini за отсутствующие параметры.Таким образом, новые параметры по умолчанию могут быть добавлены в config.ini и распространены в вашем приложении.

0 голосов
/ 04 марта 2012

1 Mercurial имеет (продолжение комментариев) выборочная (на основе строки) фиксация - см. Расширение записи

2 Локальные изменения внутри версионные публичные файлы могут быть легко получены с помощью MQ Extension (я делаю это для конфигов сайта) .Ваша головная боль с MQ

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

является результатом неполированного рабочего процесса и (некоторой) неправильной интерпретации.Если вы хотите зафиксировать без MQ-патчей - не делайте это вручную.Добавьте псевдоним для commit, который qop -all + commit и используйте только эту новую команду .И когда вы нажимаете, вы можете не беспокоиться о MQ-состоянии - вы отправляете наборов изменений из репозитория, а не WC-состояние .Локальное репо также может быть защищено без псевдонима путем предварительной проверки содержимого хука.

3 Вы можете попробовать расширение LocalBranches, где ваши локальные изменения хранятся в локальных ветвях (и объединять ветки при изменениях)- Я нашел этот способ более хлопотным, по сравнению с MQ

...