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 setUp(self): """Load a Subversion repository""" self.temper = utils.Temper() (self.repos, self.repos_path, self.repos_uri) = self.temper.alloc_known_repo( 'trac/versioncontrol/tests/svnrepos.dump', suffix='-repository') self.fs = repos.fs(self.repos) self.rev = fs.youngest_rev(self.fs) self.tmpfile = None self.unistr = u'⊙_ʘ' tmpfd, self.tmpfile = mkstemp() tmpfp = os.fdopen(tmpfd, "wb") # Use a unicode file to ensure proper non-ascii handling. tmpfp.write(self.unistr.encode('utf8')) tmpfp.close() clientctx = client.svn_client_create_context() clientctx.log_msg_func3 = client.svn_swig_py_get_commit_log_func clientctx.log_msg_baton3 = self.log_message_func providers = [ client.svn_client_get_simple_provider(), client.svn_client_get_username_provider(), ] clientctx.auth_baton = core.svn_auth_open(providers) commitinfo = client.import2(self.tmpfile, urljoin(self.repos_uri +"/", "trunk/UniTest.txt"), True, True, clientctx) self.commitedrev = commitinfo.revision
def open(self): # Register a handler for SIGTERM so we can have a chance to # cleanup. If ViewVC takes too long to start generating CGI # output, Apache will grow impatient and SIGTERM it. While we # don't mind getting told to bail, we want to gracefully close the # repository before we bail. def _sigterm_handler(signum, frame, self=self): sys.exit(-1) try: signal.signal(signal.SIGTERM, _sigterm_handler) except ValueError: # This is probably "ValueError: signal only works in main # thread", which will get thrown by the likes of mod_python # when trying to install a signal handler from a thread that # isn't the main one. We'll just not care. pass # Open the repository and init some other variables. self.repos = repos.svn_repos_open(self.rootpath) self.fs_ptr = repos.svn_repos_fs(self.repos) self.youngest = fs.youngest_rev(self.fs_ptr) self._fsroots = {} self._revinfo_cache = {} # See if a universal read access determination can be made. if self.auth and self.auth.check_universal_access(self.name) == 1: self.auth = None
def __init__(self, path, authz): Repository.__init__(self, authz) if core.SVN_VER_MAJOR < 1: raise TracError, \ "Subversion >= 1.0 required: Found %d.%d.%d" % \ (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_MICRO) self.repos = None self.fs_ptr = None self.path = path # Remove any trailing slash or else subversion might abort if not os.path.split(path)[1]: path = os.path.split(path)[0] self.path = repos.svn_repos_find_root_path(path) if self.path is None: raise TracError, "%s does not appear to be a Subversion repository." % (path, ) if self.path != path: self.scope = path[len(self.path):] if not self.scope[-1] == '/': self.scope += '/' else: self.scope = '/' self.repos = repos.svn_repos_open(self.path) self.fs_ptr = repos.svn_repos_fs(self.repos) self.rev = fs.youngest_rev(self.fs_ptr) self.history = None if self.scope != '/': self.history = [] for path,rev in _get_history(self.scope[1:], self.authz, self.fs_ptr, 0, self.rev): self.history.append(rev)
def get_youngest_rev(self): if not self.youngest: self.youngest = fs.youngest_rev(self.fs_ptr, self.pool()) if self.scope != '/': for path, rev in self._history('', 0, self.youngest, limit=1): self.youngest = rev return self.youngest
def test_do_diff2(self): class ChangeReceiver(delta.Editor): def __init__(self): self.textdeltas = [] def apply_textdelta(self, file_baton, base_checksum): def textdelta_handler(textdelta): if textdelta is not None: self.textdeltas.append(textdelta) return textdelta_handler editor = ChangeReceiver() e_ptr, e_baton = delta.make_editor(editor) fs_revnum = fs.youngest_rev(self.fs) sess_url = ra.get_session_url(self.ra_ctx) try: ra.reparent(self.ra_ctx, REPOS_URL+"/trunk") reporter, reporter_baton = ra.do_diff2(self.ra_ctx, fs_revnum, "README.txt", 0, 0, 1, REPOS_URL+"/trunk/README.txt", e_ptr, e_baton) reporter.set_path(reporter_baton, "", 0, True, None) reporter.finish_report(reporter_baton) finally: ra.reparent(self.ra_ctx, sess_url) self.assertEqual("A test.\n", editor.textdeltas[0].new_data) self.assertEqual(1, len(editor.textdeltas))
def create_file(self, file_name, content, author, comment): """ Creates a file in the SVN repository with the given name and content (text). Returns the committed revision """ assert self.svn_repos is not None, "SVN repository not set..." # Get an SVN file system pointer fs_ptr = repos.fs(self.svn_repos) rev = fs.youngest_rev(fs_ptr) # Create and SVN transaction txn = fs.begin_txn(fs_ptr, rev) txn_root = fs.txn_root(txn) # Create a file in the root transaction fs.make_file(txn_root, file_name) stream = fs.apply_text(txn_root, file_name, None) core.svn_stream_write(stream, "%s\n" % content) core.svn_stream_close(stream) # Now set the properties svn:log and svn:author to # the newly created node (file) fs.change_txn_prop(txn, 'svn:author', author) fs.change_txn_prop(txn, 'svn:log', comment) # Commit the transaction fs.commit_txn(txn) # Add teh file to the list of created files self.files.append(file_name) # Returns therevision number return rev + 1
def setUp(self): """Load a Subversion repository""" self.temper = utils.Temper() (self.repos, _, _) = self.temper.alloc_known_repo( 'trac/versioncontrol/tests/svnrepos.dump', suffix='-repository') self.fs = repos.fs(self.repos) self.rev = fs.youngest_rev(self.fs)
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 test_get_log2(self): # Get an interesting commmit. self.test_commit3() rev = fs.youngest_rev(self.fs) revprops = ra.rev_proplist(self.ra_ctx, rev) self.assert_("svn:log" in revprops) self.assert_("testprop" in revprops) def receiver(log_entry, pool): called[0] = True self.assertEqual(log_entry.revision, rev) if discover_changed_paths: self.assertEqual(list(log_entry.changed_paths.keys()), ["/bla3"]) changed_path = log_entry.changed_paths["/bla3"] self.assert_(changed_path.action in ["A", "D", "R", "M"]) self.assertEqual(changed_path.copyfrom_path, None) self.assertEqual(changed_path.copyfrom_rev, -1) else: self.assertEqual(log_entry.changed_paths, None) if log_revprops is None: self.assertEqual(log_entry.revprops, revprops) elif len(log_revprops) == 0: self.assert_(log_entry.revprops == None or len(log_entry.revprops) == 0) else: revprop_names = sorted(log_entry.revprops.keys()) log_revprops.sort() self.assertEqual(revprop_names, log_revprops) for i in log_revprops: self.assertEqual( log_entry.revprops[i], revprops[i], msg="%s != %s on %s" % (log_entry.revprops[i], revprops[i], (log_revprops, discover_changed_paths)), ) for log_revprops in ( # Retrieve the standard three. ["svn:author", "svn:date", "svn:log"], # Retrieve just testprop. ["testprop"], # Retrieve all. None, # Retrieve none. [], ): for discover_changed_paths in [True, False]: called = [False] ra.get_log2( self.ra_ctx, [""], rev, rev, # start, end 1, # limit discover_changed_paths, True, # strict_node_history False, # include_merged_revisions log_revprops, receiver, ) self.assert_(called[0])
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 get_youngest_rev(self): if not self.youngest: self.youngest = fs.youngest_rev(self.fs_ptr, self.pool()) if self.scope != "/": for path, rev in self._history("", 1, self.youngest, self.pool): self.youngest = rev break return self.youngest
def _revisionSetup(self, subpool, author, message): """ All of the setup for performing a revision. """ revision = fs.youngest_rev(self.fsob, subpool) transaction = repos.svn_repos_fs_begin_txn_for_commit(self.repos_ptr, revision, author, message, subpool) root = fs.txn_root(transaction, subpool) return (revision, transaction, root)
def get_youngest_rev(self): if not self.youngest: self.youngest = fs.youngest_rev(self.fs_ptr, self.pool()) if self.scope != '/': for path, rev in self.history(_to_svn(self.scope), 0, self.youngest, self.pool): self.youngest = rev break return self.youngest
def get_actual_version(self): """ Get the actual version of the repostory @return: youngest_rev """ # Return youngest revision return fs.youngest_rev(self.fs_ptr)
def setUp(self): """Load the mergeinfo-full Subversion repository. This dumpfile is created by dumping the repository generated for command line log tests 16. If it needs to be updated (mergeinfo format changes, for example), we can go there to get a new version.""" self.temper = utils.Temper() (self.repos, _, _) = self.temper.alloc_known_repo('data/mergeinfo.dump', suffix='-mergeinfo') self.fs = repos.fs(self.repos) self.rev = fs.youngest_rev(self.fs)
def open(self): # Open the repository and init some other variables. self.repos = repos.svn_repos_open(self.rootpath) self.fs_ptr = repos.svn_repos_fs(self.repos) self.youngest = fs.youngest_rev(self.fs_ptr) self._fsroots = {} self._revinfo_cache = {} # See if a universal read access determination can be made. if self.auth and self.auth.check_universal_access(self.name) == 1: self.auth = None
def _revisionSetup(self, subpool, author, message): """ All of the setup for performing a revision. """ revision = fs.youngest_rev(self.fsob, subpool) message = re.sub('\r\n', '<CRLF>\n', message) # Convert CRLF to LF message = re.sub('\r', '<CR>', message) # Convert CR to LF transaction = repos.svn_repos_fs_begin_txn_for_commit(self.repos_ptr, revision, author, message, subpool) root = fs.txn_root(transaction, subpool) return (revision, transaction, root)
def test_get_file(self): # Test getting the properties of a file fs_revnum = fs.youngest_rev(self.fs) rev, properties = ra.get_file(self.ra_ctx, "trunk/README2.txt", core.SVN_INVALID_REVNUM, None) self.assertEqual(rev, fs_revnum) self.assertEqual(properties["svn:mime-type"], "text/plain") # Test getting the contents of a file filestream = StringIO() rev, properties = ra.get_file(self.ra_ctx, "trunk/README2.txt", fs_revnum, filestream) self.assertEqual("A test.\n", filestream.getvalue())
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 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 get_youngest_rev(self): """Retrieve the latest revision in the repository. (wraps ``fs.youngest_rev``) """ if not self.youngest: self.youngest = fs.youngest_rev(self.fs_ptr, self.pool()) if self.scope != '/': for path, rev in self._history('', 1, self.youngest, self.pool): self.youngest = rev break return self.youngest
def tweak_dates(pool, home='.'): db_path = os.path.join(home, 'db') if not os.path.exists(db_path): db_path = home fsob = fs.new(None, pool) fs.open_berkeley(fsob, db_path) for i in range(fs.youngest_rev(fsob, pool)): # convert secs into microseconds, then a string date = core.svn_time_to_cstring((DATE_BASE+i*DATE_INCR) * 1000000L, pool) #print date fs.change_rev_prop(fsob, i+1, core.SVN_PROP_REVISION_DATE, date, pool)
def __init__(self, pool, path, cmd, rev, txn): self.pool = pool repos_ptr = repos.open(path, pool) self.fs_ptr = repos.fs(repos_ptr) if txn: self.txn_ptr = fs.open_txn(self.fs_ptr, txn, pool) else: self.txn_ptr = None if rev is None: rev = fs.youngest_rev(self.fs_ptr, pool) self.rev = rev
def delete_file(self, file_name): """Deletes the given file from the repository""" assert self.svn_repos is not None, "SVN repository not set..." # Get an SVN file system pointer fs_ptr = repos.fs(self.svn_repos) rev = fs.youngest_rev(fs_ptr) # Create and SVN transaction txn = fs.begin_txn(fs_ptr, rev) txn_root = fs.txn_root(txn) # Create a file in the root transaction fs.delete(txn_root, file_name) # Commit the transaction fs.commit_txn(txn)
def main(): argc = len(sys.argv) if argc < 3 or argc > 4: print("Usage: %s PATH-TO-REPOS PATH-IN-REPOS [REVISION]" % sys.argv[0]) sys.exit(1) fs_ptr = repos.fs(repos.open(sys.argv[1])) if argc == 3: revision = fs.youngest_rev(fs_ptr) else: revision = int(sys.argv[3]) check_history(fs_ptr, sys.argv[2], revision) sys.exit(0)
def delete_files(self): """Deletes all the files created by the helper""" if self.svn_repos is not None: # Get an SVN file system pointer fs_ptr = repos.fs(self.svn_repos) rev = fs.youngest_rev(fs_ptr) # Create and SVN transaction txn = fs.begin_txn(fs_ptr, rev) txn_root = fs.txn_root(txn) # Create a file in the root transaction for svn_file in self.files: fs.delete(txn_root, svn_file) # Commit the transaction fs.commit_txn(txn)
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 setUp(self): """Load the mergeinfo-full Subversion repository. This dumpfile is created by dumping the repository generated for command line log tests 16. If it needs to be updated (mergeinfo format changes, for example), we can go there to get a new version.""" dumpfile = open(os.path.join(os.path.split(__file__)[0], 'data', 'mergeinfo.dump')) # Remove any existing repository to ensure a fresh start self.tearDown() self.repos = repos.svn_repos_create(REPOS_PATH, '', '', None, None) repos.svn_repos_load_fs2(self.repos, dumpfile, StringIO(), repos.svn_repos_load_uuid_default, '', 0, 0, None) self.fs = repos.fs(self.repos) self.rev = fs.youngest_rev(self.fs)
def my_callback(info, pool): self.assertEqual(info.revision, fs.youngest_rev(self.fs))
def test_delta_driver_commit(self): # Setup paths we'll commit in this test. to_delete = [b'trunk/README.txt', b'trunk/dir1/dir2'] to_mkdir = [ b'test_delta_driver_commit.d', b'test_delta_driver_commit2.d' ] to_add = [b'test_delta_driver_commit', b'test_delta_driver_commit2'] to_dir_prop = [b'trunk/dir1/dir3', b'test_delta_driver_commit2.d'] to_file_prop = [b'trunk/README2.txt', b'test_delta_driver_commit2'] all_paths = {} for i in to_delete + to_mkdir + to_add + to_dir_prop + to_file_prop: all_paths[i] = True # base revision for the commit revision = fs.youngest_rev(self.fs) commit_info = [] def commit_cb(info, pool): commit_info.append(info) revprops = {b"svn:log": b"foobar", b"testprop": b""} (editor, edit_baton) = ra.get_commit_editor3(self.ra_ctx, revprops, commit_cb, None, False) try: def driver_cb(parent, path, pool): self.assertTrue(path in all_paths) dir_baton = file_baton = None if path in to_delete: # Leave dir_baton alone, as it must be None for delete. editor.delete_entry(path, revision, parent, pool) elif path in to_mkdir: dir_baton = editor.add_directory( path, parent, None, -1, # copyfrom pool) elif path in to_add: file_baton = editor.add_file( path, parent, None, -1, # copyfrom pool) # wc.py:test_commit tests apply_textdelta . if path in to_dir_prop: if dir_baton is None: dir_baton = editor.open_directory( path, parent, revision, pool) editor.change_dir_prop(dir_baton, b'test_delta_driver_commit', b'foo', pool) elif path in to_file_prop: if file_baton is None: file_baton = editor.open_file(path, parent, revision, pool) editor.change_file_prop(file_baton, b'test_delta_driver_commit', b'foo', pool) if file_baton is not None: editor.close_file(file_baton, None, pool) return dir_baton delta.path_driver(editor, edit_baton, -1, core._as_list(all_paths.keys()), driver_cb) editor.close_edit(edit_baton) except: try: editor.abort_edit(edit_baton) except: # We already have an exception in progress, not much we can do # about this. pass raise info = commit_info[0] if info.author is not None: revprops[b'svn:author'] = info.author revprops[b'svn:date'] = info.date self.assertEqual(ra.rev_proplist(self.ra_ctx, info.revision), revprops) receiver_called = [False] def receiver(changed_paths, revision, author, date, message, pool): receiver_called[0] = True self.assertEqual(revision, info.revision) self.assertEqual(author, info.author) self.assertEqual(date, info.date) self.assertEqual(message, revprops[b'svn:log']) for (path, change) in core._as_list(changed_paths.items()): path = path.lstrip(b'/') self.assertTrue(path in all_paths) if path in to_delete: self.assertEqual(change.action, b'D') elif path in to_mkdir or path in to_add: self.assertEqual(change.action, b'A') elif path in to_dir_prop or path in to_file_prop: self.assertEqual(change.action, b'M') ra.get_log( self.ra_ctx, [b''], info.revision, info.revision, 0, # limit True, # discover_changed_paths True, # strict_node_history receiver) self.assertTrue(receiver_called[0])
def test_get_log2(self): # Get an interesting commit. self.test_commit3() rev = fs.youngest_rev(self.fs) revprops = ra.rev_proplist(self.ra_ctx, rev) self.assertTrue(b"svn:log" in revprops) self.assertTrue(b"testprop" in revprops) def receiver(log_entry, pool): called[0] = True self.assertEqual(log_entry.revision, rev) if discover_changed_paths: self.assertEqual(core._as_list(log_entry.changed_paths.keys()), [b'/bla3']) changed_path = log_entry.changed_paths[b'/bla3'] self.assertTrue( changed_path.action in [b'A', b'D', b'R', b'M']) self.assertEqual(changed_path.copyfrom_path, None) self.assertEqual(changed_path.copyfrom_rev, -1) else: self.assertEqual(log_entry.changed_paths, None) if log_revprops is None: self.assertEqual(log_entry.revprops, revprops) elif len(log_revprops) == 0: self.assertTrue(log_entry.revprops == None or len(log_entry.revprops) == 0) else: revprop_names = sorted(log_entry.revprops.keys()) log_revprops.sort() self.assertEqual(revprop_names, log_revprops) for i in log_revprops: self.assertEqual(log_entry.revprops[i], revprops[i], msg="%s != %s on %s" % (log_entry.revprops[i], revprops[i], (log_revprops, discover_changed_paths))) for log_revprops in ( # Retrieve the standard three. [b"svn:author", b"svn:date", b"svn:log"], # Retrieve just testprop. [b"testprop"], # Retrieve all. None, # Retrieve none. [], ): for discover_changed_paths in [True, False]: called = [False] ra.get_log2( self.ra_ctx, [b""], rev, rev, # start, end 1, # limit discover_changed_paths, True, # strict_node_history False, # include_merged_revisions log_revprops, receiver) self.assertTrue(called[0])
def commit(self, t_fs, ctx): # commit this transaction print 'committing: %s, over %d seconds' % (time.ctime( self.t_min), self.t_max - self.t_min) # create a pool for the entire commit c_pool = util.svn_pool_create(ctx.pool) rev = fs.youngest_rev(t_fs, c_pool) txn = fs.begin_txn(t_fs, rev, c_pool) root = fs.txn_root(txn, c_pool) lastcommit = (None, None) # create a pool for each file; it will be cleared on each iteration f_pool = util.svn_pool_create(c_pool) for f, r in self.changes: # compute a repository path. ensure we have a leading "/" and drop # the ,v from the file name repos_path = '/' + relative_name(ctx.cvsroot, f[:-2]) #print 'DEBUG:', repos_path print ' changing %s : %s' % (r, repos_path) ### hmm. need to clarify OS path separators vs FS path separators dirname = os.path.dirname(repos_path) if dirname != '/': # get the components of the path (skipping the leading '/') parts = string.split(dirname[1:], os.sep) for i in range(1, len(parts) + 1): # reassemble the pieces, adding a leading slash parent_dir = '/' + string.join(parts[:i], '/') if fs.check_path(root, parent_dir, f_pool) == svn_node_none: print ' making dir:', parent_dir fs.make_dir(root, parent_dir, f_pool) if fs.check_path(root, repos_path, f_pool) == svn_node_none: created_file = 1 fs.make_file(root, repos_path, f_pool) else: created_file = 0 handler, baton = fs.apply_textdelta(root, repos_path, f_pool) # figure out the real file path for "co" try: statcache.stat(f) except os.error: dirname, fname = os.path.split(f) f = os.path.join(dirname, 'Attic', fname) statcache.stat(f) pipe = os.popen('co -q -p%s %s' % (r, f), 'r', 102400) # if we just made the file, we can send it in one big hunk, rather # than streaming it in. ### we should watch out for file sizes here; we don't want to yank ### in HUGE files... if created_file: _delta.svn_txdelta_send_string(pipe.read(), handler, baton, f_pool) else: # open an SVN stream onto the pipe stream2 = util.svn_stream_from_stdio(pipe, f_pool) # Get the current file contents from the repo, or, if we have # multiple CVS revisions to the same file being done in this # single commit, then get the contents of the previous # revision from co, or else the delta won't be correct because # the contents in the repo won't have changed yet. if repos_path == lastcommit[0]: infile2 = os.popen("co -q -p%s %s" % (lastcommit[1], f), "r", 102400) stream1 = util.svn_stream_from_stdio(infile2, f_pool) else: stream1 = fs.file_contents(root, repos_path, f_pool) txstream = _delta.svn_txdelta(stream1, stream2, f_pool) _delta.svn_txdelta_send_txstream(txstream, handler, baton, f_pool) # shut down the previous-rev pipe, if we opened it infile2 = None # shut down the current-rev pipe pipe.close() # wipe the pool. this will get rid of the pipe streams and the delta # stream, and anything the FS may have done. util.svn_pool_clear(f_pool) # remember what we just did, for the next iteration lastcommit = (repos_path, r) for f, r in self.deletes: # compute a repository path. ensure we have a leading "/" and drop # the ,v from the file name repos_path = '/' + relative_name(ctx.cvsroot, f[:-2]) print ' deleting %s : %s' % (r, repos_path) # If the file was initially added on a branch, the first mainline # revision will be marked dead, and thus, attempts to delete it will # fail, since it doesn't really exist. if r != '1.1': ### need to discriminate between OS paths and FS paths fs.delete(root, repos_path, f_pool) # wipe the pool, in case the delete loads it up util.svn_pool_clear(f_pool) # get the metadata for this commit author, log, date = self.get_metadata(c_pool) fs.change_txn_prop(txn, 'svn:author', author, c_pool) fs.change_txn_prop(txn, 'svn:log', log, c_pool) conflicts, new_rev = fs.commit_txn(txn) # set the time to the proper (past) time fs.change_rev_prop(t_fs, new_rev, 'svn:date', date, c_pool) ### how come conflicts is a newline? if conflicts != '\n': print ' CONFLICTS:', ` conflicts ` print ' new revision:', new_rev # done with the commit and file pools util.svn_pool_destroy(c_pool)
def do_youngest(self, arg): """list the youngest revision available for browsing""" rev = fs.youngest_rev(self.fs_ptr) print(rev)
def my_callback(revision, date, author): self.assertEqual(revision, fs.youngest_rev(self.fs))
def test_get_latest_revnum(self): ra_revnum = ra.get_latest_revnum(self.ra_ctx) fs_revnum = fs.youngest_rev(self.fs) self.assertEqual(ra_revnum, fs_revnum)