Mercurial Subrepositories: предотвращение случайных рекурсивных коммитов и толчков

Я работаю в команде, где у нас есть код в репозитории mercurial с несколькими подпредприятиями:

main/
main/subrepo1/
main/subrepo1/subrepo2/

поведение по умолчанию Mercurial является то, что когда hg commit выполняется в "main", любые неурегулированные изменения в подкаталогах" subrepo1 "и" subrepo2 " также будут зафиксированы. Точно так же, когда "главный" нажата, любые исходящие совершает в "subrepo1" и "subrepo2" будет нажата.

мы видим, что люди часто непреднамеренно commit и push изменения в их подпредприятиях (потому что они забыли, что внесли изменения, и hg status по умолчанию рекурсивные изменения не отображаются). Мы также обнаруживаем, что такие глобальные коммиты / толчки почти всегда случайны в нашей команде.

Mercurial 1.7 недавно улучшил ситуацию с hg status -S и hg outgoing -S, которые показывают изменения в subrepositories; но все же, это требует, чтобы люди обращали внимание.

есть ли способ в Mercurial сделать hg commit и hg push прервать, если есть изменения / фиксации в субрепосториях, которые в противном случае были бы зафиксированы/вытеснены?

5 ответов


поскольку Mercurial 1.8 есть настройка, что отключает рекурсивный совершает. В родительских репозиториях .hg/hgrc можно добавить:

[ui]
commitsubrepos = no

Если фиксация в Родительском репозитории обнаруживает незафиксированные изменения в подрепозиции, вся фиксация прерывается, а не молчаливая фиксация подрепозитов.


Mercurial 2.0 автоматически запрещает вам совершать подпредприятия, если вы вручную не укажете --subrepos (или -S аргумент) к commit.

например, вы пытаетесь выполнить фиксацию, пока есть ожидающие изменения в subrepository, вы получаете следующее сообщение:

# hg commit -m 'change main repo'
abort: uncommitted changes in subrepo hello
(use --subrepos for recursive commit)

вы можете успешно выполнить фиксацию, однако, добавив --subrepos команды:

# hg commit --subrepos -m 'commit subrepos'
committing subrepository hello

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


одно понятие-использовать URL-адреса, к которым у вас есть доступ только для чтения в вашем .hgsub файлы. Затем, когда вы действительно хотите нажать в subrepo вы можете просто cd в него и сделать hg push THE_READ_WRITE_URL.


одно возможное решение, используя идею "предварительной фиксации" VonC.

настройка двух сценариев; первый check_subrepo_commit.sh:

#!/bin/bash

# If the environment variable "SUBREPO" is set, allow changes.
[ "x$SUBREPO" != "x" ] && exit 0

# Otherwise, ensure that subrepositories have not changed.
LOCAL_CHANGES=`hg status -a -m`
GLOBAL_CHANGES=`hg status -S -a -m`
if [ "x${LOCAL_CHANGES}" != "x$GLOBAL_CHANGES" ]; then
    echo "Subrepository changes exist!"
    exit 1
fi
exit 0

второе, check_subrepo_push.sh:

#!/bin/bash

# If the environment variable "SUBREPO" is set, allow changes.
[ "x$SUBREPO" != "x" ] && exit 0

# Otherwise, ensure that subrepositories have not changed.
LOCAL_CHANGES=`hg outgoing | grep '^changeset:'`
GLOBAL_CHANGES=`hg outgoing -S | grep '^changeset:'`
if [ "x${LOCAL_CHANGES}" != "x$GLOBAL_CHANGES" ]; then
    echo "Global changes exist!"
    exit 1
fi
exit 0

добавьте к вашему .hgrc:

[hooks]
pre-commit.subrepo = check_subrepo_commit.sh
pre-push.subrepo = check_subrepo_push.sh

по умолчанию hg push и hg commit будет прервано, если есть выдающиеся изменения в подпредприятиях. Запуск такой команды:

SUBREPO=1 hg commit

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


может быть pre-commit крюк (не precommit) может ли hg status -S для вас и заблокировать фиксацию, если она обнаружит какие-либо изменения?