Mercurial Subrepositories:防止意外的递归提交和推送

时间:2011-01-31 22:31:38

标签: version-control mercurial dvcs mercurial-subrepos

我在一个团队工作,我们在一个包含多个子存储库的mercurial存储库中有一个代码:

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

Mercurial的默认行为是,当在“main”中执行hg commit时,子存储库“subrepo1”和“subrepo2”中的任何未完成的更改也将被提交。类似地,当推送“main”时,“subrepo1”和“subrepo2”中的任何传出提交也将被推送。

我们发现人们经常无意中提交并推送子库中的更改(因为他们忘记了他们已经进行了更改,默认情况下hg status不会显示递归更改)。我们还发现,在我们的团队中,这样的全球提交/推送几乎总是偶然的。

Mercurial 1.7最近通过hg status -Shg outgoing -S改善了情况,显示了子存储库的变化;但是,这仍然需要人们关注。

如果子目录中的更改/提交原本会被提交/推送,Mercurial中有没有办法让hg commithg push中止?

5 个答案:

答案 0 :(得分:9)

自Mercurial 1.8以来,配置设置为disables recursive commits。在父存储库.hg/hgrc中,您可以添加:

[ui]
commitsubrepos = no

如果父存储库中的提交在子存储库中发现未提交的更改,则整个提交将中止,而不是以静默方式提交子存储库。

答案 1 :(得分:8)

除非您为--subrepos手动指定-S(或者,commit)参数,否则Mercurial 2.0会自动阻止您提交子存储库。

例如,当子库中存在挂起的更改时,您尝试执行提交,您会收到以下消息:

# 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

有些事情需要注意:如果你已经更改了 revision ,那么子存储库当前处于子存储库,而不是子存储库的内容,Mercurial将很乐意提交没有--subrepos标志的版本更改。此外,仍然会在没有警告的情况下执行递归推送。

答案 2 :(得分:4)

一个概念是使用.hgsub文件中具有只读访问权限的网址。然后,当你真的想要推进subrepo时,你可以直接进入它并进行hg push THE_READ_WRITE_URL

答案 3 :(得分:3)

一种可能的解决方案,使用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 pushhg commit将中止。像这样运行命令:

SUBREPO=1 hg commit

将覆盖检查,允许您执行全局提交/推送,如果您真的想要。

答案 4 :(得分:2)

可能是pre-commit挂钩(not precommit)可以为您执行hg status -S,并在检测到任何更改时阻止提交?