def commit(self, paths, message, file_data, base_revision, addeddirs, deleteddirs, properties, copies): """Commits the appropriate targets from revision in editor's store. """ self.init_ra_and_client() commit_info = [] def commit_cb(_commit_info, pool): commit_info.append(_commit_info) editor, edit_baton = ra.get_commit_editor2(self.ra, message, commit_cb, None, False, self.pool) checksum = [] # internal dir batons can fall out of scope and get GCed before svn is # done with them. This prevents that (credit to gvn for the idea). batons = [edit_baton, ] def driver_cb(parent, path, pool): if not parent: bat = editor.open_root(edit_baton, base_revision, self.pool) batons.append(bat) return bat if path in deleteddirs: bat = editor.delete_entry(path, base_revision, parent, pool) batons.append(bat) return bat if path not in file_data: if path in addeddirs: bat = editor.add_directory(path, parent, None, -1, pool) else: bat = editor.open_directory(path, parent, base_revision, pool) batons.append(bat) props = properties.get(path, {}) if 'svn:externals' in props: value = props['svn:externals'] editor.change_dir_prop(bat, 'svn:externals', value, pool) return bat base_text, new_text, action = file_data[path] compute_delta = True if action == 'modify': baton = editor.open_file(path, parent, base_revision, pool) elif action == 'add': frompath, fromrev = copies.get(path, (None, -1)) if frompath: frompath = self.path2url(frompath) baton = editor.add_file(path, parent, frompath, fromrev, pool) elif action == 'delete': baton = editor.delete_entry(path, base_revision, parent, pool) compute_delta = False if path in properties: if properties[path].get('svn:special', None): new_text = 'link %s' % new_text for p, v in properties[path].iteritems(): editor.change_file_prop(baton, p, v) if compute_delta: handler, wh_baton = editor.apply_textdelta(baton, None, self.pool) txdelta_stream = delta.svn_txdelta( cStringIO.StringIO(base_text), cStringIO.StringIO(new_text), self.pool) delta.svn_txdelta_send_txstream(txdelta_stream, handler, wh_baton, pool) # TODO pass md5(new_text) instead of None editor.close_file(baton, None, pool) delta.path_driver(editor, edit_baton, base_revision, paths, driver_cb, self.pool) editor.close_edit(edit_baton, self.pool)
def test_commit(self): # Replace README.txt's contents, using binary mode so we know the # exact contents even on Windows, and therefore the MD5 checksum. readme_path = '%s/trunk/README.txt' % self.path fp = open(readme_path, 'wb') fp.write('hello\n') fp.close() # Setup ra_ctx. ra.initialize() callbacks = ra.Callbacks() ra_ctx = ra.open2(REPOS_URL, callbacks, None, None) # Get commit editor. commit_info = [None] def commit_cb(_commit_info, pool): commit_info[0] = _commit_info (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, 'log message', commit_cb, None, False) # Drive the commit. checksum = [None] def driver_cb(parent, path, pool): baton = editor.open_file(path, parent, -1, pool) adm_access = wc.adm_probe_retrieve(self.wc, readme_path, pool) (_, checksum[0]) = wc.transmit_text_deltas2(readme_path, adm_access, False, editor, baton, pool) return baton try: delta.path_driver(editor, edit_baton, -1, ['trunk/README.txt'], 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 (checksum, ) = checksum (commit_info, ) = commit_info # Assert the commit. self.assertEquals(binascii.b2a_hex(checksum), 'b1946ac92492d2347c6235b4d2611184') self.assertEquals(commit_info.revision, 13) # Bump working copy state. wc.process_committed4( readme_path, wc.adm_retrieve(self.wc, os.path.dirname(readme_path)), False, commit_info.revision, commit_info.date, commit_info.author, None, False, False, checksum) # Assert bumped state. entry = wc.entry(readme_path, self.wc, False) self.assertEquals(entry.revision, commit_info.revision) self.assertEquals(entry.schedule, wc.schedule_normal) self.assertEquals(entry.cmt_rev, commit_info.revision) self.assertEquals(entry.cmt_date, core.svn_time_from_cstring(commit_info.date))
def test_delta_driver_commit(self): # Setup paths we'll commit in this test. to_delete = ['trunk/README.txt', 'trunk/dir1/dir2'] to_mkdir = ['test_delta_driver_commit.d', 'test_delta_driver_commit2.d'] to_add = ['test_delta_driver_commit', 'test_delta_driver_commit2'] to_dir_prop = ['trunk/dir1/dir3', 'test_delta_driver_commit2.d'] to_file_prop = ['trunk/README2.txt', '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 = {"svn:log": "foobar", "testprop": ""} (editor, edit_baton) = ra.get_commit_editor3(self.ra_ctx, revprops, commit_cb, None, False) try: def driver_cb(parent, path, pool): self.assert_(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, 'test_delta_driver_commit', '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, 'test_delta_driver_commit', '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, 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['svn:author'] = info.author revprops['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['svn:log']) for (path, change) in changed_paths.iteritems(): path = path.lstrip('/') self.assert_(path in all_paths) if path in to_delete: self.assertEqual(change.action, 'D') elif path in to_mkdir or path in to_add: self.assertEqual(change.action, 'A') elif path in to_dir_prop or path in to_file_prop: self.assertEqual(change.action, 'M') ra.get_log(self.ra_ctx, [''], info.revision, info.revision, 0, # limit True, # discover_changed_paths True, # strict_node_history receiver) self.assert_(receiver_called[0])
def commit(self, paths, message, file_data, base_revision, addeddirs, deleteddirs, properties, copies): """Commits the appropriate targets from revision in editor's store. Return the committed revision as a common.Revision instance. """ self.init_ra_and_client() def commit_cb(commit_info, pool): # disregard commit_info.post_commit_err for now r = common.Revision(commit_info.revision, commit_info.author, message, commit_info.date) committedrev.append(r) committedrev = [] editor, edit_baton = ra.get_commit_editor2(self.ra, message, commit_cb, None, False, self.pool) checksum = [] # internal dir batons can fall out of scope and get GCed before svn is # done with them. This prevents that (credit to gvn for the idea). batons = [ edit_baton, ] def driver_cb(parent, path, pool): if not parent: bat = editor.open_root(edit_baton, base_revision, self.pool) batons.append(bat) return bat if path in deleteddirs: bat = editor.delete_entry(path, base_revision, parent, pool) batons.append(bat) if path not in addeddirs: return bat if path not in file_data: if path in addeddirs: frompath, fromrev = copies.get(path, (None, -1)) if frompath: frompath = self.path2url(frompath) bat = editor.add_directory(path, parent, frompath, fromrev, pool) else: bat = editor.open_directory(path, parent, base_revision, pool) batons.append(bat) props = properties.get(path, {}) if 'svn:externals' in props: value = props['svn:externals'] editor.change_dir_prop(bat, 'svn:externals', value, pool) return bat base_text, new_text, action = file_data[path] compute_delta = True if action == 'modify': baton = editor.open_file(path, parent, base_revision, pool) elif action == 'add': frompath, fromrev = copies.get(path, (None, -1)) if frompath: frompath = self.path2url(frompath) baton = editor.add_file(path, parent, frompath, fromrev, pool) elif action == 'delete': baton = editor.delete_entry(path, base_revision, parent, pool) compute_delta = False if path in properties: if properties[path].get('svn:special', None): new_text = 'link %s' % new_text for p, v in properties[path].iteritems(): editor.change_file_prop(baton, p, v) if compute_delta: handler, wh_baton = editor.apply_textdelta( baton, None, self.pool) txdelta_stream = delta.svn_txdelta( cStringIO.StringIO(base_text), cStringIO.StringIO(new_text), self.pool) delta.svn_txdelta_send_txstream(txdelta_stream, handler, wh_baton, pool) # TODO pass md5(new_text) instead of None editor.close_file(baton, None, pool) try: delta.path_driver(editor, edit_baton, base_revision, paths, driver_cb, self.pool) except: # If anything went wrong on the preceding lines, we should # abort the in-progress transaction. editor.abort_edit(edit_baton, self.pool) raise editor.close_edit(edit_baton, self.pool) return committedrev.pop()
def test_delta_driver_commit(self): # Setup paths we'll commit in this test. to_delete = ['trunk/README.txt', 'trunk/dir1/dir2'] to_mkdir = [ 'test_delta_driver_commit.d', 'test_delta_driver_commit2.d' ] to_add = ['test_delta_driver_commit', 'test_delta_driver_commit2'] to_dir_prop = ['trunk/dir1/dir3', 'test_delta_driver_commit2.d'] to_file_prop = ['trunk/README2.txt', '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 = {"svn:log": "foobar", "testprop": ""} (editor, edit_baton) = ra.get_commit_editor3(self.ra_ctx, revprops, commit_cb, None, False) try: def driver_cb(parent, path, pool): self.assert_(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, 'test_delta_driver_commit', '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, 'test_delta_driver_commit', '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, 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['svn:author'] = info.author revprops['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['svn:log']) for (path, change) in changed_paths.items(): path = path.lstrip('/') self.assert_(path in all_paths) if path in to_delete: self.assertEqual(change.action, 'D') elif path in to_mkdir or path in to_add: self.assertEqual(change.action, 'A') elif path in to_dir_prop or path in to_file_prop: self.assertEqual(change.action, 'M') ra.get_log( self.ra_ctx, [''], info.revision, info.revision, 0, # limit True, # discover_changed_paths True, # strict_node_history receiver) self.assert_(receiver_called[0])
def test_commit(self): # Replace README.txt's contents, using binary mode so we know the # exact contents even on Windows, and therefore the MD5 checksum. readme_path = "%s/trunk/README.txt" % self.path fp = open(readme_path, "wb") fp.write("hello\n") fp.close() # Setup ra_ctx. ra.initialize() callbacks = ra.Callbacks() ra_ctx = ra.open2(REPOS_URL, callbacks, None, None) # Get commit editor. commit_info = [None] def commit_cb(_commit_info, pool): commit_info[0] = _commit_info (editor, edit_baton) = ra.get_commit_editor2(ra_ctx, "log message", commit_cb, None, False) # Drive the commit. checksum = [None] def driver_cb(parent, path, pool): baton = editor.open_file(path, parent, -1, pool) adm_access = wc.adm_probe_retrieve(self.wc, readme_path, pool) (_, checksum[0]) = wc.transmit_text_deltas2(readme_path, adm_access, False, editor, baton, pool) return baton try: delta.path_driver(editor, edit_baton, -1, ["trunk/README.txt"], 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 (checksum,) = checksum (commit_info,) = commit_info # Assert the commit. self.assertEquals(binascii.b2a_hex(checksum), "b1946ac92492d2347c6235b4d2611184") self.assertEquals(commit_info.revision, 13) # Bump working copy state. wc.process_committed4( readme_path, wc.adm_retrieve(self.wc, os.path.dirname(readme_path)), False, commit_info.revision, commit_info.date, commit_info.author, None, False, False, checksum, ) # Assert bumped state. entry = wc.entry(readme_path, self.wc, False) self.assertEquals(entry.revision, commit_info.revision) self.assertEquals(entry.schedule, wc.schedule_normal) self.assertEquals(entry.cmt_rev, commit_info.revision) self.assertEquals(entry.cmt_date, core.svn_time_from_cstring(commit_info.date))