/* This implements svn_editor_cb_copy_t */ static svn_error_t * copy_cb(void *baton, const char *src_relpath, svn_revnum_t src_revision, const char *dst_relpath, svn_revnum_t replaces_rev, apr_pool_t *scratch_pool) { struct edit_baton *eb = baton; const char *src_fspath = FSPATH(src_relpath, scratch_pool); const char *dst_fspath = FSPATH(dst_relpath, scratch_pool); svn_fs_root_t *root; svn_fs_root_t *src_root; SVN_ERR(get_root(&root, eb)); /* Check if we can we replace the maybe-specified destination (revision). */ if (SVN_IS_VALID_REVNUM(replaces_rev)) { SVN_ERR(can_modify(root, dst_fspath, replaces_rev, scratch_pool)); SVN_ERR(svn_fs_delete(root, dst_fspath, scratch_pool)); } else { SVN_ERR(can_create(root, dst_fspath, scratch_pool)); } SVN_ERR(svn_fs_revision_root(&src_root, svn_fs_root_fs(root), src_revision, scratch_pool)); SVN_ERR(svn_fs_copy(src_root, src_fspath, root, dst_fspath, scratch_pool)); svn_fs_close_root(src_root); return SVN_NO_ERROR; }
/* This implements svn_editor_cb_add_file_t */ static svn_error_t * add_file_cb(void *baton, const char *relpath, const svn_checksum_t *checksum, svn_stream_t *contents, apr_hash_t *props, svn_revnum_t replaces_rev, apr_pool_t *scratch_pool) { struct edit_baton *eb = baton; const char *fspath = FSPATH(relpath, scratch_pool); svn_fs_root_t *root; SVN_ERR(get_root(&root, eb)); if (SVN_IS_VALID_REVNUM(replaces_rev)) { SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool)); SVN_ERR(svn_fs_delete(root, fspath, scratch_pool)); } else { SVN_ERR(can_create(root, fspath, scratch_pool)); } SVN_ERR(svn_fs_make_file(root, fspath, scratch_pool)); SVN_ERR(set_text(root, fspath, checksum, contents, eb->cancel_func, eb->cancel_baton, scratch_pool)); SVN_ERR(add_new_props(root, fspath, props, scratch_pool)); return SVN_NO_ERROR; }
/* This implements svn_editor_cb_add_directory_t */ static svn_error_t * add_directory_cb(void *baton, const char *relpath, const apr_array_header_t *children, apr_hash_t *props, svn_revnum_t replaces_rev, apr_pool_t *scratch_pool) { struct edit_baton *eb = baton; const char *fspath = FSPATH(relpath, scratch_pool); svn_fs_root_t *root; /* Note: we ignore CHILDREN. We have no "incomplete" state to worry about, so we don't need to be aware of what children will be created. */ SVN_ERR(get_root(&root, eb)); if (SVN_IS_VALID_REVNUM(replaces_rev)) { SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool)); SVN_ERR(svn_fs_delete(root, fspath, scratch_pool)); } else { SVN_ERR(can_create(root, fspath, scratch_pool)); } SVN_ERR(svn_fs_make_dir(root, fspath, scratch_pool)); SVN_ERR(add_new_props(root, fspath, props, scratch_pool)); return SVN_NO_ERROR; }
/* This implements svn_editor_cb_move_t */ static svn_error_t * move_cb(void *baton, const char *src_relpath, svn_revnum_t src_revision, const char *dst_relpath, svn_revnum_t replaces_rev, apr_pool_t *scratch_pool) { struct edit_baton *eb = baton; const char *src_fspath = FSPATH(src_relpath, scratch_pool); const char *dst_fspath = FSPATH(dst_relpath, scratch_pool); svn_fs_root_t *root; svn_fs_root_t *src_root; SVN_ERR(get_root(&root, eb)); /* Check if we delete the specified source (revision), and can we replace the maybe-specified destination (revision). */ SVN_ERR(can_modify(root, src_fspath, src_revision, scratch_pool)); if (SVN_IS_VALID_REVNUM(replaces_rev)) { SVN_ERR(can_modify(root, dst_fspath, replaces_rev, scratch_pool)); SVN_ERR(svn_fs_delete(root, dst_fspath, scratch_pool)); } else { SVN_ERR(can_create(root, dst_fspath, scratch_pool)); } /* ### would be nice to have svn_fs_move() */ /* Copy the src to the dst. */ SVN_ERR(svn_fs_revision_root(&src_root, svn_fs_root_fs(root), src_revision, scratch_pool)); SVN_ERR(svn_fs_copy(src_root, src_fspath, root, dst_fspath, scratch_pool)); svn_fs_close_root(src_root); /* Notice: we're deleting the src repos path from the dst root. */ SVN_ERR(svn_fs_delete(root, src_fspath, scratch_pool)); return SVN_NO_ERROR; }
static svn_error_t * test_delete_entry(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *pool) { struct dir_baton *pb = parent_baton; /* Construct the full path of this entry and delete it from the txn. */ return svn_fs_delete(pb->edit_baton->txn_root, svn_path_join(pb->edit_baton->root_path, path, pool), pool); }
/* This implements svn_editor_cb_delete_t */ static svn_error_t * delete_cb(void *baton, const char *relpath, svn_revnum_t revision, apr_pool_t *scratch_pool) { struct edit_baton *eb = baton; const char *fspath = FSPATH(relpath, scratch_pool); svn_fs_root_t *root; SVN_ERR(get_root(&root, eb)); SVN_ERR(can_modify(root, fspath, revision, scratch_pool)); SVN_ERR(svn_fs_delete(root, fspath, scratch_pool)); return SVN_NO_ERROR; }
static svn_error_t * delete_entry(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *pool) { struct dir_baton *parent = parent_baton; struct edit_baton *eb = parent->edit_baton; svn_node_kind_t kind; svn_revnum_t cr_rev; svn_repos_authz_access_t required = svn_authz_write; const char *full_path; full_path = svn_fspath__join(eb->base_path, svn_relpath_canonicalize(path, pool), pool); /* Check PATH in our transaction. */ SVN_ERR(svn_fs_check_path(&kind, eb->txn_root, full_path, pool)); /* Deletion requires a recursive write access, as well as write access to the parent directory. */ if (kind == svn_node_dir) required |= svn_authz_recursive; SVN_ERR(check_authz(eb, full_path, eb->txn_root, required, pool)); SVN_ERR(check_authz(eb, parent->path, eb->txn_root, svn_authz_write, pool)); /* If PATH doesn't exist in the txn, the working copy is out of date. */ if (kind == svn_node_none) return out_of_date(full_path, kind); /* Now, make sure we're deleting the node we *think* we're deleting, else return an out-of-dateness error. */ SVN_ERR(svn_fs_node_created_rev(&cr_rev, eb->txn_root, full_path, pool)); if (SVN_IS_VALID_REVNUM(revision) && (revision < cr_rev)) return out_of_date(full_path, kind); /* This routine is a mindless wrapper. We call svn_fs_delete() because that will delete files and recursively delete directories. */ return svn_fs_delete(eb->txn_root, full_path, pool); }
/* This implements svn_editor_cb_add_symlink_t */ static svn_error_t * add_symlink_cb(void *baton, const char *relpath, const char *target, apr_hash_t *props, svn_revnum_t replaces_rev, apr_pool_t *scratch_pool) { struct edit_baton *eb = baton; const char *fspath = FSPATH(relpath, scratch_pool); svn_fs_root_t *root; SVN_ERR(get_root(&root, eb)); if (SVN_IS_VALID_REVNUM(replaces_rev)) { SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool)); SVN_ERR(svn_fs_delete(root, fspath, scratch_pool)); } else { SVN_ERR(can_create(root, fspath, scratch_pool)); } /* ### we probably need to construct a file with specific contents ### (until the FS grows some symlink APIs) */ #if 0 SVN_ERR(svn_fs_make_file(root, fspath, scratch_pool)); SVN_ERR(svn_fs_apply_text(&fs_contents, root, fspath, NULL /* result_checksum */, scratch_pool)); /* ### SVN_ERR(svn_stream_printf(fs_contents, ..., scratch_pool)); */ apr_hash_set(props, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING, SVN_PROP_SPECIAL_VALUE); SVN_ERR(add_new_props(root, fspath, props, scratch_pool)); #endif SVN__NOT_IMPLEMENTED(); }
static svn_error_t * new_node_record(void **node_baton, apr_hash_t *headers, void *revision_baton, apr_pool_t *pool) { struct revision_baton *rb = revision_baton; struct parse_baton *pb = rb->pb; struct node_baton *nb; if (rb->rev == 0) return svn_error_create(SVN_ERR_STREAM_MALFORMED_DATA, NULL, _("Malformed dumpstream: " "Revision 0 must not contain node records")); SVN_ERR(make_node_baton(&nb, headers, rb, pool)); /* If we're skipping this revision, we're done here. */ if (rb->skipped) { *node_baton = nb; return SVN_NO_ERROR; } /* Make sure we have an action we recognize. */ if (nb->action < svn_node_action_change || nb->action > svn_node_action_replace) return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL, _("Unrecognized node-action on node '%s'"), nb->path); if (pb->notify_func) { /* ### TODO: Use proper scratch pool instead of pb->notify_pool */ svn_repos_notify_t *notify = svn_repos_notify_create( svn_repos_notify_load_node_start, pb->notify_pool); notify->path = nb->path; pb->notify_func(pb->notify_baton, notify, pb->notify_pool); svn_pool_clear(pb->notify_pool); } switch (nb->action) { case svn_node_action_change: break; case svn_node_action_delete: SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool)); break; case svn_node_action_add: SVN_ERR(maybe_add_with_history(nb, rb, pool)); break; case svn_node_action_replace: SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool)); SVN_ERR(maybe_add_with_history(nb, rb, pool)); break; } *node_baton = nb; return SVN_NO_ERROR; }