You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2014/10/27 17:52:23 UTC
svn commit: r1634591 [3/4] - in
/subversion/branches/move-tracking-2/subversion:
include/private/svn_editor3.h libsvn_delta/compat3.c libsvn_delta/editor3.c
libsvn_ra/ra_loader.c svnmover/svnmover.c
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c?rev=1634591&r1=1634590&r2=1634591&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/editor3.c Mon Oct 27 16:52:23 2014
@@ -27,6 +27,7 @@
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_dirent_uri.h"
+#include "svn_props.h"
#include "private/svn_editor3.h"
@@ -112,7 +113,7 @@ svn_editor3_create(svn_editor3_t **edito
void *
-svn_editor3_get_baton(const svn_editor3_t *editor)
+svn_editor3__get_baton(const svn_editor3_t *editor)
{
return editor->baton;
}
@@ -265,21 +266,61 @@ svn_editor3_put(svn_editor3_t *editor,
* ========================================================================
*/
+#define VALID_NODE_KIND(kind) ((kind) != svn_node_unknown && (kind) != svn_node_none)
+#define VALID_EID(eid) ((eid) >= 0)
+#define VALID_NAME(name) ((name) && (name)[0] && svn_relpath_is_canonical(name))
+#define VALID_CONTENT(content) ((content) && VALID_NODE_KIND((content)->kind))
+
svn_error_t *
svn_editor3_add(svn_editor3_t *editor,
- svn_editor3_nbid_t local_nbid,
+ svn_editor3_nbid_t *local_nbid_p,
svn_node_kind_t new_kind,
svn_editor3_nbid_t new_parent_nbid,
const char *new_name,
const svn_editor3_node_content_t *new_content)
{
- /* SVN_ERR_ASSERT(...); */
+ int eid = -1;
+
+ SVN_ERR_ASSERT(VALID_NODE_KIND(new_kind));
+ SVN_ERR_ASSERT(VALID_EID(new_parent_nbid));
+ SVN_ERR_ASSERT(VALID_NAME(new_name));
+ SVN_ERR_ASSERT(VALID_CONTENT(new_content));
+ SVN_ERR_ASSERT(new_content->kind == new_kind);
DO_CALLBACK(editor, cb_add,
- 5(local_nbid, new_kind,
+ 5(&eid, new_kind,
new_parent_nbid, new_name,
new_content));
+ SVN_ERR_ASSERT(VALID_EID(eid));
+
+ /* We allow the output pointer to be null, here, so that implementations
+ may assume their output pointer is non-null. */
+ if (local_nbid_p)
+ *local_nbid_p = eid;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_editor3_instantiate(svn_editor3_t *editor,
+ svn_editor3_nbid_t local_nbid,
+ svn_node_kind_t new_kind,
+ svn_editor3_nbid_t new_parent_nbid,
+ const char *new_name,
+ const svn_editor3_node_content_t *new_content)
+{
+ SVN_ERR_ASSERT(VALID_NODE_KIND(new_kind));
+ SVN_ERR_ASSERT(VALID_EID(local_nbid));
+ SVN_ERR_ASSERT(VALID_EID(new_parent_nbid));
+ SVN_ERR_ASSERT(VALID_NAME(new_name));
+ SVN_ERR_ASSERT(VALID_CONTENT(new_content));
+ SVN_ERR_ASSERT(new_content->kind == new_kind);
+
+ DO_CALLBACK(editor, cb_instantiate,
+ 5(local_nbid, new_kind,
+ new_parent_nbid, new_name,
+ new_content));
return SVN_NO_ERROR;
}
@@ -292,7 +333,12 @@ svn_editor3_copy_one(svn_editor3_t *edit
const char *new_name,
const svn_editor3_node_content_t *new_content)
{
- /* SVN_ERR_ASSERT(...); */
+ SVN_ERR_ASSERT(VALID_EID(local_nbid));
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(src_revision));
+ SVN_ERR_ASSERT(VALID_EID(src_nbid));
+ SVN_ERR_ASSERT(VALID_EID(new_parent_nbid));
+ SVN_ERR_ASSERT(VALID_NAME(new_name));
+ SVN_ERR_ASSERT(! new_content || VALID_CONTENT(new_content));
DO_CALLBACK(editor, cb_copy_one,
6(local_nbid,
@@ -310,7 +356,10 @@ svn_editor3_copy_tree(svn_editor3_t *edi
svn_editor3_nbid_t new_parent_nbid,
const char *new_name)
{
- /* SVN_ERR_ASSERT(...); */
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(src_revision));
+ SVN_ERR_ASSERT(VALID_EID(src_nbid));
+ SVN_ERR_ASSERT(VALID_EID(new_parent_nbid));
+ SVN_ERR_ASSERT(VALID_NAME(new_name));
DO_CALLBACK(editor, cb_copy_tree,
4(src_revision, src_nbid,
@@ -324,7 +373,7 @@ svn_editor3_delete(svn_editor3_t *editor
svn_revnum_t since_rev,
svn_editor3_nbid_t nbid)
{
- /* SVN_ERR_ASSERT(...); */
+ SVN_ERR_ASSERT(VALID_EID(nbid));
DO_CALLBACK(editor, cb_delete,
2(since_rev, nbid));
@@ -340,7 +389,10 @@ svn_editor3_alter(svn_editor3_t *editor,
const char *new_name,
const svn_editor3_node_content_t *new_content)
{
- /* SVN_ERR_ASSERT(...); */
+ SVN_ERR_ASSERT(VALID_EID(nbid));
+ SVN_ERR_ASSERT(VALID_EID(new_parent_nbid));
+ SVN_ERR_ASSERT(VALID_NAME(new_name));
+ SVN_ERR_ASSERT(! new_content || VALID_CONTENT(new_content));
DO_CALLBACK(editor, cb_alter,
5(since_rev, nbid,
@@ -384,6 +436,73 @@ svn_editor3_abort(svn_editor3_t *editor)
*/
svn_editor3_node_content_t *
+svn_editor3_node_content_dup(const svn_editor3_node_content_t *old,
+ apr_pool_t *result_pool)
+{
+ svn_editor3_node_content_t *new_content;
+
+ if (old == NULL)
+ return NULL;
+
+ new_content = apr_pmemdup(result_pool, old, sizeof(*new_content));
+ if (old->props)
+ new_content->props = svn_prop_hash_dup(old->props, result_pool);
+ if (old->kind == svn_node_file && old->text)
+ new_content->text = svn_stringbuf_dup(old->text, result_pool);
+ if (old->kind == svn_node_symlink && old->target)
+ new_content->target = apr_pstrdup(result_pool, old->target);
+ return new_content;
+}
+
+svn_boolean_t
+svn_editor3_node_content_equal(const svn_editor3_node_content_t *left,
+ const svn_editor3_node_content_t *right,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *prop_diffs;
+
+ /* references are not supported */
+ SVN_ERR_ASSERT_NO_RETURN(! left->ref.relpath && ! right->ref.relpath);
+ SVN_ERR_ASSERT_NO_RETURN(left->kind != svn_node_unknown
+ && right->kind != svn_node_unknown);
+
+ if (left->kind != right->kind)
+ {
+ return FALSE;
+ }
+
+ svn_error_clear(svn_prop_diffs(&prop_diffs,
+ left->props, right->props,
+ scratch_pool));
+
+ if (prop_diffs->nelts != 0)
+ {
+ return FALSE;
+ }
+ switch (left->kind)
+ {
+ case svn_node_dir:
+ break;
+ case svn_node_file:
+ if (! svn_stringbuf_compare(left->text, right->text))
+ {
+ return FALSE;
+ }
+ break;
+ case svn_node_symlink:
+ if (strcmp(left->target, right->target) != 0)
+ {
+ return FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+svn_editor3_node_content_t *
svn_editor3_node_content_create_ref(svn_editor3_peg_path_t ref,
apr_pool_t *result_pool)
{
@@ -504,7 +623,7 @@ static const char *
nbid_str(svn_editor3_nbid_t nbid,
apr_pool_t *result_pool)
{
- return txn_path_str(nbid, result_pool);
+ return apr_psprintf(result_pool, "%d", nbid);
}
static svn_error_t *
@@ -612,7 +731,7 @@ wrap_put(void *baton,
static svn_error_t *
wrap_add(void *baton,
- svn_editor3_nbid_t local_nbid,
+ svn_editor3_nbid_t *local_nbid,
svn_node_kind_t new_kind,
svn_editor3_nbid_t new_parent_nbid,
const char *new_name,
@@ -621,8 +740,8 @@ wrap_add(void *baton,
{
wrapper_baton_t *eb = baton;
- dbg(eb, scratch_pool, "%s : add(k=%s, p=%s, n=%s, c=...)",
- nbid_str(local_nbid, scratch_pool), svn_node_kind_to_word(new_kind),
+ dbg(eb, scratch_pool, "... : add(k=%s, p=%s, n=%s, c=...)",
+ svn_node_kind_to_word(new_kind),
nbid_str(new_parent_nbid, scratch_pool), new_name);
SVN_ERR(svn_editor3_add(eb->wrapped_editor,
local_nbid, new_kind,
@@ -631,6 +750,26 @@ wrap_add(void *baton,
}
static svn_error_t *
+wrap_instantiate(void *baton,
+ svn_editor3_nbid_t local_nbid,
+ svn_node_kind_t new_kind,
+ svn_editor3_nbid_t new_parent_nbid,
+ const char *new_name,
+ const svn_editor3_node_content_t *new_content,
+ apr_pool_t *scratch_pool)
+{
+ wrapper_baton_t *eb = baton;
+
+ dbg(eb, scratch_pool, "%s : instantiate(k=%s, p=%s, n=%s, c=...)",
+ nbid_str(local_nbid, scratch_pool), svn_node_kind_to_word(new_kind),
+ nbid_str(new_parent_nbid, scratch_pool), new_name);
+ SVN_ERR(svn_editor3_instantiate(eb->wrapped_editor,
+ local_nbid, new_kind,
+ new_parent_nbid, new_name, new_content));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
wrap_copy_one(void *baton,
svn_editor3_nbid_t local_nbid,
svn_revnum_t src_revision,
@@ -743,6 +882,7 @@ svn_editor3__get_debug_editor(svn_editor
wrap_rm,
wrap_put,
wrap_add,
+ wrap_instantiate,
wrap_copy_one,
wrap_copy_tree,
wrap_delete,
Modified: subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c?rev=1634591&r1=1634590&r2=1634591&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_ra/ra_loader.c Mon Oct 27 16:52:23 2014
@@ -54,6 +54,8 @@
#include "private/svn_ra_private.h"
#include "private/svn_delta_private.h"
+#include "private/svn_string_private.h"
+#include "../libsvn_delta/debug_editor.h"
#include "svn_private_config.h"
@@ -700,12 +702,152 @@ svn_error_t *svn_ra_rev_prop(svn_ra_sess
return session->vtable->rev_prop(session, rev, name, value, pool);
}
+/* The default branching metadata for a new repository. */
+static const char *default_repos_info
+ = "r0: fids 0 1 root-fid 0\n"
+ "f0: bids 0 1 eids 0 1 parent-fid 0\n"
+ "f0b0: root-eid 0 at .\n"
+ "f0b0e0: -1 . .\n";
+
+/* Create a new revision-root object and read the move-tracking /
+ * branch-tracking metadata from the repository into it.
+ */
+static svn_error_t *
+svn_branch_revision_fetch_info(svn_branch_revision_root_t **rev_root_p,
+ int *next_fid_p,
+ svn_branch_repos_t *repos,
+ svn_ra_session_t *ra_session,
+ svn_revnum_t revision,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_string_t *value;
+ svn_stream_t *stream;
+ svn_branch_revision_root_t *rev_root;
+
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
+
+ /* Read initial state from repository */
+ SVN_ERR(svn_ra_rev_prop(ra_session, revision, "svn-br-info", &value,
+ scratch_pool));
+ if (! value && revision == 0)
+ {
+ value = svn_string_create(default_repos_info, scratch_pool);
+ SVN_DBG(("fetch_per_revision_info(r%ld): LOADED DEFAULT INFO:\n%s",
+ revision, value->data));
+ SVN_ERR(svn_ra_change_rev_prop2(ra_session, revision, "svn-br-info",
+ NULL, value, scratch_pool));
+ }
+ SVN_ERR_ASSERT(value);
+ stream = svn_stream_from_string(value, scratch_pool);
+
+ SVN_ERR(svn_branch_revision_root_parse(&rev_root, next_fid_p, repos, stream,
+ result_pool, scratch_pool));
+
+ /* Self-test: writing out the info should produce exactly the same string. */
+ {
+ svn_stringbuf_t *buf = svn_stringbuf_create_empty(scratch_pool);
+
+ stream = svn_stream_from_stringbuf(buf, scratch_pool);
+ SVN_ERR(svn_branch_revision_root_serialize(stream, rev_root, *next_fid_p,
+ scratch_pool));
+ SVN_ERR(svn_stream_close(stream));
+
+ SVN_ERR_ASSERT(svn_string_compare(value,
+ svn_stringbuf__morph_into_string(buf)));
+ }
+
+ *rev_root_p = rev_root;
+ return SVN_NO_ERROR;
+}
+
+/* Create a new repository object and read the move-tracking /
+ * branch-tracking metadata from the repository into it.
+ */
+static svn_error_t *
+svn_branch_repos_fetch_info(svn_branch_repos_t **repos_p,
+ svn_ra_session_t *ra_session,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_branch_repos_t *repos
+ = svn_branch_repos_create(result_pool);
+ svn_revnum_t base_revision;
+ svn_revnum_t r;
+
+ SVN_ERR(svn_ra_get_latest_revnum(ra_session, &base_revision, scratch_pool));
+
+ repos->next_fid = 0;
+ for (r = 0; r <= base_revision; r++)
+ {
+ svn_branch_revision_root_t *rev_root;
+ int next_fid;
+
+ SVN_ERR(svn_branch_revision_fetch_info(&rev_root, &next_fid,
+ repos, ra_session, r,
+ result_pool, scratch_pool));
+ APR_ARRAY_PUSH(repos->rev_roots, void *) = rev_root;
+ repos->next_fid = MAX(repos->next_fid, next_fid);
+ }
+
+ *repos_p = repos;
+ return SVN_NO_ERROR;
+}
+
+/* Return a mutable state for the youngest revision in REPOS.
+ */
+static svn_error_t *
+svn_branch_get_mutable_state(svn_branch_revision_root_t **rev_root_p,
+ svn_branch_repos_t *repos,
+ svn_ra_session_t *ra_session,
+ svn_revnum_t base_revision,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ int next_fid;
+
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(base_revision));
+
+ SVN_ERR(svn_branch_revision_fetch_info(rev_root_p, &next_fid,
+ repos, ra_session, base_revision,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* Store the move-tracking / branch-tracking metadata from REV_ROOT into the
+ * repository.
+ */
+static svn_error_t *
+store_repos_info(svn_branch_revision_root_t *rev_root,
+ svn_ra_session_t *ra_session,
+ apr_pool_t *scratch_pool)
+{
+ svn_branch_repos_t *repos = rev_root->repos;
+ svn_stringbuf_t *buf = svn_stringbuf_create_empty(scratch_pool);
+ svn_stream_t *stream = svn_stream_from_stringbuf(buf, scratch_pool);
+ svn_revnum_t youngest_rev;
+
+ SVN_ERR(svn_branch_revision_root_serialize(stream, rev_root, repos->next_fid,
+ scratch_pool));
+
+ SVN_ERR(svn_stream_close(stream));
+ /*SVN_DBG(("store_repos_info: %s", buf->data));*/
+ SVN_ERR(svn_ra_get_latest_revnum(ra_session, &youngest_rev,
+ scratch_pool));
+ SVN_ERR(svn_ra_change_rev_prop2(ra_session, youngest_rev, "svn-br-info",
+ NULL, svn_stringbuf__morph_into_string(buf),
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
struct ccw_baton
{
svn_commit_callback2_t original_callback;
void *original_baton;
svn_ra_session_t *session;
+ svn_branch_revision_root_t *branching_txn;
};
/* Wrapper which populates the repos_root field of the commit_info struct */
@@ -719,7 +861,16 @@ commit_callback_wrapper(const svn_commit
SVN_ERR(svn_ra_get_repos_root2(ccwb->session, &ci->repos_root, pool));
- return ccwb->original_callback(ci, ccwb->original_baton, pool);
+ SVN_ERR(ccwb->original_callback(ci, ccwb->original_baton, pool));
+
+ /* if this commit used element-branching info, store the new info */
+ if (ccwb->branching_txn)
+ {
+ ccwb->branching_txn->rev = commit_info->revision;
+ SVN_ERR(store_repos_info(ccwb->branching_txn, ccwb->session, pool));
+ }
+
+ return SVN_NO_ERROR;
}
@@ -730,6 +881,7 @@ static void
remap_commit_callback(svn_commit_callback2_t *callback,
void **callback_baton,
svn_ra_session_t *session,
+ svn_branch_revision_root_t *branching_txn,
svn_commit_callback2_t original_callback,
void *original_baton,
apr_pool_t *result_pool)
@@ -746,6 +898,7 @@ remap_commit_callback(svn_commit_callbac
struct ccw_baton *ccwb = apr_palloc(result_pool, sizeof(*ccwb));
ccwb->session = session;
+ ccwb->branching_txn = branching_txn;
ccwb->original_callback = original_callback;
ccwb->original_baton = original_baton;
@@ -839,12 +992,24 @@ svn_error_t *svn_ra_get_commit_editor_ev
svn_boolean_t keep_locks,
apr_pool_t *pool)
{
+ svn_revnum_t base_revision;
+ svn_branch_repos_t *repos;
+ svn_branch_revision_root_t *branching_txn;
const svn_delta_editor_t *deditor;
void *dedit_baton;
svn_editor3__shim_connector_t *shim_connector;
+ /* ### for element-branching, currently need to start from a single base revision */
+ SVN_ERR(svn_ra_get_latest_revnum(session, &base_revision, pool));
+
+ /* load branching info */
+ SVN_ERR(svn_branch_repos_fetch_info(&repos, session, pool, pool));
+ SVN_ERR(svn_branch_get_mutable_state(&branching_txn, repos, session,
+ base_revision,
+ pool, pool));
+
remap_commit_callback(&commit_callback, &commit_baton,
- session, commit_callback, commit_baton,
+ session, branching_txn, commit_callback, commit_baton,
pool);
SVN_ERR(session->vtable->get_commit_editor(session, &deditor, &dedit_baton,
@@ -863,10 +1028,13 @@ svn_error_t *svn_ra_get_commit_editor_ev
SVN_ERR(svn_ra_dup_session(&fbb->session, session, repos_root_url, pool, pool));
fbb->session_path = base_relpath;
fbb->repos_root_url = repos_root_url;
- SVN_ERR(svn_delta__ev3_from_delta_for_commit(
+
+ SVN_ERR(svn_delta__get_debug_editor(&deditor, &dedit_baton,
+ deditor, dedit_baton, "", pool));
+ SVN_ERR(svn_delta__ev3_from_delta_for_commit2(
editor,
&shim_connector,
- deditor, dedit_baton,
+ deditor, dedit_baton, branching_txn,
repos_root_url, base_relpath,
svn_ra_fetch, fbb,
NULL, NULL /*cancel*/,
@@ -887,7 +1055,8 @@ svn_error_t *svn_ra_get_commit_editor3(s
apr_pool_t *pool)
{
remap_commit_callback(&commit_callback, &commit_baton,
- session, commit_callback, commit_baton,
+ session, NULL /*branching_txn*/,
+ commit_callback, commit_baton,
pool);
SVN_ERR(session->vtable->get_commit_editor(session, editor, edit_baton,
@@ -1700,7 +1869,7 @@ svn_ra__get_commit_ev2(svn_editor_t **ed
/* Remap for RA layers exposing Ev1. */
remap_commit_callback(&commit_callback, &commit_baton,
- session, commit_callback, commit_baton,
+ session, NULL, commit_callback, commit_baton,
result_pool);
return svn_error_trace(svn_ra__use_commit_shim(