PySVN - 如何判断仓库是否存在

2 投票
2 回答
5179 浏览
提问于 2025-04-16 13:09

我正在写一个小脚本,用来管理几个SVN仓库。用户需要提供他们想要更改的仓库的ID(这些仓库的根地址是这样的:https://www.mydomain.com/)。

我需要检查一下这个仓库是否真的存在。我尝试使用 Client.list 来查看是否能找到任何文件,代码是这样的:

client = pysvn.Client()
client.list("https://.../<username>/")

但是如果这个仓库不存在,脚本就会在列出文件的那一行卡住。从错误信息中查找,我发现pysvn实际上是在登录凭证的回调上卡住了(client.callback_get_login - 我已经实现了这个,但没有展示出来,如果仓库存在的话,它不会失败)。

你能建议我如何用pysvn来判断一个仓库是否存在吗?

谢谢,

Pete

2 个回答

1

彼得,

我和我的团队也遇到了同样的问题。Samplebias,试着提供一个 callback_get_login 函数,但把你的 callback_server_ssl_trust_prompt 设置为返回 (True, trust_dict['failures'], True)。如果子版本控制没有缓存你的服务器证书信任设置,你可能会发现 info2()(或者彼得的 list() 命令)会卡住(其实并不是卡住,只是返回的时间间歇性地变得很长)。奇怪的是,当你在这种情况下按下 CTRL-C 停止解释器时,你会看到它在登录回调上卡住,而不是在服务器证书验证上。你可以试着调整你的 ~/.subversion/auth 设置(特别是 svn.simplesvn.ssl.server 目录),你会发现不同的“卡住时间”。如果你需要处理那些确实永远不会返回的情况,可以看看 pysvn.Client.callback_cancel

考虑一下这个链接: http://pysvn.tigris.org/docs/pysvn_prog_ref.html#pysvn_client_callback_ssl_server_trust_prompt,你需要决定你想要的行为是什么。你是想只允许那些你已经缓存的信任连接?还是想无论服务器证书验证如何都始终接受(警告:这显然可能会带来安全隐患)。考虑以下建议:

import pysvn

URL1 = "https://exists.your.org/svn/repos/dev/trunk/current"
URL2 = "https://doesntexit.your.org/svn/repos/dev/trunk/current"
URL3 = "https://exists.your.org/svn/repos/dev/trunk/youDontHavePermissionsBranch"

ALWAYS = "ALWAYS"
NEVER = "NEVER"

DESIRED_BEHAVIOR = ALWAYS

def ssl_server_certificate_trust_prompt(trust_dict):

if DESIRED_BEHAVIOR == NEVER:
    return (False, 0, False)
elif DESIRED_BEHAVIOR == ALWAYS:
    return (True, trust_dict['failures'], True)
raise Exception, "Unsupported behavior"

def testURL(url):
    try:
        c.info2(url)
        return True
    except pysvn.ClientError, ce:
        if ('non-existant' in ce.args[0]) or ('Host not found' in ce.args[0]):
            return False
        else:
            raise ce

c = pysvn.Client()
c.callback_ssl_server_trust_prompt = lambda t: (False, t['failures'], True)
c.callback_get_login = lambda x, y, z: (True, "uname", "pw", False)

if not testURL(URL1): print "Test1 failed."

if testURL(URL2): print "Test2 failed."
try:
    testURL(URL3)
    print "Test3 failed."
except: pass

实际上,你可能不想像我这样复杂地处理返回值。我认为考虑服务器返回的潜在403错误和“找不到主机”的情况是很重要的,应该分开处理。

1

我没法重现你提到的在凭据回调中卡住的问题,所以可能需要更详细地描述一下这个问题。我在Ubuntu 10.04上运行的是pysvn 1.7.2,Python版本是2.6.6。

当我尝试用client.list()列出一个不存在的远程仓库时,它会抛出一个异常。你也可以使用client.info2()来检查远程仓库是否存在:

head_rev = pysvn.Revision(pysvn.opt_revision_kind.head)
bad_repo = 'https://.../xyz_i_dont_exist'
good_repo = 'https://.../real_project'
for url in (bad_repo, good_repo):
    try:
        info = client.info2(url, revision=head_rev, recurse=False)
        print url, 'exists.'
    except pysvn._pysvn_2_6.ClientError, ex:
        if 'non-existent' in ex.args[0]:
            print url, 'does not exist'
        else:
            print url, 'error:', ex.args[0]

撰写回答