Si no les importa usar Python y la biblioteca pysvn, aquí es un completo programa de línea de comandos que estoy usando para lo externo SVN:
"""
@file
@brief SVN externals utilities.
@author Lukasz Matecki
"""
import sys
import os
import pysvn
import argparse
class External(object):
def __init__(self, parent, remote_loc, local_loc, revision):
self.parent = parent
self.remote_loc = remote_loc
self.local_loc = local_loc
self.revision = revision
def __str__(self):
if self.revision.kind == pysvn.opt_revision_kind.number:
return """\
Parent: {0}
Source: {1}@{2}
Local name: {3}""".format(self.parent, self.remote_loc, self.revision.number, self.local_loc)
else:
return """\
Parent: {0}
Source: {1}
Local name: {2}""".format(self.parent, self.remote_loc, self.local_loc)
def find_externals(client, repo_path, external_path=None):
"""
@brief Find SVN externals.
@param client (pysvn.Client) The client to use.
@param repo_path (str) The repository path to analyze.
@param external_path (str) The URL of the external to find; if omitted, all externals will be searched.
@returns [External] The list of externals descriptors or empty list if none found.
"""
repo_root = client.root_url_from_path(repo_path)
def parse(ext_prop):
for parent in ext_prop:
external = ext_prop[parent]
for line in external.splitlines():
path, name = line.split()
path = path.replace("^", repo_root)
parts = path.split("@")
if len(parts) > 1:
url = parts[0]
rev = pysvn.Revision(pysvn.opt_revision_kind.number, int(parts[1]))
else:
url = parts[0]
rev = pysvn.Revision(pysvn.opt_revision_kind.head)
retval = External(parent, url, name, rev)
if external_path and not external_path == url:
continue
else:
yield retval
for entry in client.ls(repo_path, recurse=True):
if entry["kind"] == pysvn.node_kind.dir and entry["has_props"] == True:
externals = client.propget("svn:externals", entry["name"])
if externals:
for e in parse(externals):
yield e
def check_externals(client, externals_list):
for i, e in enumerate(externals_list):
url = e.remote_loc
rev = e.revision
try:
info = client.info2(url, revision=rev, recurse=False)
props = info[0][1]
url = props.URL
print("[{0}] Existing:\n{1}".format(i + 1, "\n".join([" {0}".format(line) for line in str(e).splitlines()])))
except:
print("[{0}] Not found:\n{1}".format(i + 1, "\n".join([" {0}".format(line) for line in str(e).splitlines()])))
def main(cmdargs):
parser = argparse.ArgumentParser(description="SVN externals processing.",
formatter_class=argparse.RawDescriptionHelpFormatter,
prefix_chars='-+')
SUPPORTED_COMMANDS = ("check", "references")
parser.add_argument(
"action",
type=str,
default="check",
choices=SUPPORTED_COMMANDS,
help="""\
the operation to execute:
'check' to validate all externals in a given location;
'references' to print all references to a given location""")
parser.add_argument(
"url",
type=str,
help="the URL to operate on")
parser.add_argument(
"--repo", "-r",
dest="repo",
type=str,
default=None,
help="the repository (or path within) to perform the operation on, if omitted is inferred from url parameter")
args = parser.parse_args()
client = pysvn.Client()
if args.action == "check":
externals = find_externals(client, args.url)
check_externals(client, externals)
elif args.action == "references":
if args.repo:
repo_root = args.repo
else:
repo_root = client.root_url_from_path(args.url)
for i, e in enumerate(find_externals(client, repo_root, args.url)):
print("[{0}] Reference:\n{1}".format(i + 1, "\n".join([" {0}".format(line) for line in str(e).splitlines()])))
if __name__ == "__main__":
sys.exit(main(sys.argv))
Esto debería funcionar tanto en Python 2 y Python 3. Y ou puede utilizar de esta manera (direcciones reales eliminados):
python svn_externals.py references https://~~~~~~~~~~~~~~/cmd_utils.py
[1] Reference:
Parent: https://~~~~~~~~~~~~~~/BEFORE_MK2/scripts/utils
Source: https://~~~~~~~~~~~~~~/tools/python/cmd_utils.py
Local name: cmd_utils.py
[2] Reference:
Parent: https://~~~~~~~~~~~~~~/VTB-1425_PCU/scripts/utils
Source: https://~~~~~~~~~~~~~~/tools/python/cmd_utils.py
Local name: cmd_utils.py
[3] Reference:
Parent: https://~~~~~~~~~~~~~~/scripts/utils
Source: https://~~~~~~~~~~~~~~/tools/python/cmd_utils.py
Local name: cmd_utils.py
En cuanto al rendimiento, esto funciona bastante rápido (aunque mi repositorio es bastante pequeña). Tienes que verificarlo por ti mismo.
Sí, descubrí por qué lo hace, pero me preguntaba si alguien tenía una manera más rápida. Sin embargo, no parece prometedor. – NeoSkye
Creo que es así de simple: si necesita hacerlo recursivamente, solo será lento. – Argeman