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 2015/10/14 08:38:16 UTC
svn commit: r1708550 [2/2] - in
/subversion/branches/move-tracking-2/subversion: include/private/
libsvn_delta/ svnmover/ tests/cmdline/ tests/cmdline/svntest/
Copied: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_nested.c (from r1708080, subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c)
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_nested.c?p2=subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_nested.c&p1=subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c&r1=1708080&r2=1708550&rev=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_nested.c Wed Oct 14 06:38:16 2015
@@ -1,5 +1,5 @@
/*
- * branch.c : Element-Based Branching and Move Tracking.
+ * branch_nested.c : Nested Branches
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -29,513 +29,145 @@
#include "svn_hash.h"
#include "svn_iter.h"
-#include "private/svn_element.h"
-#include "private/svn_branch.h"
-#include "private/svn_sorts_private.h"
+#include "private/svn_branch_nested.h"
+#include "private/svn_branch_repos.h"
#include "svn_private_config.h"
-/* Is EID allocated (no matter whether an element with this id exists)? */
-#define EID_IS_ALLOCATED(branch, eid) \
- ((eid) >= (branch)->rev_root->first_eid && (eid) < (branch)->rev_root->next_eid)
-
-#define IS_BRANCH_ROOT_EID(branch, eid) \
- ((eid) == (branch)->root_eid)
-
-/* Is BRANCH1 the same branch as BRANCH2? Compare by full branch-ids; don't
- require identical branch objects. */
-#define BRANCH_IS_SAME_BRANCH(branch1, branch2, scratch_pool) \
- (strcmp(svn_branch_get_id(branch1, scratch_pool), \
- svn_branch_get_id(branch2, scratch_pool)) == 0)
-
-/* Is BRANCH1 an immediate child of BRANCH2? Compare by full branch-ids; don't
- require identical branch objects. */
-#define BRANCH_IS_CHILD_OF_BRANCH(branch1, branch2, scratch_pool) \
- ((branch1)->outer_branch && \
- BRANCH_IS_SAME_BRANCH((branch1)->outer_branch, branch2, scratch_pool))
-
-svn_branch_revision_root_t *
-svn_branch_revision_root_create(svn_branch_repos_t *repos,
- svn_revnum_t rev,
- svn_revnum_t base_rev,
- apr_pool_t *result_pool)
-{
- svn_branch_revision_root_t *rev_root
- = apr_pcalloc(result_pool, sizeof(*rev_root));
-
- rev_root->repos = repos;
- rev_root->rev = rev;
- rev_root->base_rev = base_rev;
- rev_root->root_branches = apr_array_make(result_pool, 0, sizeof(void *));
- rev_root->branches = svn_array_make(result_pool);
- return rev_root;
-}
-
-int
-svn_branch_txn_new_eid(svn_branch_revision_root_t *rev_root)
-{
- int eid = (rev_root->first_eid < 0) ? rev_root->first_eid - 1 : -2;
-
- rev_root->first_eid = eid;
- return eid;
+void
+svn_branch_get_outer_branch_and_eid(svn_branch_state_t **outer_branch_p,
+ int *outer_eid_p,
+ const svn_branch_state_t *branch,
+ apr_pool_t *scratch_pool)
+{
+ const char *outer_bid;
+
+ svn_branch_id_unnest(&outer_bid, outer_eid_p, branch->bid, scratch_pool);
+ *outer_branch_p = NULL;
+ if (outer_bid)
+ {
+ *outer_branch_p
+ = svn_branch_revision_root_get_branch_by_id(branch->rev_root, outer_bid,
+ scratch_pool);
+ }
}
-/* Change txn-local EIDs (negative integers) in BRANCH to revision EIDs, by
- * assigning a new revision-EID (positive integer) for each one.
- */
-static svn_error_t *
-branch_finalize_eids(svn_branch_state_t *branch,
- int mapping_offset,
- apr_pool_t *scratch_pool)
+const char *
+svn_branch_get_root_rrpath(const svn_branch_state_t *branch,
+ apr_pool_t *result_pool)
{
- apr_hash_index_t *hi;
+ svn_branch_state_t *outer_branch;
+ int outer_eid;
+ const char *root_rrpath;
- if (branch->root_eid < -1)
+ svn_branch_get_outer_branch_and_eid(&outer_branch, &outer_eid, branch,
+ result_pool);
+ if (outer_branch)
{
- branch->root_eid = mapping_offset - branch->root_eid;
+ root_rrpath
+ = svn_branch_get_rrpath_by_eid(outer_branch, outer_eid, result_pool);
}
-
- if (branch->outer_eid < -1)
+ else
{
- branch->outer_eid = mapping_offset - branch->outer_eid;
+ root_rrpath = "";
}
- for (hi = apr_hash_first(scratch_pool, branch->e_map);
- hi; hi = apr_hash_next(hi))
- {
- int old_eid = svn_int_hash_this_key(hi);
- svn_branch_el_rev_content_t *element = apr_hash_this_val(hi);
-
- if (old_eid < -1)
- {
- int new_eid = mapping_offset - old_eid;
-
- svn_int_hash_set(branch->e_map, old_eid, NULL);
- svn_int_hash_set(branch->e_map, new_eid, element);
- }
- if (element->parent_eid < -1)
- {
- element->parent_eid = mapping_offset - element->parent_eid;
- }
- }
- return SVN_NO_ERROR;
+ SVN_ERR_ASSERT_NO_RETURN(root_rrpath);
+ return root_rrpath;
}
-svn_error_t *
-svn_branch_txn_finalize_eids(svn_branch_revision_root_t *txn,
- apr_pool_t *scratch_pool)
+const char *
+svn_branch_get_rrpath_by_eid(const svn_branch_state_t *branch,
+ int eid,
+ apr_pool_t *result_pool)
{
- int n_txn_eids = (-1) - txn->first_eid;
- int mapping_offset;
- int i;
-
- if (txn->first_eid == 0)
- return SVN_NO_ERROR;
-
- /* mapping from txn-local (negative) EID to committed (positive) EID is:
- txn_local_eid == -2 => committed_eid := (txn.next_eid + 0)
- txn_local_eid == -3 => committed_eid := (txn.next_eid + 1) ... */
- mapping_offset = txn->next_eid - 2;
+ const char *path = svn_branch_get_path_by_eid(branch, eid, result_pool);
+ const char *rrpath = NULL;
- for (i = 0; i < txn->branches->nelts; i++)
+ if (path)
{
- svn_branch_state_t *b = APR_ARRAY_IDX(txn->branches, i, void *);
-
- SVN_ERR(branch_finalize_eids(b, mapping_offset, scratch_pool));
+ rrpath = svn_relpath_join(svn_branch_get_root_rrpath(branch, result_pool),
+ path, result_pool);
}
-
- txn->next_eid += n_txn_eids;
- txn->first_eid = 0;
- return SVN_NO_ERROR;
-}
-
-svn_branch_state_t *
-svn_branch_revision_root_get_root_branch(svn_branch_revision_root_t *rev_root,
- int top_branch_num)
-{
- if (top_branch_num < 0 || top_branch_num >= rev_root->root_branches->nelts)
- return NULL;
- return APR_ARRAY_IDX(rev_root->root_branches, top_branch_num, void *);
-
-}
-
-const apr_array_header_t *
-svn_branch_revision_root_get_branches(svn_branch_revision_root_t *rev_root,
- apr_pool_t *result_pool)
-{
- return rev_root->branches;
+ return rrpath;
}
svn_branch_state_t *
-svn_branch_revision_root_get_branch_by_id(const svn_branch_revision_root_t *rev_root,
- const char *branch_id,
- apr_pool_t *scratch_pool)
+svn_branch_get_subbranch_at_eid(svn_branch_state_t *branch,
+ int eid,
+ apr_pool_t *scratch_pool)
{
- SVN_ITER_T(svn_branch_state_t) *bi;
- svn_branch_state_t *branch = NULL;
+ svn_branch_el_rev_content_t *element = svn_branch_get_element(branch, eid);
- for (SVN_ARRAY_ITER(bi, rev_root->branches, scratch_pool))
+ if (element && element->payload->is_subbranch_root)
{
- svn_branch_state_t *b = bi->val;
+ const char *branch_id = svn_branch_get_id(branch, scratch_pool);
+ const char *subbranch_id = svn_branch_id_nest(branch_id, eid,
+ scratch_pool);
- if (strcmp(svn_branch_get_id(b, scratch_pool), branch_id) == 0)
- {
- branch = b;
- break;
- }
+ return svn_branch_revision_root_get_branch_by_id(branch->rev_root,
+ subbranch_id,
+ scratch_pool);
}
- return branch;
+ return NULL;
}
-static void
-branch_validate_element(const svn_branch_state_t *branch,
- int eid,
- const svn_branch_el_rev_content_t *element);
-
-/* Assert BRANCH satisfies all its invariants.
- */
-static void
-assert_branch_state_invariants(const svn_branch_state_t *branch,
- apr_pool_t *scratch_pool)
+apr_array_header_t *
+svn_branch_get_immediate_subbranches(svn_branch_state_t *branch,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
+ svn_array_t *subbranches = svn_array_make(result_pool);
+ const char *branch_id = svn_branch_get_id(branch, scratch_pool);
apr_hash_index_t *hi;
- assert(branch->rev_root);
- if (branch->outer_branch)
- {
- assert(EID_IS_ALLOCATED(branch, branch->outer_eid));
- }
- assert(branch->outer_eid != -1);
- assert(branch->e_map);
-
- /* Validate elements in the map */
for (hi = apr_hash_first(scratch_pool, branch->e_map);
hi; hi = apr_hash_next(hi))
{
- branch_validate_element(branch, svn_int_hash_this_key(hi),
- apr_hash_this_val(hi));
- }
-}
-
-svn_branch_state_t *
-svn_branch_state_create(svn_branch_rev_bid_t *predecessor,
- int root_eid,
- svn_branch_revision_root_t *rev_root,
- svn_branch_state_t *outer_branch,
- int outer_eid,
- apr_pool_t *result_pool)
-{
- svn_branch_state_t *b = apr_pcalloc(result_pool, sizeof(*b));
-
- b->predecessor = svn_branch_rev_bid_dup(predecessor, result_pool);
- b->root_eid = root_eid;
- b->rev_root = rev_root;
- b->e_map = apr_hash_make(result_pool);
- b->outer_branch = outer_branch;
- b->outer_eid = outer_eid;
- assert_branch_state_invariants(b, result_pool);
- return b;
-}
-
-svn_branch_el_rev_id_t *
-svn_branch_el_rev_id_create(svn_branch_state_t *branch,
- int eid,
- svn_revnum_t rev,
- apr_pool_t *result_pool)
-{
- svn_branch_el_rev_id_t *id = apr_palloc(result_pool, sizeof(*id));
-
- id->branch = branch;
- id->eid = eid;
- id->rev = rev;
- return id;
-}
-
-svn_branch_rev_bid_eid_t *
-svn_branch_rev_bid_eid_create(svn_revnum_t rev,
- const char *branch_id,
- int eid,
- apr_pool_t *result_pool)
-{
- svn_branch_rev_bid_eid_t *id = apr_palloc(result_pool, sizeof(*id));
-
- id->bid = branch_id;
- id->eid = eid;
- id->rev = rev;
- return id;
-}
-
-svn_branch_rev_bid_eid_t *
-svn_branch_rev_bid_eid_dup(const svn_branch_rev_bid_eid_t *old_id,
- apr_pool_t *result_pool)
-{
- svn_branch_rev_bid_eid_t *id;
-
- if (! old_id)
- return NULL;
-
- id = apr_pmemdup(result_pool, old_id, sizeof(*id));
- id->bid = apr_pstrdup(result_pool, old_id->bid);
- return id;
-}
-
-svn_branch_rev_bid_t *
-svn_branch_rev_bid_create(svn_revnum_t rev,
- const char *branch_id,
- apr_pool_t *result_pool)
-{
- svn_branch_rev_bid_t *id = apr_palloc(result_pool, sizeof(*id));
-
- id->bid = branch_id;
- id->rev = rev;
- return id;
-}
-
-svn_branch_rev_bid_t *
-svn_branch_rev_bid_dup(const svn_branch_rev_bid_t *old_id,
- apr_pool_t *result_pool)
-{
- svn_branch_rev_bid_t *id;
-
- if (! old_id)
- return NULL;
-
- id = apr_pmemdup(result_pool, old_id, sizeof(*id));
- id->bid = apr_pstrdup(result_pool, old_id->bid);
- return id;
-}
-
-svn_branch_el_rev_content_t *
-svn_branch_el_rev_content_create(svn_branch_eid_t parent_eid,
- const char *name,
- const svn_element_payload_t *payload,
- apr_pool_t *result_pool)
-{
- svn_branch_el_rev_content_t *content
- = apr_palloc(result_pool, sizeof(*content));
-
- content->parent_eid = parent_eid;
- content->name = apr_pstrdup(result_pool, name);
- content->payload = svn_element_payload_dup(payload, result_pool);
- return content;
-}
-
-svn_branch_el_rev_content_t *
-svn_branch_el_rev_content_dup(const svn_branch_el_rev_content_t *old,
- apr_pool_t *result_pool)
-{
- svn_branch_el_rev_content_t *content
- = apr_pmemdup(result_pool, old, sizeof(*content));
-
- content->name = apr_pstrdup(result_pool, old->name);
- content->payload = svn_element_payload_dup(old->payload, result_pool);
- return content;
-}
-
-svn_boolean_t
-svn_branch_el_rev_content_equal(const svn_branch_el_rev_content_t *content_left,
- const svn_branch_el_rev_content_t *content_right,
- apr_pool_t *scratch_pool)
-{
- if (!content_left && !content_right)
- {
- return TRUE;
- }
- else if (!content_left || !content_right)
- {
- return FALSE;
- }
-
- if (content_left->parent_eid != content_right->parent_eid)
- {
- return FALSE;
- }
- if (strcmp(content_left->name, content_right->name) != 0)
- {
- return FALSE;
- }
- if (! svn_element_payload_equal(content_left->payload, content_right->payload,
- scratch_pool))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- * ========================================================================
- * Branch mappings
- * ========================================================================
- */
-
-svn_branch_subtree_t *
-svn_branch_subtree_create(apr_hash_t *e_map,
- int root_eid,
- apr_pool_t *result_pool)
-{
- svn_branch_subtree_t *subtree = apr_pcalloc(result_pool, sizeof(*subtree));
-
- subtree->e_map = e_map ? apr_hash_copy(result_pool, e_map)
- : apr_hash_make(result_pool);
- subtree->root_eid = root_eid;
- subtree->subbranches = apr_hash_make(result_pool);
- return subtree;
-}
-
-svn_branch_subtree_t *
-svn_branch_subtree_get_subbranch_at_eid(svn_branch_subtree_t *subtree,
- int eid,
- apr_pool_t *result_pool)
-{
- subtree = svn_int_hash_get(subtree->subbranches, eid);
-
- return subtree;
-}
-
-/* Validate that ELEMENT is suitable for a mapping of BRANCH:EID.
- * ELEMENT->payload may be null.
- */
-static void
-branch_validate_element(const svn_branch_state_t *branch,
- int eid,
- const svn_branch_el_rev_content_t *element)
-{
- SVN_ERR_ASSERT_NO_RETURN(element);
+ int eid = svn_int_hash_this_key(hi);
+ svn_branch_el_rev_content_t *element = apr_hash_this_val(hi);
- /* Parent EID must be valid and different from this element's EID, or -1
- iff this is the branch root element. */
- SVN_ERR_ASSERT_NO_RETURN(
- IS_BRANCH_ROOT_EID(branch, eid)
- ? (element->parent_eid == -1)
- : (element->parent_eid != eid
- && EID_IS_ALLOCATED(branch, element->parent_eid)));
-
- /* Element name must be given, and empty iff EID is the branch root. */
- SVN_ERR_ASSERT_NO_RETURN(
- element->name
- && IS_BRANCH_ROOT_EID(branch, eid) == (*element->name == '\0'));
+ if (element->payload->is_subbranch_root)
+ {
+ const char *subbranch_id
+ = svn_branch_id_nest(branch_id, eid, scratch_pool);
+ svn_branch_state_t *subbranch
+ = svn_branch_revision_root_get_branch_by_id(branch->rev_root,
+ subbranch_id,
+ scratch_pool);
- SVN_ERR_ASSERT_NO_RETURN(svn_element_payload_invariants(element->payload));
- if (element->payload->is_subbranch_root)
- {
- /* a subbranch root element must not be the branch root element */
- SVN_ERR_ASSERT_NO_RETURN(eid != branch->root_eid);
+ SVN_ARRAY_PUSH(subbranches) = subbranch;
+ }
}
+ return subbranches;
}
-apr_hash_t *
-svn_branch_get_elements(svn_branch_state_t *branch)
-{
- return branch->e_map;
-}
-
-svn_branch_el_rev_content_t *
-svn_branch_get_element(const svn_branch_state_t *branch,
- int eid)
-{
- svn_branch_el_rev_content_t *element;
-
- SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
- element = svn_int_hash_get(branch->e_map, eid);
-
- if (element)
- branch_validate_element(branch, eid, element);
- return element;
-}
-
-/* In BRANCH, set element EID to ELEMENT.
- *
- * If ELEMENT is null, delete element EID. Otherwise, ELEMENT->payload may be
- * null meaning it is a subbranch-root.
- *
- * Assume ELEMENT is already allocated with sufficient lifetime.
- */
-static void
-branch_map_set(svn_branch_state_t *branch,
- int eid,
- svn_branch_el_rev_content_t *element)
-{
- apr_pool_t *map_pool = apr_hash_pool_get(branch->e_map);
-
- SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
- if (element)
- branch_validate_element(branch, eid, element);
-
- svn_int_hash_set(branch->e_map, eid, element);
- assert_branch_state_invariants(branch, map_pool);
-}
-
-void
-svn_branch_delete_element(svn_branch_state_t *branch,
- int eid)
-{
- SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
- branch_map_set(branch, eid, NULL);
-}
-
-void
-svn_branch_update_element(svn_branch_state_t *branch,
- int eid,
- svn_branch_eid_t new_parent_eid,
- const char *new_name,
- const svn_element_payload_t *new_payload)
-{
- apr_pool_t *map_pool = apr_hash_pool_get(branch->e_map);
- svn_branch_el_rev_content_t *element
- = svn_branch_el_rev_content_create(new_parent_eid, new_name, new_payload,
- map_pool);
-
- /* EID must be a valid element id */
- SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
- /* NEW_PAYLOAD must be specified, either in full or by reference */
- SVN_ERR_ASSERT_NO_RETURN(new_payload);
-
- /* Insert the new version */
- branch_map_set(branch, eid, element);
-}
-
-static void
-map_purge_orphans(apr_hash_t *e_map,
- int root_eid,
- apr_pool_t *scratch_pool);
-
svn_branch_subtree_t *
-svn_branch_get_subtree(const svn_branch_state_t *branch,
+svn_branch_get_subtree(svn_branch_state_t *branch,
int eid,
apr_pool_t *result_pool)
{
svn_branch_subtree_t *new_subtree;
- svn_branch_el_rev_content_t *subtree_root_element;
SVN_ITER_T(svn_branch_state_t) *bi;
SVN_BRANCH_SEQUENCE_POINT(branch);
- new_subtree = svn_branch_subtree_create(branch->e_map, eid,
- result_pool);
- new_subtree->predecessor = svn_branch_rev_bid_dup(branch->predecessor,
- result_pool);
-
- /* Purge orphans */
- map_purge_orphans(new_subtree->e_map, new_subtree->root_eid, result_pool);
-
- /* Remove 'parent' and 'name' attributes from subtree root element */
- subtree_root_element
- = svn_int_hash_get(new_subtree->e_map, new_subtree->root_eid);
- svn_int_hash_set(new_subtree->e_map, new_subtree->root_eid,
- svn_branch_el_rev_content_create(
- -1, "", subtree_root_element->payload, result_pool));
+ new_subtree
+ = svn_branch_get_subtree_n(branch, eid, result_pool);
/* Add subbranches */
for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
branch, result_pool, result_pool), result_pool))
{
svn_branch_state_t *subbranch = bi->val;
- const char *subbranch_relpath_in_subtree
- = svn_branch_subtree_get_path_by_eid(new_subtree, subbranch->outer_eid,
+ const char *outer_bid;
+ int outer_eid;
+ const char *subbranch_relpath_in_subtree;
+
+ svn_branch_id_unnest(&outer_bid, &outer_eid, subbranch->bid,
+ bi->iterpool);
+ subbranch_relpath_in_subtree
+ = svn_branch_subtree_get_path_by_eid(new_subtree, outer_eid,
bi->iterpool);
/* Is it pathwise at or below EID? If so, add it into the subtree. */
@@ -544,285 +176,19 @@ svn_branch_get_subtree(const svn_branch_
svn_branch_subtree_t *this_subtree
= svn_branch_get_subtree(subbranch, subbranch->root_eid, result_pool);
- svn_int_hash_set(new_subtree->subbranches, subbranch->outer_eid,
+ svn_int_hash_set(new_subtree->subbranches, outer_eid,
this_subtree);
}
}
return new_subtree;
}
-/* Purge entries from E_MAP that don't connect, via parent directory hierarchy,
- * to ROOT_EID. In other words, remove elements that have been implicitly
- * deleted.
- *
- * ROOT_EID must be present in E_MAP.
- *
- * ### Does not detect cycles: current implementation will not purge a cycle
- * that is disconnected from ROOT_EID. This could be a problem.
- */
-static void
-map_purge_orphans(apr_hash_t *e_map,
- int root_eid,
- apr_pool_t *scratch_pool)
-{
- apr_hash_index_t *hi;
- svn_boolean_t changed;
-
- SVN_ERR_ASSERT_NO_RETURN(svn_int_hash_get(e_map, root_eid));
-
- do
- {
- changed = FALSE;
-
- for (hi = apr_hash_first(scratch_pool, e_map);
- hi; hi = apr_hash_next(hi))
- {
- int this_eid = svn_int_hash_this_key(hi);
- svn_branch_el_rev_content_t *this_element = apr_hash_this_val(hi);
-
- if (this_eid != root_eid)
- {
- svn_branch_el_rev_content_t *parent_element
- = svn_int_hash_get(e_map, this_element->parent_eid);
-
- /* Purge if parent is deleted */
- if (! parent_element)
- {
- SVN_DBG(("purge orphan: e%d", this_eid));
- svn_int_hash_set(e_map, this_eid, NULL);
- changed = TRUE;
- }
- else
- SVN_ERR_ASSERT_NO_RETURN(
- ! parent_element->payload->is_subbranch_root);
- }
- }
- }
- while (changed);
-}
-
-void
-svn_branch_purge_r(svn_branch_state_t *branch,
- apr_pool_t *scratch_pool)
-{
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- /* first, remove elements that have no parent element */
- map_purge_orphans(branch->e_map, branch->root_eid, scratch_pool);
-
- /* second, remove subbranches that have no subbranch-root element */
- for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
- branch, scratch_pool, scratch_pool), scratch_pool))
- {
- svn_branch_state_t *b = bi->val;
-
- if (svn_branch_get_element(branch, b->outer_eid))
- {
- svn_branch_purge_r(b, bi->iterpool);
- }
- else
- {
- svn_branch_delete_branch_r(b, bi->iterpool);
- }
- }
-}
-
-const char *
-svn_branch_get_root_rrpath(const svn_branch_state_t *branch,
- apr_pool_t *result_pool)
-{
- const char *root_rrpath;
-
- if (branch->outer_branch)
- {
- root_rrpath
- = svn_branch_get_rrpath_by_eid(branch->outer_branch, branch->outer_eid,
- result_pool);
- }
- else
- {
- root_rrpath = "";
- }
-
- SVN_ERR_ASSERT_NO_RETURN(root_rrpath);
- return root_rrpath;
-}
-
-const char *
-svn_branch_subtree_get_path_by_eid(const svn_branch_subtree_t *subtree,
- int eid,
- apr_pool_t *result_pool)
-{
- const char *path = "";
- svn_branch_el_rev_content_t *element;
-
- for (; eid != subtree->root_eid; eid = element->parent_eid)
- {
- element = svn_int_hash_get(subtree->e_map, eid);
- if (! element)
- return NULL;
- path = svn_relpath_join(element->name, path, result_pool);
- }
- SVN_ERR_ASSERT_NO_RETURN(eid == subtree->root_eid);
- return path;
-}
-
-const char *
-svn_branch_get_path_by_eid(const svn_branch_state_t *branch,
- int eid,
- apr_pool_t *result_pool)
-{
- const char *path = "";
- svn_branch_el_rev_content_t *element;
-
- SVN_ERR_ASSERT_NO_RETURN(EID_IS_ALLOCATED(branch, eid));
-
- for (; ! IS_BRANCH_ROOT_EID(branch, eid); eid = element->parent_eid)
- {
- element = svn_branch_get_element(branch, eid);
- if (! element)
- return NULL;
- path = svn_relpath_join(element->name, path, result_pool);
- }
- SVN_ERR_ASSERT_NO_RETURN(IS_BRANCH_ROOT_EID(branch, eid));
- return path;
-}
-
-const char *
-svn_branch_get_rrpath_by_eid(const svn_branch_state_t *branch,
- int eid,
- apr_pool_t *result_pool)
-{
- const char *path = svn_branch_get_path_by_eid(branch, eid, result_pool);
- const char *rrpath = NULL;
-
- if (path)
- {
- rrpath = svn_relpath_join(svn_branch_get_root_rrpath(branch, result_pool),
- path, result_pool);
- }
- return rrpath;
-}
-
-int
-svn_branch_get_eid_by_path(const svn_branch_state_t *branch,
- const char *path,
- apr_pool_t *scratch_pool)
-{
- apr_hash_index_t *hi;
-
- /* ### This is a crude, linear search */
- for (hi = apr_hash_first(scratch_pool, branch->e_map);
- hi; hi = apr_hash_next(hi))
- {
- int eid = svn_int_hash_this_key(hi);
- const char *this_path = svn_branch_get_path_by_eid(branch, eid,
- scratch_pool);
-
- if (! this_path)
- {
- /* Mapping is not complete; this element is in effect not present. */
- continue;
- }
- if (strcmp(path, this_path) == 0)
- {
- return eid;
- }
- }
-
- return -1;
-}
-
-int
-svn_branch_get_eid_by_rrpath(svn_branch_state_t *branch,
- const char *rrpath,
- apr_pool_t *scratch_pool)
-{
- const char *path = svn_relpath_skip_ancestor(svn_branch_get_root_rrpath(
- branch, scratch_pool),
- rrpath);
- int eid = -1;
-
- if (path)
- {
- eid = svn_branch_get_eid_by_path(branch, path, scratch_pool);
- }
- return eid;
-}
-
svn_error_t *
-svn_branch_map_add_subtree(svn_branch_state_t *to_branch,
- int to_eid,
- svn_branch_eid_t new_parent_eid,
- const char *new_name,
- svn_branch_subtree_t new_subtree,
- apr_pool_t *scratch_pool)
+svn_branch_instantiate_elements_r(svn_branch_state_t *to_branch,
+ svn_branch_subtree_t elements,
+ apr_pool_t *scratch_pool)
{
- apr_hash_index_t *hi;
- svn_branch_el_rev_content_t *new_root_content;
-
- if (new_subtree.subbranches && apr_hash_count(new_subtree.subbranches))
- {
- return svn_error_createf(SVN_ERR_BRANCHING, NULL,
- _("Adding or copying a subtree containing "
- "subbranches is not implemented"));
- }
-
- /* Get a new EID for the root element, if not given. */
- if (to_eid == -1)
- {
- to_eid = svn_branch_txn_new_eid(to_branch->rev_root);
- }
-
- /* Create the new subtree root element */
- new_root_content = svn_int_hash_get(new_subtree.e_map, new_subtree.root_eid);
- svn_branch_update_element(to_branch, to_eid,
- new_parent_eid, new_name,
- new_root_content->payload);
-
- /* Process its immediate children */
- for (hi = apr_hash_first(scratch_pool, new_subtree.e_map);
- hi; hi = apr_hash_next(hi))
- {
- int this_from_eid = svn_int_hash_this_key(hi);
- svn_branch_el_rev_content_t *from_element = apr_hash_this_val(hi);
-
- if (from_element->parent_eid == new_subtree.root_eid)
- {
- svn_branch_subtree_t this_subtree;
-
- /* Recurse. (We don't try to check whether it's a directory node,
- as we might not have the node kind in the map.) */
- this_subtree.e_map = new_subtree.e_map;
- this_subtree.root_eid = this_from_eid;
- this_subtree.subbranches = apr_hash_make(scratch_pool);
- SVN_ERR(svn_branch_map_add_subtree(to_branch, -1 /*to_eid*/,
- to_eid, from_element->name,
- this_subtree, scratch_pool));
- }
- }
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_branch_instantiate_elements(svn_branch_state_t *to_branch,
- svn_branch_subtree_t elements,
- apr_pool_t *scratch_pool)
-{
- apr_hash_index_t *hi;
-
- /* Instantiate all the elements of NEW_SUBTREE */
- for (hi = apr_hash_first(scratch_pool, elements.e_map);
- hi; hi = apr_hash_next(hi))
- {
- int this_eid = svn_int_hash_this_key(hi);
- svn_branch_el_rev_content_t *this_element = apr_hash_this_val(hi);
-
- branch_map_set(to_branch, this_eid,
- svn_branch_el_rev_content_dup(
- this_element, apr_hash_pool_get(to_branch->e_map)));
- }
+ SVN_ERR(svn_branch_instantiate_elements(to_branch, elements, scratch_pool));
/* branch any subbranches */
{
@@ -832,477 +198,26 @@ svn_branch_instantiate_elements(svn_bran
{
int this_outer_eid = svn_int_hash_this_key(bi->apr_hi);
svn_branch_subtree_t *this_subtree = bi->val;
+ const char *new_branch_id;
svn_branch_state_t *new_branch;
/* branch this subbranch into NEW_BRANCH (recursing) */
- new_branch = svn_branch_add_new_branch(to_branch->rev_root,
+ new_branch_id = svn_branch_id_nest(to_branch->bid, this_outer_eid,
+ bi->iterpool);
+ new_branch = svn_branch_add_new_branch(new_branch_id,
+ to_branch->rev_root,
this_subtree->predecessor,
- to_branch, this_outer_eid,
this_subtree->root_eid,
bi->iterpool);
- SVN_ERR(svn_branch_instantiate_elements(new_branch, *this_subtree,
- bi->iterpool));
+ SVN_ERR(svn_branch_instantiate_elements_r(new_branch, *this_subtree,
+ bi->iterpool));
}
}
return SVN_NO_ERROR;
}
-apr_array_header_t *
-svn_branch_get_immediate_subbranches(const svn_branch_state_t *branch,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_array_t *subbranches = svn_array_make(result_pool);
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- for (SVN_ARRAY_ITER(bi, branch->rev_root->branches, scratch_pool))
- {
- /* Is it an immediate child? */
- if (bi->val->outer_branch == branch)
- SVN_ARRAY_PUSH(subbranches) = bi->val;
- }
- return subbranches;
-}
-
-svn_branch_state_t *
-svn_branch_get_subbranch_at_eid(svn_branch_state_t *branch,
- int eid,
- apr_pool_t *scratch_pool)
-{
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- /* TODO: more efficient to search in branch->rev_root->branches */
- for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
- branch, scratch_pool, scratch_pool), scratch_pool))
- {
- if (bi->val->outer_eid == eid)
- return bi->val;
- }
- return NULL;
-}
-
-svn_branch_state_t *
-svn_branch_add_new_branch(svn_branch_revision_root_t *rev_root,
- svn_branch_rev_bid_t *predecessor,
- svn_branch_state_t *outer_branch,
- int outer_eid,
- int root_eid,
- apr_pool_t *scratch_pool)
-{
- svn_branch_state_t *new_branch;
-
- SVN_ERR_ASSERT_NO_RETURN(!outer_branch || outer_branch->rev_root == rev_root);
- SVN_ERR_ASSERT_NO_RETURN(root_eid != -1);
-
- if (! outer_branch)
- outer_eid = rev_root->root_branches->nelts;
-
- new_branch = svn_branch_state_create(predecessor, root_eid, rev_root,
- outer_branch, outer_eid,
- rev_root->branches->pool);
-
- /* A branch must not already exist at this outer element */
- SVN_ERR_ASSERT_NO_RETURN(!outer_branch ||
- svn_branch_get_subbranch_at_eid(
- outer_branch, outer_eid, scratch_pool) == NULL);
-
- SVN_ARRAY_PUSH(rev_root->branches) = new_branch;
- if (!outer_branch)
- SVN_ARRAY_PUSH(rev_root->root_branches) = new_branch;
-
- return new_branch;
-}
-
-/* Remove branch BRANCH from the list of branches in REV_ROOT.
- */
-static void
-svn_branch_revision_root_delete_branch(
- svn_branch_revision_root_t *rev_root,
- svn_branch_state_t *branch,
- apr_pool_t *scratch_pool)
-{
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- SVN_ERR_ASSERT_NO_RETURN(branch->rev_root == rev_root);
-
- for (SVN_ARRAY_ITER(bi, rev_root->branches, scratch_pool))
- {
- if (bi->val == branch)
- {
- SVN_DBG(("deleting branch b%s e%d",
- svn_branch_get_id(bi->val, bi->iterpool),
- bi->val->root_eid));
- svn_sort__array_delete(rev_root->branches, bi->i, 1);
- break;
- }
- }
- for (SVN_ARRAY_ITER(bi, rev_root->root_branches, scratch_pool))
- {
- if (bi->val == branch)
- {
- SVN_DBG(("deleting root-branch b%s e%d",
- svn_branch_get_id(bi->val, bi->iterpool),
- bi->val->root_eid));
- svn_sort__array_delete(rev_root->root_branches, bi->i, 1);
- break;
- }
- }
-}
-
-void
-svn_branch_delete_branch_r(svn_branch_state_t *branch,
- apr_pool_t *scratch_pool)
-{
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- for (SVN_ARRAY_ITER(bi, svn_branch_get_immediate_subbranches(
- branch, scratch_pool, scratch_pool), scratch_pool))
- {
- svn_branch_delete_branch_r(bi->val, bi->iterpool);
- }
-
- svn_branch_revision_root_delete_branch(branch->rev_root,
- branch, scratch_pool);
-}
-
-
-/*
- * ========================================================================
- * Parsing and Serializing
- * ========================================================================
- */
-
-svn_string_t *
-svn_branch_get_default_r0_metadata(apr_pool_t *result_pool)
-{
- static const char *default_repos_info
- = "r0: eids 0 1 branches 1\n"
- "B0 root-eid 0 num-eids 1 # at /\n"
- "e0: normal -1 .\n";
-
- return svn_string_create(default_repos_info, result_pool);
-}
-
-/* */
-static svn_error_t *
-parse_branch_line(char *bid_p,
- int *root_eid_p,
- int *num_eids_p,
- svn_branch_rev_bid_t **predecessor,
- svn_stream_t *stream,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_stringbuf_t *line;
- svn_boolean_t eof;
- int n;
- svn_revnum_t pred_rev;
- char pred_bid[1000];
-
- /* Read a line */
- SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool));
- SVN_ERR_ASSERT(!eof);
-
- n = sscanf(line->data, "%s root-eid %d num-eids %d from r%ld.%s",
- bid_p, root_eid_p, num_eids_p, &pred_rev, pred_bid);
- SVN_ERR_ASSERT(n == 3 || n == 5);
-
- if (n == 5)
- {
- *predecessor = svn_branch_rev_bid_create(pred_rev, pred_bid, result_pool);
- }
- else
- {
- *predecessor = NULL;
- }
-
- return SVN_NO_ERROR;
-}
-
-/* */
-static svn_error_t *
-parse_element_line(int *eid_p,
- svn_boolean_t *is_subbranch_p,
- int *parent_eid_p,
- const char **name_p,
- svn_stream_t *stream,
- apr_pool_t *scratch_pool)
-{
- svn_stringbuf_t *line;
- svn_boolean_t eof;
- char kind[10];
- int n;
- int offset;
-
- /* Read a line */
- SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool));
- SVN_ERR_ASSERT(!eof);
-
- n = sscanf(line->data, "e%d: %9s %d%n",
- eid_p,
- kind, parent_eid_p, &offset);
- SVN_ERR_ASSERT(n >= 3); /* C std is unclear on whether '%n' counts */
- SVN_ERR_ASSERT(line->data[offset] == ' ');
- *name_p = line->data + offset + 1;
-
- *is_subbranch_p = (strcmp(kind, "subbranch") == 0);
-
- if (strcmp(*name_p, "(null)") == 0)
- *name_p = NULL;
- else if (strcmp(*name_p, ".") == 0)
- *name_p = "";
-
- return SVN_NO_ERROR;
-}
-
-const char *
-svn_branch_id_nest(const char *outer_bid,
- int outer_eid,
- apr_pool_t *result_pool)
-{
- if (!outer_bid)
- return apr_psprintf(result_pool, "B%d", outer_eid);
-
- return apr_psprintf(result_pool, "%s.%d", outer_bid, outer_eid);
-}
-
-void
-svn_branch_id_unnest(const char **outer_bid,
- int *outer_eid,
- const char *bid,
- apr_pool_t *result_pool)
-{
- char *last_dot = strrchr(bid, '.');
-
- if (last_dot) /* BID looks like "B3.11" or "B3.11.22" etc. */
- {
- *outer_bid = apr_pstrndup(result_pool, bid, last_dot - bid);
- *outer_eid = atoi(last_dot + 1);
- }
- else /* looks like "B0" or B22" (with no dot) */
- {
- *outer_bid = NULL;
- *outer_eid = atoi(bid + 1);
- }
-}
-
-/* Create a new branch *NEW_BRANCH, initialized
- * with info parsed from STREAM, allocated in RESULT_POOL.
- */
-static svn_error_t *
-svn_branch_state_parse(svn_branch_state_t **new_branch,
- svn_branch_revision_root_t *rev_root,
- svn_stream_t *stream,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- char bid[1000];
- int root_eid, num_eids;
- svn_branch_rev_bid_t *predecessor;
- svn_branch_state_t *branch_state;
- svn_branch_state_t *outer_branch;
- int outer_eid;
- int i;
-
- SVN_ERR(parse_branch_line(bid, &root_eid, &num_eids, &predecessor,
- stream, scratch_pool, scratch_pool));
-
- /* Find the outer branch and outer EID */
- {
- const char *outer_bid;
-
- svn_branch_id_unnest(&outer_bid, &outer_eid, bid, scratch_pool);
- if (outer_bid)
- {
- outer_branch
- = svn_branch_revision_root_get_branch_by_id(rev_root, outer_bid,
- scratch_pool);
- }
- else
- outer_branch = NULL;
- }
- branch_state = svn_branch_state_create(predecessor, root_eid, rev_root,
- outer_branch, outer_eid,
- result_pool);
-
- /* Read in the structure. Set the payload of each normal element to a
- (branch-relative) reference. */
- for (i = 0; i < num_eids; i++)
- {
- int eid, this_parent_eid;
- const char *this_name;
- svn_boolean_t is_subbranch;
-
- SVN_ERR(parse_element_line(&eid,
- &is_subbranch, &this_parent_eid, &this_name,
- stream, scratch_pool));
-
- if (this_name)
- {
- svn_element_payload_t *payload;
- if (! is_subbranch)
- {
- payload = svn_element_payload_create_ref(rev_root->rev, bid, eid,
- result_pool);
- }
- else
- {
- payload
- = svn_element_payload_create_subbranch(result_pool);
- }
- svn_branch_update_element(
- branch_state, eid, this_parent_eid, this_name, payload);
- }
- }
-
- *new_branch = branch_state;
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_branch_revision_root_parse(svn_branch_revision_root_t **rev_root_p,
- svn_branch_repos_t *repos,
- svn_stream_t *stream,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_branch_revision_root_t *rev_root;
- svn_revnum_t rev;
- int first_eid, next_eid;
- int num_branches;
- svn_stringbuf_t *line;
- svn_boolean_t eof;
- int n;
- int j;
-
- SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, scratch_pool));
- SVN_ERR_ASSERT(! eof);
- n = sscanf(line->data, "r%ld: eids %d %d "
- "branches %d",
- &rev,
- &first_eid, &next_eid,
- &num_branches);
- SVN_ERR_ASSERT(n == 4);
-
- rev_root = svn_branch_revision_root_create(repos, rev, rev - 1,
- result_pool);
- rev_root->first_eid = first_eid;
- rev_root->next_eid = next_eid;
-
- /* parse the branches */
- for (j = 0; j < num_branches; j++)
- {
- svn_branch_state_t *branch;
-
- SVN_ERR(svn_branch_state_parse(&branch, rev_root, stream,
- result_pool, scratch_pool));
- SVN_ARRAY_PUSH(rev_root->branches) = branch;
-
- /* Note the root branches */
- if (! branch->outer_branch)
- {
- APR_ARRAY_PUSH(rev_root->root_branches, void *) = branch;
- }
- }
-
- *rev_root_p = rev_root;
- return SVN_NO_ERROR;
-}
-
-/* ### Duplicated in svnmover.c. */
-static int
-sort_compare_items_by_eid(const svn_sort__item_t *a,
- const svn_sort__item_t *b)
-{
- int eid_a = *(const int *)a->key;
- int eid_b = *(const int *)b->key;
-
- return eid_a - eid_b;
-}
-
-/* Write to STREAM a parseable representation of BRANCH.
- */
-svn_error_t *
-svn_branch_state_serialize(svn_stream_t *stream,
- svn_branch_state_t *branch,
- apr_pool_t *scratch_pool)
-{
- const char *branch_root_rrpath = svn_branch_get_root_rrpath(branch,
- scratch_pool);
- SVN_ITER_T(svn_branch_el_rev_content_t) *hi;
- const char *predecessor_str = "";
-
- if (branch->predecessor)
- {
- assert(SVN_IS_VALID_REVNUM(branch->predecessor->rev));
- predecessor_str = apr_psprintf(scratch_pool, " from r%ld.%s",
- branch->predecessor->rev,
- branch->predecessor->bid);
- }
-
- SVN_ERR(svn_stream_printf(stream, scratch_pool,
- "%s root-eid %d num-eids %d%s # at /%s\n",
- svn_branch_get_id(branch, scratch_pool),
- branch->root_eid,
- apr_hash_count(branch->e_map),
- predecessor_str,
- branch_root_rrpath));
-
- map_purge_orphans(branch->e_map, branch->root_eid, scratch_pool);
-
- for (SVN_HASH_ITER_SORTED(hi, branch->e_map, sort_compare_items_by_eid,
- scratch_pool))
- {
- int eid = *(const int *)hi->key;
- svn_branch_el_rev_content_t *element = svn_branch_get_element(branch, eid);
- int parent_eid;
- const char *name;
-
- SVN_ERR_ASSERT(element);
- parent_eid = element->parent_eid;
- name = element->name[0] ? element->name : ".";
- SVN_ERR(svn_stream_printf(stream, scratch_pool,
- "e%d: %s %d %s\n",
- eid,
- element ? ((! element->payload->is_subbranch_root)
- ? "normal" : "subbranch")
- : "none",
- parent_eid, name));
- }
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_branch_revision_root_serialize(svn_stream_t *stream,
- svn_branch_revision_root_t *rev_root,
- apr_pool_t *scratch_pool)
-{
- SVN_ITER_T(svn_branch_state_t) *bi;
-
- SVN_ERR(svn_stream_printf(stream, scratch_pool,
- "r%ld: eids %d %d "
- "branches %d\n",
- rev_root->rev,
- rev_root->first_eid, rev_root->next_eid,
- rev_root->branches->nelts));
-
- for (SVN_ARRAY_ITER(bi, rev_root->branches, scratch_pool))
- {
- svn_branch_state_t *branch = bi->val;
-
- if (branch->predecessor && branch->predecessor->rev < 0)
- {
- branch->predecessor->rev = rev_root->rev;
- }
-
- SVN_ERR(svn_branch_state_serialize(stream, bi->val, bi->iterpool));
- }
- return SVN_NO_ERROR;
-}
-
-
/*
* ========================================================================
*/
@@ -1327,12 +242,16 @@ svn_branch_find_nested_branch_element_by
scratch_pool))
{
svn_branch_state_t *subbranch = bi->val;
+ svn_branch_state_t *outer_branch;
+ int outer_eid;
const char *relpath_to_subbranch;
const char *relpath_in_subbranch;
+ svn_branch_get_outer_branch_and_eid(&outer_branch, &outer_eid,
+ subbranch, scratch_pool);
+
relpath_to_subbranch
- = svn_branch_get_path_by_eid(root_branch, subbranch->outer_eid,
- scratch_pool);
+ = svn_branch_get_path_by_eid(root_branch, outer_eid, scratch_pool);
relpath_in_subbranch
= svn_relpath_skip_ancestor(relpath_to_subbranch, relpath);
@@ -1355,23 +274,30 @@ svn_branch_find_nested_branch_element_by
*eid_p = svn_branch_get_eid_by_path(root_branch, relpath, scratch_pool);
}
-
-/*
- * ========================================================================
- */
-
-const char *
-svn_branch_get_id(svn_branch_state_t *branch,
- apr_pool_t *result_pool)
+svn_error_t *
+svn_branch_repos_find_el_rev_by_path_rev(svn_branch_el_rev_id_t **el_rev_p,
+ const svn_branch_repos_t *repos,
+ svn_revnum_t revnum,
+ const char *branch_id,
+ const char *relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- const char *id = "";
+ svn_branch_el_rev_id_t *el_rev = apr_palloc(result_pool, sizeof(*el_rev));
+ svn_branch_state_t *branch;
- while (branch->outer_branch)
- {
- id = apr_psprintf(result_pool, ".%d%s", branch->outer_eid, id);
- branch = branch->outer_branch;
- }
- id = apr_psprintf(result_pool, "B%d%s", branch->outer_eid, id);
- return id;
+ SVN_ERR(svn_branch_repos_get_branch_by_id(&branch,
+ repos, revnum, branch_id,
+ scratch_pool));
+ el_rev->rev = revnum;
+ svn_branch_find_nested_branch_element_by_relpath(&el_rev->branch,
+ &el_rev->eid,
+ branch, relpath,
+ scratch_pool);
+
+ /* Any relpath must at least be within the originally given branch */
+ SVN_ERR_ASSERT_NO_RETURN(el_rev->branch);
+ *el_rev_p = el_rev;
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c?rev=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/branch_repos.c Wed Oct 14 06:38:16 2015
@@ -71,17 +71,6 @@ svn_branch_repos_get_revision(const svn_
return svn_array_get(repos->rev_roots, revnum);
}
-struct svn_branch_state_t *
-svn_branch_repos_get_root_branch(const svn_branch_repos_t *repos,
- svn_revnum_t revnum,
- int top_branch_num)
-{
- svn_branch_revision_root_t *rev_root
- = svn_branch_repos_get_revision(repos, revnum);
-
- return svn_branch_revision_root_get_root_branch(rev_root, top_branch_num);
-}
-
svn_branch_revision_root_t *
svn_branch_repos_get_base_revision_root(svn_branch_revision_root_t *rev_root)
{
@@ -137,31 +126,4 @@ svn_branch_repos_find_el_rev_by_id(svn_b
*el_rev_p = el_rev;
return SVN_NO_ERROR;
}
-
-svn_error_t *
-svn_branch_repos_find_el_rev_by_path_rev(svn_branch_el_rev_id_t **el_rev_p,
- const svn_branch_repos_t *repos,
- svn_revnum_t revnum,
- const char *branch_id,
- const char *relpath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_branch_el_rev_id_t *el_rev = apr_palloc(result_pool, sizeof(*el_rev));
- svn_branch_state_t *branch;
-
- SVN_ERR(svn_branch_repos_get_branch_by_id(&branch,
- repos, revnum, branch_id,
- scratch_pool));
- el_rev->rev = revnum;
- svn_branch_find_nested_branch_element_by_relpath(&el_rev->branch,
- &el_rev->eid,
- branch, relpath,
- scratch_pool);
-
- /* Any relpath must at least be within the originally given branch */
- SVN_ERR_ASSERT_NO_RETURN(el_rev->branch);
- *el_rev_p = el_rev;
- return SVN_NO_ERROR;
-}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c?rev=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/compat3e.c Wed Oct 14 06:38:16 2015
@@ -32,6 +32,7 @@
#include "svn_pools.h"
#include "private/svn_branch_repos.h"
+#include "private/svn_branch_nested.h"
#include "private/svn_delta_private.h"
#include "private/svn_editor3e.h"
#include "../libsvn_delta/debug_editor.h"
@@ -952,18 +953,6 @@ apply_change(void **dir_baton,
* (A branch root is not necessarily a directory, it could be a file.)
*/
-/* */
-static int
-branch_get_top_num(const svn_branch_state_t *branch,
- apr_pool_t *scratch_pool)
-{
- while (branch->outer_branch)
- {
- branch = branch->outer_branch;
- }
- return branch->outer_eid;
-}
-
/* Get the old-repository path for the storage of the root element of BRANCH.
*
* Currently, this is the same as the nested-branching hierarchical path
@@ -973,7 +962,7 @@ static const char *
branch_get_storage_root_rrpath(const svn_branch_state_t *branch,
apr_pool_t *result_pool)
{
- int top_branch_num = branch_get_top_num(branch, result_pool);
+ int top_branch_num = atoi(branch->bid + 1);
const char *top_path = apr_psprintf(result_pool, "top%d", top_branch_num);
const char *nested_path = svn_branch_get_root_rrpath(branch, result_pool);
@@ -1187,7 +1176,6 @@ editor3_open_branch(void *baton,
{
ev3_from_delta_baton_t *eb = baton;
svn_branch_state_t *new_branch;
- svn_branch_state_t *outer_branch = NULL;
/* if the subbranch already exists, just return its bid */
*new_branch_id_p
@@ -1204,14 +1192,10 @@ editor3_open_branch(void *baton,
return SVN_NO_ERROR;
}
- if (outer_branch_id)
- outer_branch = svn_branch_revision_root_get_branch_by_id(
- eb->edited_rev_root, outer_branch_id, scratch_pool);
- new_branch = svn_branch_add_new_branch(eb->edited_rev_root,
+ new_branch = svn_branch_add_new_branch(*new_branch_id_p,
+ eb->edited_rev_root,
predecessor,
- outer_branch, outer_eid,
root_eid, scratch_pool);
- *new_branch_id_p = svn_branch_get_id(new_branch, result_pool);
return SVN_NO_ERROR;
}
@@ -1228,7 +1212,6 @@ editor3_branch(void *baton,
ev3_from_delta_baton_t *eb = baton;
svn_branch_rev_bid_t *predecessor;
svn_branch_state_t *new_branch;
- svn_branch_state_t *outer_branch = NULL;
svn_branch_state_t *from_branch;
svn_branch_subtree_t *from_subtree;
@@ -1244,20 +1227,18 @@ editor3_branch(void *baton,
from->rev, from->bid, from->eid);
}
- if (outer_branch_id)
- outer_branch = svn_branch_revision_root_get_branch_by_id(
- eb->edited_rev_root, outer_branch_id, scratch_pool);
+ *new_branch_id_p
+ = svn_branch_id_nest(outer_branch_id, outer_eid, result_pool);
predecessor = svn_branch_rev_bid_create(from->rev, from->bid, scratch_pool);
- new_branch = svn_branch_add_new_branch(eb->edited_rev_root,
+ new_branch = svn_branch_add_new_branch(*new_branch_id_p,
+ eb->edited_rev_root,
predecessor,
- outer_branch, outer_eid,
from->eid, scratch_pool);
/* Populate the mapping from the 'from' source */
- SVN_ERR(svn_branch_instantiate_elements(new_branch, *from_subtree,
- scratch_pool));
+ SVN_ERR(svn_branch_instantiate_elements_r(new_branch, *from_subtree,
+ scratch_pool));
- *new_branch_id_p = svn_branch_get_id(new_branch, result_pool);
return SVN_NO_ERROR;
}
@@ -1843,17 +1824,20 @@ drive_changes(ev3_from_delta_baton_t *eb
for (i = 0; i < eb->edited_rev_root->root_branches->nelts; i++)
{
svn_branch_state_t *root_branch
- = svn_branch_revision_root_get_root_branch(eb->edited_rev_root, i);
+ = APR_ARRAY_IDX(eb->edited_rev_root->root_branches, i, void *);
apr_hash_t *paths_final;
const char *top_path = branch_get_storage_root_rrpath(root_branch,
scratch_pool);
svn_pathrev_t current;
- svn_branch_state_t *base_root_branch
- = svn_branch_repos_get_root_branch(eb->edited_rev_root->repos,
- eb->edited_rev_root->base_rev,
- root_branch->outer_eid /*top_branch_num*/);
- svn_boolean_t branch_is_new = !base_root_branch;
+ svn_branch_state_t *base_root_branch;
+ svn_boolean_t branch_is_new;
+
+ SVN_ERR(svn_branch_repos_get_branch_by_id(&base_root_branch,
+ eb->edited_rev_root->repos,
+ eb->edited_rev_root->base_rev,
+ root_branch->bid, scratch_pool));
+ branch_is_new = !base_root_branch;
paths_final = apr_hash_make(scratch_pool);
convert_branch_to_paths_r(paths_final,
@@ -1913,13 +1897,35 @@ editor3_sequence_point(void *baton,
ev3_from_delta_baton_t *eb = baton;
int i;
- for (i = 0; i < eb->edited_rev_root->root_branches->nelts; i++)
+ /* first, purge elements in each branch */
+ for (i = 0; i < eb->edited_rev_root->branches->nelts; i++)
+ {
+ svn_branch_state_t *b
+ = APR_ARRAY_IDX(eb->edited_rev_root->branches, i, void *);
+
+ svn_branch_purge(b, scratch_pool);
+ }
+
+ /* second, purge branches that are no longer nested */
+ for (i = 0; i < eb->edited_rev_root->branches->nelts; i++)
{
svn_branch_state_t *b
- = svn_branch_revision_root_get_root_branch(eb->edited_rev_root, i);
+ = APR_ARRAY_IDX(eb->edited_rev_root->branches, i, void *);
+ svn_branch_state_t *outer_branch;
+ int outer_eid;
+
+ svn_branch_get_outer_branch_and_eid(&outer_branch, &outer_eid,
+ b, scratch_pool);
- svn_branch_purge_r(b, scratch_pool);
+ if (outer_branch
+ && ! svn_branch_get_element(outer_branch, outer_eid))
+ {
+ svn_branch_revision_root_delete_branch(b->rev_root, b, scratch_pool);
+ /* Re-visit this position in the array */
+ i--;
+ }
}
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Wed Oct 14 06:38:16 2015
@@ -46,6 +46,7 @@
#include "private/svn_cmdline_private.h"
#include "private/svn_subr_private.h"
#include "private/svn_branch_repos.h"
+#include "private/svn_branch_nested.h"
#include "private/svn_editor3e.h"
#include "private/svn_ra_private.h"
#include "private/svn_string_private.h"
@@ -1010,10 +1011,14 @@ branch_id_str(svn_branch_state_t *branch
else
{
svn_branch_el_rev_content_t *outer_el = NULL;
+ svn_branch_state_t *outer_branch;
+ int outer_eid;
- if (branch->outer_branch)
- outer_el = svn_branch_get_element(branch->outer_branch,
- branch->outer_eid);
+ svn_branch_get_outer_branch_and_eid(&outer_branch, &outer_eid,
+ branch, scratch_pool);
+
+ if (outer_branch)
+ outer_el = svn_branch_get_element(outer_branch, outer_eid);
return apr_psprintf(result_pool, "%-10s %-12s root=e%d",
svn_branch_get_id(branch, scratch_pool),
@@ -2515,8 +2520,8 @@ do_branch_into(svn_branch_state_t *from_
new_root_content);
/* Populate the new branch mapping */
- SVN_ERR(svn_branch_instantiate_elements(to_branch, *from_subtree,
- scratch_pool));
+ SVN_ERR(svn_branch_instantiate_elements_r(to_branch, *from_subtree,
+ scratch_pool));
notify_v("A+ %s (subtree)",
svn_branch_get_path_by_eid(to_branch, from_eid, scratch_pool));
@@ -2998,17 +3003,24 @@ typedef struct arg_t
*/
static svn_error_t *
point_to_outer_element_instead(svn_branch_el_rev_id_t *el_rev,
- const char *op)
+ const char *op,
+ apr_pool_t *scratch_pool)
{
if (is_branch_root_element(el_rev->branch, el_rev->eid))
{
- if (! el_rev->branch->outer_branch)
+ svn_branch_state_t *outer_branch;
+ int outer_eid;
+
+ svn_branch_get_outer_branch_and_eid(&outer_branch, &outer_eid,
+ el_rev->branch, scratch_pool);
+
+ if (! outer_branch)
return svn_error_createf(SVN_ERR_BRANCHING, NULL, "%s: %s", op,
_("svnmover cannot delete or move a "
"top-level branch"));
- el_rev->eid = el_rev->branch->outer_eid;
- el_rev->branch = el_rev->branch->outer_branch;
+ el_rev->eid = outer_eid;
+ el_rev->branch = outer_branch;
}
return SVN_NO_ERROR;
@@ -3290,7 +3302,8 @@ execute(svnmover_wc_t *wc,
break;
case ACTION_MV:
- SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev, "mv"));
+ SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev, "mv",
+ iterpool));
VERIFY_REV_UNSPECIFIED("mv", 0);
VERIFY_EID_EXISTS("mv", 0);
@@ -3333,7 +3346,8 @@ execute(svnmover_wc_t *wc,
break;
case ACTION_RM:
- SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev, "rm"));
+ SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev, "rm",
+ iterpool));
VERIFY_REV_UNSPECIFIED("rm", 0);
VERIFY_EID_EXISTS("rm", 0);
@@ -3344,7 +3358,7 @@ execute(svnmover_wc_t *wc,
case ACTION_CP_RM:
SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev,
- "copy-and-delete"));
+ "copy-and-delete", iterpool));
VERIFY_REV_UNSPECIFIED("copy-and-delete", 0);
VERIFY_EID_EXISTS("copy-and-delete", 0);
@@ -3363,7 +3377,8 @@ execute(svnmover_wc_t *wc,
case ACTION_BR_RM:
SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev,
- "branch-and-delete"));
+ "branch-and-delete",
+ iterpool));
VERIFY_REV_UNSPECIFIED("branch-and-delete", 0);
VERIFY_EID_EXISTS("branch-and-delete", 0);
@@ -3382,7 +3397,8 @@ execute(svnmover_wc_t *wc,
case ACTION_BR_INTO_RM:
SVN_ERR(point_to_outer_element_instead(arg[0]->el_rev,
- "branch-into-and-delete"));
+ "branch-into-and-delete",
+ iterpool));
VERIFY_REV_UNSPECIFIED("branch-into-and-delete", 0);
VERIFY_EID_EXISTS("branch-into-and-delete", 0);
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py?rev=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnmover_tests.py Wed Oct 14 06:38:16 2015
@@ -1340,13 +1340,14 @@ def merge_swap_abc(sbox):
sbox_build_svnmover(sbox)
expected_eids = svntest.wc.State('', {
- '' : Item(eid=0),
- 'X' : Item(eid=2),
- 'X/A' : Item(eid=3),
- 'X/A/a1' : Item(eid=4),
- 'X/A/B' : Item(eid=5),
- 'X/A/B/C' : Item(eid=6),
- 'X/A/B/C/c1' : Item(eid=7),
+ 'B0' : Item(eid=0),
+ 'B0/X' : Item(eid=1),
+ 'B0.1' : Item(eid=2),
+ 'B0.1/A' : Item(eid=3),
+ 'B0.1/A/a1' : Item(eid=4),
+ 'B0.1/A/B' : Item(eid=5),
+ 'B0.1/A/B/C' : Item(eid=6),
+ 'B0.1/A/B/C/c1' : Item(eid=7),
})
test_svnmover3(sbox, '',
reported_br_diff('') +
@@ -1360,20 +1361,21 @@ def merge_swap_abc(sbox):
'mkdir X/A/B/C/c1')
expected_eids.add({
- 'Y' : Item(eid=2),
- 'Y/A' : Item(eid=3),
- 'Y/A/a1' : Item(eid=4),
- 'Y/A/B' : Item(eid=5),
- 'Y/A/B/C' : Item(eid=6),
- 'Y/A/B/C/c1' : Item(eid=7),
+ 'B0/Y' : Item(eid=8),
+ 'B0.8' : Item(eid=2),
+ 'B0.8/A' : Item(eid=3),
+ 'B0.8/A/a1' : Item(eid=4),
+ 'B0.8/A/B' : Item(eid=5),
+ 'B0.8/A/B/C' : Item(eid=6),
+ 'B0.8/A/B/C/c1' : Item(eid=7),
})
test_svnmover3(sbox, '', None, expected_eids,
'branch X Y')
expected_eids.rename({
- 'X/A/B/C' : 'X/A',
- 'X/A/B' : 'X/A/B',
- 'X/A' : 'X/A/B/C',
+ 'B0.1/A/B/C' : 'B0.1/A',
+ 'B0.1/A/B' : 'B0.1/A/B',
+ 'B0.1/A' : 'B0.1/A/B/C',
})
test_svnmover3(sbox, '',
reported_br_diff('X') +
@@ -1387,9 +1389,9 @@ def merge_swap_abc(sbox):
'mv X/C X/A')
expected_eids.rename({
- 'Y/A' : 'Y/A/B/C',
- 'Y/A/B' : 'Y/A/B',
- 'Y/A/B/C' : 'Y/A',
+ 'B0.8/A' : 'B0.8/A/B/C',
+ 'B0.8/A/B' : 'B0.8/A/B',
+ 'B0.8/A/B/C' : 'B0.8/A',
})
test_svnmover3(sbox, '',
reported_br_diff('Y') +
@@ -1404,10 +1406,11 @@ def move_to_related_branch_2(sbox):
sbox_build_svnmover(sbox)
expected_eids = svntest.wc.State('', {
- '' : Item(eid=0),
- 'X' : Item(eid=2),
- 'X/A' : Item(eid=3),
- 'X/A/B' : Item(eid=4),
+ 'B0' : Item(eid=0),
+ 'B0/X' : Item(eid=1),
+ 'B0.1' : Item(eid=2),
+ 'B0.1/A' : Item(eid=3),
+ 'B0.1/A/B' : Item(eid=4),
})
test_svnmover3(sbox, '',
reported_br_diff('') +
@@ -1418,9 +1421,10 @@ def move_to_related_branch_2(sbox):
'mkdir X/A/B')
expected_eids.add({
- 'Y' : Item(eid=2),
- 'Y/A' : Item(eid=3),
- 'Y/A/B' : Item(eid=4),
+ 'B0/Y' : Item(eid=5),
+ 'B0.5' : Item(eid=2),
+ 'B0.5/A' : Item(eid=3),
+ 'B0.5/A/B' : Item(eid=4),
})
test_svnmover3(sbox, '',
reported_br_diff('') +
@@ -1429,10 +1433,10 @@ def move_to_related_branch_2(sbox):
'branch X Y')
expected_eids.add({
- 'X/A/ax' : Item(eid=6),
- 'X/A/B/bx' : Item(eid=7),
- 'Y/A/ay' : Item(eid=8),
- 'Y/A/B/by' : Item(eid=9),
+ 'B0.1/A/ax' : Item(eid=6),
+ 'B0.1/A/B/bx' : Item(eid=7),
+ 'B0.5/A/ay' : Item(eid=8),
+ 'B0.5/A/B/by' : Item(eid=9),
})
test_svnmover3(sbox, '',
reported_br_diff('X') +
@@ -1450,10 +1454,10 @@ def move_to_related_branch_2(sbox):
# X and Y are related, X/A/B contains X/A/B/bx, Y/A/B contains Y/A/B/by.
# Moving X/A/B to Y/B, i.e. from X to Y, by branch-into-and-delete,
# results in Y/B that contains both bx and by.
- expected_eids.rename({'X/A/B' : 'Y/B'})
- expected_eids.remove('Y/A/B', 'Y/A/B/by')
+ expected_eids.rename({'B0.1/A/B' : 'B0.5/B'})
+ expected_eids.remove('B0.5/A/B', 'B0.5/A/B/by')
expected_eids.add({
- 'Y/B/by' : Item(eid=9),
+ 'B0.5/B/by' : Item(eid=9),
})
test_svnmover3(sbox, '',
reported_br_diff('X') +
Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py?rev=1708550&r1=1708549&r2=1708550&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svntest/wc.py Wed Oct 14 06:38:16 2015
@@ -119,13 +119,11 @@ _re_parse_commit = re.compile('^(\w+( \
#rN: eids 0 15 branches 4
_re_parse_eid_header = re.compile('^r(-1|[0-9]+): eids ([0-9]+) ([0-9]+) '
'branches ([0-9]+)$')
-# B0.2 root-eid 3 # at /X
-_re_parse_eid_branch = re.compile('^B([0-9.]+) root-eid ([0-9]+) num-eids ([0-9]+)( from [^ ]*)? # at /(.*)$')
+# B0.2 root-eid 3
+_re_parse_eid_branch = re.compile('^(B[0-9.]+) root-eid ([0-9]+) num-eids ([0-9]+)( from [^ ]*)?$')
# e4: normal 6 C
_re_parse_eid_ele = re.compile('^e([0-9]+): (none|normal|subbranch) '
'(-1|[0-9]+) (.*)$')
-# 25.34.78
-_re_parse_split_branch_eid = re.compile('^([0-9.]+)\.([0-9]+)$')
class State:
"""Describes an existing or expected state of a working copy.
@@ -789,6 +787,7 @@ class State:
# Need to read all elements in a branch before we can construct
# the full path to an element.
+ # For the full path we use <branch-id>/<path-within-branch>.
def eid_path(eids, eid):
ele = eids[eid]
@@ -799,20 +798,17 @@ class State:
return ele[1]
return parent_path + '/' + ele[1]
- def eid_full_path(eids, eid, root_path):
+ def eid_full_path(eids, eid, branch_id):
path = eid_path(eids, eid)
- if root_path == '':
- return eid_path(eids, eid)
if path == '':
- return root_path
- return root_path + '/' + eid_path(eids, eid)
+ return branch_id
+ return branch_id + '/' + path
- def add_to_desc(eids, desc, branch_root_path):
+ def add_to_desc(eids, desc, branch_id):
for k, v in eids.items():
- desc[eid_full_path(eids, k, branch_root_path)] = StateItem(eid=k)
+ desc[eid_full_path(eids, k, branch_id)] = StateItem(eid=k)
- branches = {}
- branch = None
+ branch_id = None
eids = {}
desc = {}
for line in lines:
@@ -828,21 +824,13 @@ class State:
match = _re_parse_eid_branch.search(line)
if match:
- if branch:
- branches[branch[0]] = branch
- add_to_desc(eids, desc, branch[3])
+ if branch_id:
+ add_to_desc(eids, desc, branch_id)
eids = {}
- parent_branch_eid = None
- branch_eid = match.group(1)
- match2 = _re_parse_split_branch_eid.search(branch_eid)
- if match2:
- parent_branch_eid = branches[match2.group(1)]
+ branch_id = match.group(1)
root_eid = match.group(2)
- path = match.group(5)
- branch = [branch_eid, parent_branch_eid, root_eid, path]
- branches[branch[0]] = branch
- add_to_desc(eids, desc, branch[3])
+ add_to_desc(eids, desc, branch_id)
return cls('', desc)