def svn_move(src_path, dst_path, username='', commitmsg=''): '''Move src_path to dst_path, where each is the url to a file or directory in a Subversion repository. Apply the change as username, and log with commitmsg. ''' def log_message(items, pool): '''Return a commit log message, use as a callback ''' def fname(s): return s.rstrip('/').rsplit('/', 1)[1] src_fname = fname(items[1][2]) dst_fname = fname(items[0][2]) default_msg = 'Moved %s to %s' % (src_fname, dst_fname) return commitmsg or default_msg src_path = core.svn_path_canonicalize(src_path) dst_path = core.svn_path_canonicalize(dst_path) force = False # Ignored for repository -> repository moves move_as_child = False # If dst_path exists don't attempt to move src_path # as it's child make_parents = False # Make parents of dst_path as needed (like mkdir -p) revprop_tbl = None # Use a dict of str prop: vals to set custom svn props # The move operation is coordinated by a client context, suitbly populated # To set the commit message we provide a callback that returns commitmsg client_ctx = client.create_context() client_ctx.log_msg_func3 = client.svn_swig_py_get_commit_log_func client_ctx.log_msg_baton3 = log_message # Configure minimal authentication, this is an example only auth_providers = [ client.svn_client_get_simple_provider(), client.svn_client_get_username_provider(), ] client_ctx.auth_baton = core.svn_auth_open(auth_providers) # libsvn normally infers the username from the environment the working copy # and the configuration. If requested override all that. if username is not None: core.svn_auth_set_parameter(client_ctx.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, username) # Move one directory or file to another location in the same repository # svn_client_move5 can mv a number of files/directories at once if dst_path # is a directory, we ignore this and pass a 1-tuple commit_info = client.svn_client_move5( (src_path, ), dst_path, force, # Ignored move_as_child, make_parents, revprop_tbl, client_ctx, ) print commit_info.revision
def svn_move(src_path, dst_path, username='', commitmsg=''): '''Move src_path to dst_path, where each is the url to a file or directory in a Subversion repository. Apply the change as username, and log with commitmsg. ''' def log_message(items, pool): '''Return a commit log message, use as a callback ''' def fname(s): return s.rstrip('/').rsplit('/', 1)[1] src_fname = fname(items[1][2]) dst_fname = fname(items[0][2]) default_msg = 'Moved %s to %s' % (src_fname, dst_fname) return commitmsg or default_msg src_path = core.svn_path_canonicalize(src_path) dst_path = core.svn_path_canonicalize(dst_path) force = False # Ignored for repository -> repository moves move_as_child = False # If dst_path exists don't attempt to move src_path # as it's child make_parents = False # Make parents of dst_path as needed (like mkdir -p) revprop_tbl = None # Use a dict of str prop: vals to set custom svn props # The move operation is coordinated by a client context, suitbly populated # To set the commit message we provide a callback that returns commitmsg client_ctx = client.create_context() client_ctx.log_msg_func3 = client.svn_swig_py_get_commit_log_func client_ctx.log_msg_baton3 = log_message # Configure minimal authentication, this is an example only auth_providers = [client.svn_client_get_simple_provider(), client.svn_client_get_username_provider(), ] client_ctx.auth_baton = core.svn_auth_open(auth_providers) # libsvn normally infers the username from the environment the working copy # and the configuration. If requested override all that. if username is not None: core.svn_auth_set_parameter(client_ctx.auth_baton, core.SVN_AUTH_PARAM_DEFAULT_USERNAME, username) # Move one directory or file to another location in the same repository # svn_client_move5 can mv a number of files/directories at once if dst_path # is a directory, we ignore this and pass a 1-tuple commit_info = client.svn_client_move5((src_path,), dst_path, force, # Ignored move_as_child, make_parents, revprop_tbl, client_ctx, ) print commit_info.revision
def __init__(self, path, rev=None, txn=None, cmd=None): """ path - path to repository rev - revision number txn - name of transaction (usually the one about to be committed) cmd - if set, specifies cmd_* method to execute txn takes precedence over rev; if both are None, inspect the head revision """ path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) self.fs_ptr = repos.fs(repos_ptr) # if set, txn takes precendence if txn: self.txn_ptr = fs.open_txn(self.fs_ptr, txn) else: self.txn_ptr = None if rev is None: rev = fs.youngest_rev(self.fs_ptr) else: rev = int(rev) self.rev = rev if cmd != None: getattr(self, 'cmd_' + cmd)()
def __init__(self, url='', username='', password='', head=None, password_stores=None): parsed = common.parse_url(url, username, password) # --username and --password override URL credentials self.username = parsed[0] self.password = parsed[1] self.svn_url = core.svn_path_canonicalize(parsed[2]) self.auth_baton_pool = core.Pool() self.auth_baton = _create_auth_baton(self.auth_baton_pool, password_stores) # self.init_ra_and_client() assumes that a pool already exists self.pool = core.Pool() self.init_ra_and_client() self.uuid = ra.get_uuid(self.ra, self.pool) self.svn_url = ra.get_session_url(self.ra, self.pool) self.root = ra.get_repos_root(self.ra, self.pool) assert self.svn_url.startswith(self.root) # *will* have a leading '/', would not if we used get_repos_root2 self.subdir = self.svn_url[len(self.root):] if not self.subdir or self.subdir[-1] != '/': self.subdir += '/' # the RA interface always yields quoted paths, but the editor interface # expects unquoted paths self.subdir = urllib.unquote(self.subdir) self.hasdiff3 = True self.autoprops_config = common.AutoPropsConfig()
def __init__(self, url='', username='', password='', head=None, password_stores=None, meta=None): parsed = common.parse_url(url, username, password) # --username and --password override URL credentials self.username = parsed[0] self.password = parsed[1] self.svn_url = core.svn_path_canonicalize(parsed[2]) self.auth_baton_pool = core.Pool() self.auth_baton = _create_auth_baton(self.auth_baton_pool, password_stores) # self.init_ra_and_client() assumes that a pool already exists self.pool = core.Pool() self.init_ra_and_client() self.uuid = ra.get_uuid(self.ra, self.pool) self.svn_url = ra.get_session_url(self.ra, self.pool) self.root = ra.get_repos_root(self.ra, self.pool) assert self.svn_url.startswith(self.root) # *will* have a leading '/', would not if we used get_repos_root2 self.subdir = self.svn_url[len(self.root):] if not self.subdir or self.subdir[-1] != '/': self.subdir += '/' # the RA interface always yields quoted paths, but the editor interface # expects unquoted paths self.subdir = urllib.unquote(self.subdir) self.hasdiff3 = True self.autoprops_config = common.AutoPropsConfig() # store the svn meta object for use with branch skipping self.meta = meta
def putfile(fname, rpath, uname="", commitmsg=""): rpath = core.svn_path_canonicalize(rpath) repos_ptr = repos.open(rpath) fsob = repos.fs(repos_ptr) # open a transaction against HEAD rev = fs.youngest_rev(fsob) txn = repos.fs_begin_txn_for_commit(repos_ptr, rev, uname, commitmsg) root = fs.txn_root(txn) rev_root = fs.revision_root(fsob, rev) kind = fs.check_path(root, fname) if kind == core.svn_node_none: print("file '%s' does not exist, creating..." % fname) fs.make_file(root, fname) elif kind == core.svn_node_dir: print("File '%s' is a dir." % fname) return else: print("Updating file '%s'" % fname) handler, baton = fs.apply_textdelta(root, fname, None, None) ### it would be nice to get an svn_stream_t. for now, just load in the ### whole file and shove it into the FS. delta.svn_txdelta_send_string(open(fname, 'rb').read(), handler, baton) newrev = repos.fs_commit_txn(repos_ptr, txn) print("revision: %s" % newrev)
def main(): argc = len(sys.argv) if argc < 4 or argc > 5: usage_and_exit("Not enough arguments provided.") try: repos_path = core.svn_path_canonicalize(sys.argv[1]) except AttributeError: repos_path = os.path.normpath(sys.argv[1]) if repos_path[-1] == '/' and len(repos_path) > 1: repos_path = repos_path[:-1] try: author = sys.argv[4] except IndexError: author = None mode = sys.argv[2] try: if mode == "replace": old_author = sys.argv[3] fs_obj = get_fs_obj(repos_path) for revision in range(fs.svn_fs_youngest_rev(fs_obj) + 1): if fetch_rev_author(fs_obj, revision) == old_author: tweak_rev_author(fs_obj, revision, author) elif mode == "revision": try: revision = int(sys.argv[3]) except ValueError: usage_and_exit("Invalid revision number (%s) provided." % (sys.argv[3])) tweak_rev_author(get_fs_obj(repos_path), revision, author) else: usage_and_exit("Invalid mode (%s) provided." % (mode)) except SystemExit: raise except Exception as e: error_and_exit(str(e))
def load(self, repo_path): repo_path = core.svn_path_canonicalize(repo_path) repos_ptr = repos.open(repo_path) fs_ptr = repos.fs(repos_ptr) rev = fs.youngest_rev(fs_ptr) base_root = fs.revision_root(fs_ptr, 0) root = fs.revision_root(fs_ptr, rev) hist = fs.node_history(root, self.root) while hist is not None: hist = fs.history_prev(hist,0) dummy,rev = fs.history_location(hist) d = fs.revision_prop(fs_ptr, rev, core.SVN_PROP_REVISION_DATE) author = fs.revision_prop(fs_ptr, rev, \ core.SVN_PROP_REVISION_AUTHOR) if author == 'svnadmin': continue self.last_author = author self.last_date = core.svn_time_from_cstring(d) / 1000000 self.last_rev = rev def authz_cb(root, path, pool): return 1 editor = SvnDumperEditor(self) e_ptr, e_baton = delta.make_editor(editor) repos.dir_delta(base_root, '', '', root, self.root, e_ptr, e_baton, authz_cb, 0, 1, 0, 0) break
def main(): try: opts, args = my_getopt(sys.argv[1:], "vh?", ["verbose", "naive-mode", "help"]) except: raise usage_and_exit("Unable to process arguments/options.") # Process arguments. if not args: usage_and_exit("No working copy path provided.") else: branch_path = core.svn_path_canonicalize(args[0]) # Process options. verbose = naive_mode = False for opt, value in opts: if opt == "--help" or opt in ("-h", "-?"): usage_and_exit() elif opt == "--verbose" or opt == "-v": verbose = True elif opt == "--naive-mode": naive_mode = True else: usage_and_exit("Unknown option '%s'" % (opt)) # Do the work. shm = SvnmergeHistoryMigrator(SvnClient(), verbose, naive_mode) shm.migrate_path(branch_path)
def blame(path, filename, rev=None): annotresult = {} path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) fsob = repos.fs(repos_ptr) if rev is None: rev = fs.youngest_rev(fsob) filedata = '' for i in xrange(0, rev + 1): root = fs.revision_root(fsob, i) if fs.check_path(root, filename) != core.svn_node_none: first = i break print "First revision is %d" % first print "Last revision is %d" % rev for i in xrange(first, rev + 1): previousroot = root root = fs.revision_root(fsob, i) if i != first: if not fs.contents_changed(root, filename, previousroot, filename): continue file = fs.file_contents(root, filename) previousdata = filedata filedata = '' while 1: data = core.svn_stream_read(file, CHUNK_SIZE) if not data: break filedata = filedata + data print "Current revision is %d" % i diffresult = difflib.ndiff(previousdata.splitlines(1), filedata.splitlines(1)) # print ''.join(diffresult) k = 0 for j in diffresult: if j[0] == ' ': if annotresult.has_key(k): k = k + 1 continue else: annotresult[k] = (i, j[2:]) k = k + 1 continue elif j[0] == '?': continue annotresult[k] = (i, j[2:]) if j[0] != '-': k = k + 1 # print ''.join(diffresult) # print annotresult for x in xrange(len(annotresult.keys())): sys.stdout.write("Line %d (rev %d):%s" % (x, annotresult[x][0], annotresult[x][1]))
def load(self, repo_path): repo_path = core.svn_path_canonicalize(repo_path) repos_ptr = repos.open(repo_path) fs_ptr = repos.fs(repos_ptr) rev = fs.youngest_rev(fs_ptr) base_root = fs.revision_root(fs_ptr, 0) root = fs.revision_root(fs_ptr, rev) hist = fs.node_history(root, self.root) while hist is not None: hist = fs.history_prev(hist, 0) dummy, rev = fs.history_location(hist) d = fs.revision_prop(fs_ptr, rev, core.SVN_PROP_REVISION_DATE) author = fs.revision_prop(fs_ptr, rev, \ core.SVN_PROP_REVISION_AUTHOR) if author == 'svnadmin': continue self.last_author = author self.last_date = core.svn_time_from_cstring(d) / 1000000 self.last_rev = rev def authz_cb(root, path, pool): return 1 editor = SvnDumperEditor(self) e_ptr, e_baton = delta.make_editor(editor) repos.dir_delta(base_root, '', '', root, self.root, e_ptr, e_baton, authz_cb, 0, 1, 0, 0) break
def blame(path, filename, rev=None): annotresult = {} path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) fsob = repos.fs(repos_ptr) if rev is None: rev = fs.youngest_rev(fsob) filedata = '' for i in range(0, rev+1): root = fs.revision_root(fsob, i) if fs.check_path(root, filename) != core.svn_node_none: first = i break print("First revision is %d" % first) print("Last revision is %d" % rev) for i in range(first, rev+1): previousroot = root root = fs.revision_root(fsob, i) if i != first: if not fs.contents_changed(root, filename, previousroot, filename): continue file = fs.file_contents(root, filename) previousdata = filedata filedata = '' while True: data = core.svn_stream_read(file, CHUNK_SIZE) if not data: break filedata = filedata + data print("Current revision is %d" % i) diffresult = difflib.ndiff(previousdata.splitlines(1), filedata.splitlines(1)) # print ''.join(diffresult) k = 0 for j in diffresult: if j[0] == ' ': if k in annotresult: k = k + 1 continue else: annotresult[k] = (i, j[2:]) k = k + 1 continue elif j[0] == '?': continue annotresult[k] = (i, j[2:]) if j[0] != '-': k = k + 1 # print ''.join(diffresult) # print annotresult for x in range(len(annotresult.keys())): sys.stdout.write("Line %d (r%d):%s" % (x, annotresult[x][0], annotresult[x][1]))
def __init__(self, repos_path, txn_name): # these are for SVNLOOK/changed self.rpath = repos_path self.tname = txn_name self.repos_path = core.svn_path_canonicalize(repos_path) self.fs = repos.svn_repos_fs(repos.svn_repos_open(repos_path)) self.txn = fs.svn_fs_open_txn(self.fs, txn_name) self.txn_root = fs.svn_fs_txn_root(self.txn)
def test_info_file(self): """Test svn_client_info on working copy file and remote files.""" # This test requires a file /trunk/README.txt of size 8 bytes # in the repository. rev = core.svn_opt_revision_t() rev.kind = core.svn_opt_revision_head wc_path = core.svn_path_canonicalize(tempfile.mktemp()) client.checkout2(REPOS_URL, wc_path, rev, rev, True, True, self.client_ctx) adm_access = wc.adm_open3(None, wc_path, True, -1, None) try: # Test 1: Run info -r BASE. We expect the size value to be filled in. rev.kind = core.svn_opt_revision_base readme_path = '%s/trunk/README.txt' % wc_path readme_url = '%s/trunk/README.txt' % REPOS_URL client.info(readme_path, rev, rev, self.info_receiver, False, self.client_ctx) self.assertEqual(self.path, os.path.basename(readme_path)) self.info.assert_valid() self.assertEqual(self.info.working_size, client.SWIG_SVN_INFO_SIZE_UNKNOWN) self.assertEqual(self.info.size, 8) # Test 2: Run info (revision unspecified). We expect the working_size value # to be filled in. rev.kind = core.svn_opt_revision_unspecified client.info(readme_path, rev, rev, self.info_receiver, False, self.client_ctx) self.assertEqual(self.path, readme_path) self.info.assert_valid() self.assertEqual(self.info.size, client.SWIG_SVN_INFO_SIZE_UNKNOWN) # README.txt contains one EOL char, so on Windows it will be expanded from # LF to CRLF hence the working_size will be 9 instead of 8. if os.name == 'nt': self.assertEqual(self.info.working_size, 9) else: self.assertEqual(self.info.working_size, 8) # Test 3: Run info on the repository URL of README.txt. We expect the size # value to be filled in. rev.kind = core.svn_opt_revision_head client.info(readme_url, rev, rev, self.info_receiver, False, self.client_ctx) self.info.assert_valid() self.assertEqual(self.info.working_size, client.SWIG_SVN_INFO_SIZE_UNKNOWN) self.assertEqual(self.info.size, 8) finally: wc.adm_close(adm_access) core.svn_io_remove_dir(wc_path)
def dumpprops(path, filename='', rev=None): path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) fsob = repos.fs(repos_ptr) if rev is None: rev = fs.youngest_rev(fsob) root = fs.revision_root(fsob, rev) print_props(root, filename) if fs.is_dir(root, filename): walk_tree(root, filename)
def _rootpath2url(rootpath, path): rootpath = os.path.abspath(rootpath) drive, rootpath = os.path.splitdrive(rootpath) if os.sep != "/": rootpath = rootpath.replace(os.sep, "/") rootpath = _quote(rootpath) path = _quote(path) if drive: url = "file:///" + drive + rootpath + "/" + path else: url = "file://" + rootpath + "/" + path return core.svn_path_canonicalize(url)
def _rootpath2url(rootpath, path): rootpath = os.path.abspath(rootpath) drive, rootpath = os.path.splitdrive(rootpath) if os.sep != '/': rootpath = rootpath.replace(os.sep, '/') rootpath = _quote(rootpath) path = _quote(path) if drive: url = 'file:///' + drive + rootpath + '/' + path else: url = 'file://' + rootpath + '/' + path return core.svn_path_canonicalize(url)
def __init__(self, path): """initialize an SVNShell object""" Cmd.__init__(self) path = core.svn_path_canonicalize(path) self.fs_ptr = repos.fs(repos.open(path)) self.is_rev = 1 self.rev = fs.youngest_rev(self.fs_ptr) self.txn = None self.root = fs.revision_root(self.fs_ptr, self.rev) self.path = "/" self._setup_prompt() self.cmdloop()
def __init__(self, repos, txn): """ Initialize with the repository path and the transaction id (as strings). These are usually the arguments passed to the svn hooks. """ self._repos_path = svn_path_canonicalize(repos) self._txn_name = txn self._repos = None self._txn = None self._root = None self._changes = None
def __init__(self, path, cmd, rev, txn): path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) self.fs_ptr = repos.fs(repos_ptr) if txn: self.txn_ptr = fs.open_txn(self.fs_ptr, txn) else: self.txn_ptr = None if rev is None: rev = fs.youngest_rev(self.fs_ptr) self.rev = rev getattr(self, 'cmd_' + cmd)()
def getfile(path, filename, rev=None): path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) fsob = repos.fs(repos_ptr) if rev is None: rev = fs.youngest_rev(fsob) print("Using youngest revision %s" % rev) root = fs.revision_root(fsob, rev) file = fs.file_contents(root, filename) while True: data = core.svn_stream_read(file, CHUNK_SIZE) if not data: break sys.stdout.write(data)
def getfile(path, filename, rev=None): path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) fsob = repos.fs(repos_ptr) if rev is None: rev = fs.youngest_rev(fsob) print("Using youngest revision %s" % rev) root = fs.revision_root(fsob, rev) file = fs.file_contents(root, filename) while 1: data = core.svn_stream_read(file, CHUNK_SIZE) if not data: break sys.stdout.write(data)
def parse_args(args): argc = len(sys.argv) # parse the target URL and optional peg revision path_pieces = args[0].split('@') if len(path_pieces) > 1: peg_revision = int(path_pieces[-1]) assert peg_revision >= 0 url = '@'.join(path_pieces[:-1]) else: peg_revision = core.SVN_INVALID_REVNUM url = path_pieces[0] url = core.svn_path_canonicalize(url) # parse the revision range, if any if argc > 2: rev_pieces = args[1].split(':') num_revs = len(rev_pieces) assert num_revs < 3 if num_revs == 2: start_revision = int(rev_pieces[0]) end_revision = int(rev_pieces[1]) else: start_revision = end_revision = int(rev_pieces[0]) assert (start_revision >= 0) assert (end_revision >= 0) else: start_revision = peg_revision end_revision = 0 # validate if start_revision >= 0 \ and end_revision >= 0 \ and end_revision > start_revision: raise Exception("End revision must not be younger than start revision") if peg_revision >= 0 \ and start_revision >= 0 \ and start_revision > peg_revision: raise Exception("Start revision must not be younger than peg revision") return url, peg_revision, start_revision, end_revision
def parse_args(args): argc = len(sys.argv) # parse the target URL and optional peg revision path_pieces = args[0].split('@') if len(path_pieces) > 1: peg_revision = int(path_pieces[-1]) assert peg_revision >= 0 url = '@'.join(path_pieces[:-1]) else: peg_revision = core.SVN_INVALID_REVNUM url = path_pieces[0] url = core.svn_path_canonicalize(url) # parse the revision range, if any if argc > 2: rev_pieces = args[1].split(':') num_revs = len(rev_pieces) assert num_revs < 3 if num_revs == 2: start_revision = int(rev_pieces[0]) end_revision = int(rev_pieces[1]) else: start_revision = end_revision = int(rev_pieces[0]) assert(start_revision >= 0) assert(end_revision >= 0) else: start_revision = peg_revision end_revision = 0 # validate if start_revision >= 0 \ and end_revision >= 0 \ and end_revision > start_revision: raise Exception("End revision must not be younger than start revision") if peg_revision >= 0 \ and start_revision >= 0 \ and start_revision > peg_revision: raise Exception("Start revision must not be younger than peg revision") return url, peg_revision, start_revision, end_revision
def __init__(self, path, file_path, rev=None): self.file_path = file_path self.path = path repos_path = core.svn_path_canonicalize( os.path.normpath(self.path).replace('\\', '/') ) svn_repos = repos.svn_repos_open(repos_path) fs_ptr = repos.svn_repos_fs(svn_repos) if rev: self.rev = rev else: self.rev = fs.youngest_rev(fs_ptr) self.root = fs.revision_root(fs_ptr, self.rev) self.kind = KIND_MAP[fs.check_path(self.root, self.file_path)] self.name = os.path.split(self.file_path)[-1] self.cr = fs.node_created_rev(self.root, self.file_path) props = fs.revision_proplist(fs_ptr, self.cr) self.date = props[core.SVN_PROP_REVISION_DATE] self.author = props[core.SVN_PROP_REVISION_AUTHOR] self.log = props[core.SVN_PROP_REVISION_LOG]
def setUp(self): """Load a Subversion repository""" # Isolate each test from the others with a fresh repository. # Eventually, we should move this into a shared TestCase base # class that all test cases in this directory can use. SubversionRepositoryTestSetup().setUp() # Open repository directly for cross-checking self.repos = repos.open(REPOS_PATH) self.fs = repos.fs(self.repos) self.path = core.svn_path_canonicalize(tempfile.mktemp()) client_ctx = client.create_context() rev = core.svn_opt_revision_t() rev.kind = core.svn_opt_revision_head client.checkout2(REPOS_URL, self.path, rev, rev, True, True, client_ctx) self.wc = wc.adm_open3(None, self.path, True, -1, None)
def __init__(self, path, rev, txn): self.repo_root_path = core.svn_path_canonicalize(path) root_ptr = repos.open(self.repo_root_path) self.fs_ptr = repos.fs(root_ptr) # Set the revision/transaction if txn: self.txn_ptr = fs.open_txn(self.fs_ptr, txn) else: self.txn_ptr = None if rev is None: rev = fs.youngest_rev(self.fs_ptr) self.rev = rev # Set the root if self.txn_ptr: self.root = fs.txn_root(self.txn_ptr) else: self.root = fs.revision_root(self.fs_ptr, self.rev) # Set the base revision/transaction if self.txn_ptr: self.base_rev = fs.txn_base_revision(self.txn_ptr) else: self.base_rev = self.rev - 1 # Set the base root of the comparison self.base_root = fs.revision_root(self.fs_ptr, self.base_rev) # Get all the changes and sort by path editor = repos.ChangeCollector(self.fs_ptr, self.root) e_ptr, e_baton = delta.make_editor(editor) repos.replay(self.root, e_ptr, e_baton) self.changelist = editor.get_changes().items() self.changelist.sort()
import sys, string from svn import core, fs, delta, repos import codecs #argvs[1]:repository path #argvs[2]:changeset folder #argvs[3]:start revision #argvs[4]:end revision argvs = sys.argv #コマンドライン引数リスト argc = len(argvs) #引数の個数 if (argc != 5): #5でなければ出る usage(1) path = argvs[1] path = core.svn_path_canonicalize(path) repos_ptr = repos.open(path) fs_ptr = repos.fs(repos_ptr) changeset_folder = argvs[2] start_rev = int(argvs[3]) end_rev = int(argvs[4]) if start_rev > end_rev: sys.exit(exit) rev = fs.youngest_rev(fs_ptr) if start_rev > rev and end_rev > rev: sys.exit(exit)
def _c(path): return core.svn_path_canonicalize(path.strip('/'))
def MakeRecordsFromPath(srcrepo, srcrev, srcpath, dstpath, record_source): """Generate Records adding the contents of a given repo/rev/path. Args: srcrepo: path to the source repository srcrev: revision number srcpath: path within the source repository dstpath: destination path in the repository being filtered record_source: the source attribute of the Records generated Returns: a list of Records Raises: RuntimeError: if svnrdump seems to have failed This is the fundamental feature of a working svndumpfilter replacement. In the upstream svndumpfilter, copyfrom operations that reference paths that are excluded by filtering cannot be resolved. To fix that, each svndumpfilter replacement must find a way to turn that copy operation into a series of add operations. svndumpfilter2 originally did this by calling the svnlook utility to list the directory structure, grab file contents, list property names, and grab property values. This resulted in calling svnlook once per tree, twice per file, and once per property. For a time, we tried instead making a single call to svnrdump which, unlike svnadmin dump (which is used by svndumpfilter3 with disastrous results for performance) can output a dump file containing only the desired subdirectory. The dump file is parsed into Records, the paths have the destination path prepended, and the Records are inserted into the dump. Unfortunately, svnrdump always produces format 3 dumps which use deltas. Even though it was only used for a single non-incremental revision, every file's contents were in the form of a delta. Since some tools (such as p4convert-svn) do not support deltas, svnrdump was done away with, replaced by the SVN SWIG bindings. It turns out that this same functionality is critical to 'internalizing' SVN externals. By generating Records that add all of the files and directories in the repo/rev/path referenced by an svn:external property, the history can be made to look as though the actual files had been there all along, not just a reference to them. Further filtering of these generated Records must be done in the case of externals to delete externals when they are removed and modify the filesystem when the revision is changed, rather than deleting and reading it every time (see externals.FromRev, externals.Diff, Diff). """ srcrepo = svn_core.svn_path_canonicalize(srcrepo) repo_ptr = svn_repos.open(srcrepo) fs = svn_repos.fs(repo_ptr) root = svn_fs.revision_root(fs, srcrev) output = [] # Perform a depth-first search stack = [srcpath] while stack: path = stack.pop() if srcpath: relative_path = path[len(srcpath):] node_path = dstpath + relative_path else: node_path = (dstpath + '/' + path) if path else dstpath if svn_fs.is_dir(root, path): record = Record(action='add', kind='dir', path=node_path, source=record_source) # Add children to the stack prefix = (path + '/') if path else '' for name in svn_fs.dir_entries(root, path).keys(): stack.append(prefix + name) else: record = Record(action='add', kind='file', path=node_path, source=record_source) # Fetch file content stream = svn_fs.file_contents(root, path) record.text = _ReadSVNStream(stream) checksum = svn_fs.file_md5_checksum(root, path) record.headers['Text-content-md5'] = checksum.encode('hex_codec') # Fetch properties props = svn_fs.node_proplist(root, path) record.props = {key: str(value) for key, value in props.iteritems()} output.append(record) return output
def _canonicalize_path(path): try: return core.svn_path_canonicalize(path) except AttributeError: return path
def _geturl(self, path=None): if not path: return self.rootpath path = self.rootpath + '/' + _quote(path) return core.svn_path_canonicalize(path)