我在Mercurial存储库中有一个软件。
我将我的软件项目打包为Debian软件包。
似乎这样做的标准方法是拥有一个
Debian包文件的单独分支,
它位于debian
子目录中。
我一直存在的一个问题是我忘了我是哪个分支 on并意外地提交错误的分支。有时候是这样的 经常,真的很烦人。当这种情况发生时我通常会 在实现问题之前推送到远程,然后有 手动修复本地和远程存储库,这是 痛苦。
我能想到的唯一选择是预先提交挂钩 如果我试图提交错误的分支,那就会中止。
具体来说,假设主分支称为default
和分支
包含Debian文件的内容称为debian
。然后我想要提交default
只有在提交中的所有文件都来自debian
时,分支才能成功
目录。我希望提交到debian
目录才能成功
提交中的文件位于debian
目录中。
我花了一些时间阅读关于Mercurial Hooks的章节并浏览这些例子
在Hg Book中,但仍然不知道如何去做。我确实得到了强烈的印象
对于像这样的东西我可能会调用外部Python脚本
在.hg/
。
答案 0 :(得分:3)
是的,您可以发现precommit
挂钩可以做到这一点。如果你想用bash做,你可以选择:
#!/bin/bash
revs=$(hg log -r "$HG_NODE:tip" --template '{rev} ') #Intentional space after {rev}
rc=0
for rev in $revs
do
files=$(hg log -r $rev --template '{files}')
#Above will include discards. So you cannot 'hg cat' them all. So you may want
# files=$(hg log -r $rev --template '{file_mods} {file_adds}')
branch=$(hg log -r $rev --template '{branch}')
for file in $files
do
if [ branch == "debian" ] && [ "$(echo $file | grep -v "debian")" != "" ] ; then
echo "ERROR: Non debian file in debian branch."
exit 1
fi
if [ branch != "debian" ] && [ "$(echo $file | grep "debian")" != "" ] ; then
echo "ERROR: debian file in non-debian branch."
exit 1
fi
done
done
exit $rc
那些if / grep几乎肯定是错误的,但是你得到了图片。
答案 1 :(得分:0)
使用@ Ry4an的解决方案作为起点,我使用新的hglib API提出了以下脚本。
#!/usr/bin/python
# Abort commit to the debian branch if it is not contained in a debian
# subdirectory
# Similary abort commit to non-debian branches if it is contained in a
# debian subdirectory
import hglib, os, sys
client = hglib.open("/home/faheem/hooktest")
ctx = client['tip']
files = ctx.files()
branch = ctx.branch()
for f in files:
d = os.path.dirname(f)
if branch == "debian" and d != "debian":
sys.exit("cannot commit %s (file not in 'debian' directory) to 'debian' branch"%f)
if branch != "debian" and d == "debian":
sys.exit("cannot commit %s (file in 'debian' directory) to non 'debian' branch"%f)
答案 2 :(得分:0)
使用进程内挂钩的方法是以下代码。这些
函数可以在Mercurial存储库的.hgrc
中使用。
pretxncommit.foo = python:mercurial_hooks.abort_commit_to_wrong_branch
pre-qfinish.bar = python:mercurial_hooks.qfinish_abort_commit_to_wrong_branch
abort_commit_to_wrong_branch
不允许正常提交错误
分支,但允许MQ提交。 qfinish_abort_commit_to_wrong_branch
阻止qfinish将错误分支上的MQ提交转换为
定期提交。
我使用了函数finish
https://bitbucket.org/mirror/mercurial/src/tip/hgext/mq.py?at=default#cl-3034
供参考。
def abort_commit_to_wrong_branch(ui, repo, **kwargs):
"""
Don't allow commits to 'debian' branch including files not
contained in the 'debian/' directory. Also don't allow commits to
non-'debian' branches including files contained in the 'debian/'
directory. Don't restrict MQ commits.
"""
# If repo has '_committingpatch' attribute, then it is an mq
# commit in progress, so return 'False'
import os
ctx = repo[kwargs['node']]
files = ctx.files()
branch = ctx.branch()
if hasattr(repo, "_committingpatch"):
for f in files:
d = os.path.dirname(f)
if branch == "debian" and d != "debian":
ui.warn("Warning: committing %s (file not in 'debian' directory) to 'debian' branch. Allowed since this ia an MQ commit.\n"%f)
if branch != "debian" and d == "debian":
ui.warn("Warning: committing %s (file in 'debian' directory) to non 'debian' branch. Allowed since this ia an MQ commit.\n"%f)
return False
for f in files:
d = os.path.dirname(f)
if branch == "debian" and d != "debian":
ui.warn("Error: cannot commit %s (file not in 'debian' directory) to 'debian' branch\n"%f)
return True
if branch != "debian" and d == "debian":
ui.warn("Error: cannot commit %s (file in 'debian' directory) to non 'debian' branch\n"%f)
return True
def qfinish_abort_commit_to_wrong_branch(ui, repo, **kwargs):
"""
Don't allow qfinish on 'debian' branch including files not
contained in the 'debian/' directory. Also don't allow qfinish on
non-'debian' branches including files contained in the 'debian/'
directory. Don't restrict MQ commits.
"""
from mercurial import scmutil
import os
if not repo.mq.applied:
ui.status(('no patches applied\n'))
return True
opts = kwargs['opts']
# case corresponding to `-a`. no revisions specified.
if opts.get('applied'):
revrange = ('qbase::qtip',)
# case where revision(s) specified
revrange = kwargs['pats']
revs = scmutil.revrange(repo, revrange)
# loop over revisions
for rev in revs:
ctx = repo[rev]
files = ctx.files()
branch = ctx.branch()
for f in files:
d = os.path.dirname(f)
if branch == "debian" and d != "debian":
ui.warn("Error: cannot commit %s (file not in 'debian' directory) to 'debian' branch\n"%f)
return True
if branch != "debian" and d == "debian":
ui.warn("Error: cannot commit %s (file in 'debian' directory) to non 'debian' branch\n"%f)
return True