You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2018/11/07 12:30:11 UTC
svn commit: r1846002 [21/44] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/generator/swig/
build/generator/templates/ build/generator/util/ build/win32/
contrib/client-side/ contrib/client-side/svn_load_dirs/ contr...
Modified: subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/upgrade.c Wed Nov 7 12:30:06 2018
@@ -653,178 +653,6 @@ ensure_repos_info(svn_wc_entry_t *entry,
}
-/*
- * Read tree conflict descriptions from @a conflict_data. Set @a *conflicts
- * to a hash of pointers to svn_wc_conflict_description2_t objects indexed by
- * svn_wc_conflict_description2_t.local_abspath, all newly allocated in @a
- * pool. @a dir_path is the path to the working copy directory whose conflicts
- * are being read. The conflicts read are the tree conflicts on the immediate
- * child nodes of @a dir_path. Do all allocations in @a pool.
- *
- * Note: There were some concerns about this function:
- *
- * ### this is BAD. the CONFLICTS structure should not be dependent upon
- * ### DIR_PATH. each conflict should be labeled with an entry name, not
- * ### a whole path. (and a path which happens to vary based upon invocation
- * ### of the user client and these APIs)
- *
- * those assumptions were baked into former versions of the data model, so
- * they have to stick around here. But they have been removed from the
- * New Way. */
-static svn_error_t *
-read_tree_conflicts(apr_hash_t **conflicts,
- const char *conflict_data,
- const char *dir_path,
- apr_pool_t *pool)
-{
- const svn_skel_t *skel;
- apr_pool_t *iterpool;
-
- *conflicts = apr_hash_make(pool);
-
- if (conflict_data == NULL)
- return SVN_NO_ERROR;
-
- skel = svn_skel__parse(conflict_data, strlen(conflict_data), pool);
- if (skel == NULL)
- return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,
- _("Error parsing tree conflict skel"));
-
- iterpool = svn_pool_create(pool);
- for (skel = skel->children; skel != NULL; skel = skel->next)
- {
- const svn_wc_conflict_description2_t *conflict;
-
- svn_pool_clear(iterpool);
- SVN_ERR(svn_wc__deserialize_conflict(&conflict, skel, dir_path,
- pool, iterpool));
- if (conflict != NULL)
- svn_hash_sets(*conflicts,
- svn_dirent_basename(conflict->local_abspath, pool),
- conflict);
- }
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-/* */
-static svn_error_t *
-migrate_single_tree_conflict_data(svn_sqlite__db_t *sdb,
- const char *tree_conflict_data,
- apr_int64_t wc_id,
- const char *local_relpath,
- apr_pool_t *scratch_pool)
-{
- apr_hash_t *conflicts;
- apr_hash_index_t *hi;
- apr_pool_t *iterpool;
-
- SVN_ERR(read_tree_conflicts(&conflicts, tree_conflict_data, local_relpath,
- scratch_pool));
-
- iterpool = svn_pool_create(scratch_pool);
- for (hi = apr_hash_first(scratch_pool, conflicts);
- hi;
- hi = apr_hash_next(hi))
- {
- const svn_wc_conflict_description2_t *conflict = apr_hash_this_val(hi);
- const char *conflict_relpath;
- const char *conflict_data;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
- svn_skel_t *skel;
-
- svn_pool_clear(iterpool);
-
- conflict_relpath = svn_dirent_join(local_relpath,
- svn_dirent_basename(
- conflict->local_abspath, iterpool),
- iterpool);
-
- SVN_ERR(svn_wc__serialize_conflict(&skel, conflict, iterpool, iterpool));
- conflict_data = svn_skel__unparse(skel, iterpool)->data;
-
- /* See if we need to update or insert an ACTUAL node. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, conflict_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- SVN_ERR(svn_sqlite__reset(stmt));
-
- if (have_row)
- {
- /* There is an existing ACTUAL row, so just update it. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPDATE_ACTUAL_CONFLICT));
- }
- else
- {
- /* We need to insert an ACTUAL row with the tree conflict data. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_INSERT_ACTUAL_CONFLICT));
- }
-
- SVN_ERR(svn_sqlite__bindf(stmt, "iss", wc_id, conflict_relpath,
- conflict_data));
- if (!have_row)
- SVN_ERR(svn_sqlite__bind_text(stmt, 4, local_relpath));
-
- SVN_ERR(svn_sqlite__step_done(stmt));
- }
-
- svn_pool_destroy(iterpool);
-
- return SVN_NO_ERROR;
-}
-
-
-/* */
-static svn_error_t *
-migrate_tree_conflict_data(svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
- apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
- /* Iterate over each node which has a set of tree conflicts, then insert
- all of them into the new schema. */
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPGRADE_21_SELECT_OLD_TREE_CONFLICT));
-
- /* Get all the existing tree conflict data. */
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- while (have_row)
- {
- apr_int64_t wc_id;
- const char *local_relpath;
- const char *tree_conflict_data;
-
- svn_pool_clear(iterpool);
-
- wc_id = svn_sqlite__column_int64(stmt, 0);
- local_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
- tree_conflict_data = svn_sqlite__column_text(stmt, 2, iterpool);
-
- SVN_ERR(migrate_single_tree_conflict_data(sdb, tree_conflict_data,
- wc_id, local_relpath,
- iterpool));
-
- /* We don't need to do anything but step over the previously
- prepared statement. */
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
- SVN_ERR(svn_sqlite__reset(stmt));
-
- /* Erase all the old tree conflict data. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPGRADE_21_ERASE_OLD_CONFLICTS));
- SVN_ERR(svn_sqlite__step_done(stmt));
-
- svn_pool_destroy(iterpool);
- return SVN_NO_ERROR;
-}
-
/* ### need much more docco
### this function should be called within a sqlite transaction. it makes
@@ -1318,234 +1146,6 @@ migrate_text_bases(apr_hash_t **text_bas
return SVN_NO_ERROR;
}
-static svn_error_t *
-bump_to_20(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_NODES));
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_20));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_21(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_21));
- SVN_ERR(migrate_tree_conflict_data(sdb, scratch_pool));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_22(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_22));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_23(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- const char *wcroot_abspath = ((struct bump_baton *)baton)->wcroot_abspath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPGRADE_23_HAS_WORKING_NODES));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- SVN_ERR(svn_sqlite__reset(stmt));
- if (have_row)
- return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("The working copy at '%s' is format 22 with "
- "WORKING nodes; use a format 22 client to "
- "diff/revert before using this client"),
- wcroot_abspath);
-
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_23));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_24(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_24));
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_NODES_TRIGGERS));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_25(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_25));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_26(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_26));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_27(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- const char *wcroot_abspath = ((struct bump_baton *)baton)->wcroot_abspath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPGRADE_27_HAS_ACTUAL_NODES_CONFLICTS));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- SVN_ERR(svn_sqlite__reset(stmt));
- if (have_row)
- return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
- _("The working copy at '%s' is format 26 with "
- "conflicts; use a format 26 client to resolve "
- "before using this client"),
- wcroot_abspath);
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_27));
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-bump_to_28(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_28));
- return SVN_NO_ERROR;
-}
-
-/* If FINFO indicates that ABSPATH names a file, rename it to
- * '<ABSPATH>.svn-base'.
- *
- * Ignore any file whose name is not the expected length, in order to make
- * life easier for any developer who runs this code twice or has some
- * non-standard files in the pristine directory.
- *
- * A callback for bump_to_29(), implementing #svn_io_walk_func_t. */
-static svn_error_t *
-rename_pristine_file(void *baton,
- const char *abspath,
- const apr_finfo_t *finfo,
- apr_pool_t *pool)
-{
- if (finfo->filetype == APR_REG
- && (strlen(svn_dirent_basename(abspath, pool))
- == PRISTINE_BASENAME_OLD_LEN))
- {
- const char *new_abspath
- = apr_pstrcat(pool, abspath, PRISTINE_STORAGE_EXT, SVN_VA_NULL);
-
- SVN_ERR(svn_io_file_rename2(abspath, new_abspath, FALSE, pool));
- }
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-upgrade_externals(struct bump_baton *bb,
- svn_sqlite__db_t *sdb,
- apr_pool_t *scratch_pool)
-{
- svn_sqlite__stmt_t *stmt;
- svn_sqlite__stmt_t *stmt_add;
- svn_boolean_t have_row;
- apr_pool_t *iterpool;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_SELECT_EXTERNAL_PROPERTIES));
-
- SVN_ERR(svn_sqlite__get_statement(&stmt_add, sdb,
- STMT_INSERT_EXTERNAL));
-
- /* ### For this intermediate upgrade we just assume WC_ID = 1.
- ### Before this bump we lost track of externals all the time,
- ### so lets keep this easy. */
- SVN_ERR(svn_sqlite__bindf(stmt, "is", (apr_int64_t)1, ""));
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
- iterpool = svn_pool_create(scratch_pool);
- while (have_row)
- {
- apr_hash_t *props;
- const char *externals;
-
- svn_pool_clear(iterpool);
-
- SVN_ERR(svn_sqlite__column_properties(&props, stmt, 0,
- iterpool, iterpool));
-
- externals = svn_prop_get_value(props, SVN_PROP_EXTERNALS);
-
- if (externals)
- {
- apr_array_header_t *ext;
- const char *local_relpath;
- const char *local_abspath;
- int i;
-
- local_relpath = svn_sqlite__column_text(stmt, 1, NULL);
- local_abspath = svn_dirent_join(bb->wcroot_abspath, local_relpath,
- iterpool);
-
- SVN_ERR(svn_wc_parse_externals_description3(&ext, local_abspath,
- externals, FALSE,
- iterpool));
-
- for (i = 0; i < ext->nelts; i++)
- {
- const svn_wc_external_item2_t *item;
- const char *item_relpath;
-
- item = APR_ARRAY_IDX(ext, i, const svn_wc_external_item2_t *);
- item_relpath = svn_relpath_join(local_relpath, item->target_dir,
- iterpool);
-
- /* Insert dummy externals definitions: Insert an unknown
- external, to make sure it will be cleaned up when it is not
- updated on the next update. */
- SVN_ERR(svn_sqlite__bindf(stmt_add, "isssssis",
- (apr_int64_t)1, /* wc_id */
- item_relpath,
- svn_relpath_dirname(item_relpath,
- iterpool),
- "normal",
- "unknown",
- local_relpath,
- (apr_int64_t)1, /* repos_id */
- "" /* repos_relpath */));
- SVN_ERR(svn_sqlite__insert(NULL, stmt_add));
- }
- }
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
-
- svn_pool_destroy(iterpool);
- return svn_error_trace(svn_sqlite__reset(stmt));
-}
-
-static svn_error_t *
-bump_to_29(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
-{
- struct bump_baton *bb = baton;
- const char *wcroot_abspath = bb->wcroot_abspath;
- const char *pristine_dir_abspath;
-
- /* Rename all pristine files, adding a ".svn-base" suffix. */
- pristine_dir_abspath = svn_dirent_join_many(scratch_pool, wcroot_abspath,
- svn_wc_get_adm_dir(scratch_pool),
- PRISTINE_STORAGE_RELPATH,
- SVN_VA_NULL);
- SVN_ERR(svn_io_dir_walk2(pristine_dir_abspath, APR_FINFO_MIN,
- rename_pristine_file, NULL, scratch_pool));
-
- /* Externals */
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_EXTERNALS));
-
- SVN_ERR(upgrade_externals(bb, sdb, scratch_pool));
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_29));
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_wc__upgrade_conflict_skel_from_raw(svn_skel_t **conflicts,
svn_wc__db_t *db,
@@ -1637,7 +1237,7 @@ svn_wc__upgrade_conflict_skel_from_raw(s
db, wri_abspath,
tc->reason,
tc->action,
- NULL,
+ NULL, NULL,
scratch_pool,
scratch_pool));
@@ -1774,41 +1374,10 @@ bump_to_31(void *baton,
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_array_header_t *empty_iprops = apr_array_make(
scratch_pool, 0, sizeof(svn_prop_inherited_item_t *));
- svn_boolean_t iprops_column_exists = FALSE;
svn_error_t *err;
- /* Add the inherited_props column to NODES if it does not yet exist.
- *
- * When using a format >= 31 client to upgrade from old formats which
- * did not yet have a NODES table, the inherited_props column has
- * already been created as part of the NODES table. Attemping to add
- * the inherited_props column will raise an error in this case, so check
- * if the column exists first.
- *
- * Checking for the existence of a column before ALTER TABLE is not
- * possible within SQLite. We need to run a separate query and evaluate
- * its result in C first.
- */
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PRAGMA_TABLE_INFO_NODES));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- while (have_row)
- {
- const char *column_name = svn_sqlite__column_text(stmt, 1, NULL);
-
- if (strcmp(column_name, "inherited_props") == 0)
- {
- iprops_column_exists = TRUE;
- break;
- }
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- }
- SVN_ERR(svn_sqlite__reset(stmt));
- if (!iprops_column_exists)
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_31_ALTER_TABLE));
-
/* Run additional statements to finalize the upgrade to format 31. */
- SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_31_FINALIZE));
+ SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_31));
/* Set inherited_props to an empty array for the roots of all
switched subtrees in the WC. This allows subsequent updates
@@ -2090,6 +1659,15 @@ svn_wc__upgrade_sdb(int *result_format,
svn_dirent_local_style(wcroot_abspath,
scratch_pool),
start_format);
+ else if (start_format < 29)
+ return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,
+ _("Working copy '%s' is an old development "
+ "version (format %d); to upgrade it, "
+ "use a Subversion 1.7-1.9 client, then "
+ "use the current client"),
+ svn_dirent_local_style(wcroot_abspath,
+ scratch_pool),
+ start_format);
/* ### need lock-out. only one upgrade at a time. note that other code
### cannot use this un-upgraded database until we finish the upgrade. */
@@ -2098,66 +1676,6 @@ svn_wc__upgrade_sdb(int *result_format,
intentional. */
switch (start_format)
{
- case 19:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_20, &bb,
- scratch_pool));
- *result_format = 20;
- /* FALLTHROUGH */
-
- case 20:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_21, &bb,
- scratch_pool));
- *result_format = 21;
- /* FALLTHROUGH */
-
- case 21:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_22, &bb,
- scratch_pool));
- *result_format = 22;
- /* FALLTHROUGH */
-
- case 22:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_23, &bb,
- scratch_pool));
- *result_format = 23;
- /* FALLTHROUGH */
-
- case 23:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_24, &bb,
- scratch_pool));
- *result_format = 24;
- /* FALLTHROUGH */
-
- case 24:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_25, &bb,
- scratch_pool));
- *result_format = 25;
- /* FALLTHROUGH */
-
- case 25:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_26, &bb,
- scratch_pool));
- *result_format = 26;
- /* FALLTHROUGH */
-
- case 26:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_27, &bb,
- scratch_pool));
- *result_format = 27;
- /* FALLTHROUGH */
-
- case 27:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_28, &bb,
- scratch_pool));
- *result_format = 28;
- /* FALLTHROUGH */
-
- case 28:
- SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_29, &bb,
- scratch_pool));
- *result_format = 29;
- /* FALLTHROUGH */
-
case 29:
SVN_ERR(svn_sqlite__with_transaction(sdb, bump_to_30, &bb,
scratch_pool));
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc-metadata.sql Wed Nov 7 12:30:06 2018
@@ -229,11 +229,6 @@ CREATE TABLE WC_LOCK (
);
-PRAGMA user_version =
--- define: SVN_WC__VERSION
-;
-
-
/* ------------------------------------------------------------------------- */
/* The NODES table describes the way WORKING nodes are layered on top of
@@ -279,7 +274,6 @@ PRAGMA user_version =
An 'svn revert foo/bar' would remove the NODES of (2).
*/
--- STMT_CREATE_NODES
CREATE TABLE NODES (
/* Working copy location related fields */
@@ -503,8 +497,6 @@ CREATE VIEW NODES_BASE AS
SELECT * FROM nodes
WHERE op_depth = 0;
--- STMT_CREATE_NODES_TRIGGERS
-
CREATE TRIGGER nodes_insert_trigger
AFTER INSERT ON nodes
WHEN NEW.checksum IS NOT NULL
@@ -532,8 +524,6 @@ BEGIN
WHERE checksum = OLD.checksum;
END;
--- STMT_CREATE_EXTERNALS
-
CREATE TABLE EXTERNALS (
/* Working copy location related fields (like NODES)*/
@@ -572,6 +562,12 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED
def_local_relpath,
local_relpath);
+
+PRAGMA user_version =
+-- define: SVN_WC__VERSION
+;
+
+
/* ------------------------------------------------------------------------- */
/* This statement provides SQLite with the necessary information about our
indexes to make better decisions in the query planner.
@@ -630,208 +626,6 @@ INSERT INTO sqlite_stat1(tbl, idx, stat)
ANALYZE sqlite_master; /* Loads sqlite_stat1 data for query optimizer */
/* ------------------------------------------------------------------------- */
-/* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */
-
--- STMT_UPGRADE_TO_20
-
-UPDATE BASE_NODE SET checksum = (SELECT checksum FROM pristine
- WHERE md5_checksum = BASE_NODE.checksum)
-WHERE EXISTS (SELECT 1 FROM pristine WHERE md5_checksum = BASE_NODE.checksum);
-
-UPDATE WORKING_NODE SET checksum = (SELECT checksum FROM pristine
- WHERE md5_checksum = WORKING_NODE.checksum)
-WHERE EXISTS (SELECT 1 FROM pristine
- WHERE md5_checksum = WORKING_NODE.checksum);
-
-INSERT INTO NODES (
- wc_id, local_relpath, op_depth, parent_relpath,
- repos_id, repos_path, revision,
- presence, depth, moved_here, moved_to, kind,
- changed_revision, changed_date, changed_author,
- checksum, properties, translated_size, last_mod_time,
- dav_cache, symlink_target, file_external )
-SELECT wc_id, local_relpath, 0 /*op_depth*/, parent_relpath,
- repos_id, repos_relpath, revnum,
- presence, depth, NULL /*moved_here*/, NULL /*moved_to*/, kind,
- changed_rev, changed_date, changed_author,
- checksum, properties, translated_size, last_mod_time,
- dav_cache, symlink_target, file_external
-FROM BASE_NODE;
-INSERT INTO NODES (
- wc_id, local_relpath, op_depth, parent_relpath,
- repos_id, repos_path, revision,
- presence, depth, moved_here, moved_to, kind,
- changed_revision, changed_date, changed_author,
- checksum, properties, translated_size, last_mod_time,
- dav_cache, symlink_target, file_external )
-SELECT wc_id, local_relpath, 2 /*op_depth*/, parent_relpath,
- copyfrom_repos_id, copyfrom_repos_path, copyfrom_revnum,
- presence, depth, NULL /*moved_here*/, NULL /*moved_to*/, kind,
- changed_rev, changed_date, changed_author,
- checksum, properties, translated_size, last_mod_time,
- NULL /*dav_cache*/, symlink_target, NULL /*file_external*/
-FROM WORKING_NODE;
-
-DROP TABLE BASE_NODE;
-DROP TABLE WORKING_NODE;
-
-PRAGMA user_version = 20;
-
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 21 involves no schema changes, it moves the tree conflict victim
- information to victime nodes, rather than parents. */
-
--- STMT_UPGRADE_TO_21
-PRAGMA user_version = 21;
-
-/* For format 21 bump code */
--- STMT_UPGRADE_21_SELECT_OLD_TREE_CONFLICT
-SELECT wc_id, local_relpath, tree_conflict_data
-FROM actual_node
-WHERE tree_conflict_data IS NOT NULL
-
-/* For format 21 bump code */
--- STMT_UPGRADE_21_ERASE_OLD_CONFLICTS
-UPDATE actual_node SET tree_conflict_data = NULL
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 22 simply moves the tree conflict information from the conflict_data
- column to the tree_conflict_data column. */
-
--- STMT_UPGRADE_TO_22
-UPDATE actual_node SET tree_conflict_data = conflict_data;
-UPDATE actual_node SET conflict_data = NULL;
-
-PRAGMA user_version = 22;
-
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 23 involves no schema changes, it introduces multi-layer
- op-depth processing for NODES. */
-
--- STMT_UPGRADE_TO_23
-PRAGMA user_version = 23;
-
--- STMT_UPGRADE_23_HAS_WORKING_NODES
-SELECT 1 FROM nodes WHERE op_depth > 0
-LIMIT 1
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 24 involves no schema changes; it starts using the pristine
- table's refcount column correctly. */
-
--- STMT_UPGRADE_TO_24
-UPDATE pristine SET refcount =
- (SELECT COUNT(*) FROM nodes
- WHERE checksum = pristine.checksum /*OR checksum = pristine.md5_checksum*/);
-
-PRAGMA user_version = 24;
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 25 introduces the NODES_CURRENT view. */
-
--- STMT_UPGRADE_TO_25
-DROP VIEW IF EXISTS NODES_CURRENT;
-CREATE VIEW NODES_CURRENT AS
- SELECT * FROM nodes
- JOIN (SELECT wc_id, local_relpath, MAX(op_depth) AS op_depth FROM nodes
- GROUP BY wc_id, local_relpath) AS filter
- ON nodes.wc_id = filter.wc_id
- AND nodes.local_relpath = filter.local_relpath
- AND nodes.op_depth = filter.op_depth;
-
-PRAGMA user_version = 25;
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 26 introduces the NODES_BASE view. */
-
--- STMT_UPGRADE_TO_26
-DROP VIEW IF EXISTS NODES_BASE;
-CREATE VIEW NODES_BASE AS
- SELECT * FROM nodes
- WHERE op_depth = 0;
-
-PRAGMA user_version = 26;
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 27 involves no schema changes, it introduces stores
- conflict files as relpaths rather than names in ACTUAL_NODE. */
-
--- STMT_UPGRADE_TO_27
-PRAGMA user_version = 27;
-
-/* For format 27 bump code */
--- STMT_UPGRADE_27_HAS_ACTUAL_NODES_CONFLICTS
-SELECT 1 FROM actual_node
-WHERE NOT ((prop_reject IS NULL) AND (conflict_old IS NULL)
- AND (conflict_new IS NULL) AND (conflict_working IS NULL)
- AND (tree_conflict_data IS NULL))
-LIMIT 1
-
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 28 involves no schema changes, it only converts MD5 pristine
- references to SHA1. */
-
--- STMT_UPGRADE_TO_28
-
-UPDATE NODES SET checksum = (SELECT checksum FROM pristine
- WHERE md5_checksum = nodes.checksum)
-WHERE EXISTS (SELECT 1 FROM pristine WHERE md5_checksum = nodes.checksum);
-
-PRAGMA user_version = 28;
-
-/* ------------------------------------------------------------------------- */
-
-/* Format 29 introduces the EXTERNALS table (See STMT_CREATE_TRIGGERS) and
- optimizes a few trigger definitions. ... */
-
--- STMT_UPGRADE_TO_29
-
-DROP TRIGGER IF EXISTS nodes_update_checksum_trigger;
-DROP TRIGGER IF EXISTS nodes_insert_trigger;
-DROP TRIGGER IF EXISTS nodes_delete_trigger;
-
-CREATE TRIGGER nodes_update_checksum_trigger
-AFTER UPDATE OF checksum ON nodes
-WHEN NEW.checksum IS NOT OLD.checksum
- /* AND (NEW.checksum IS NOT NULL OR OLD.checksum IS NOT NULL) */
-BEGIN
- UPDATE pristine SET refcount = refcount + 1
- WHERE checksum = NEW.checksum;
- UPDATE pristine SET refcount = refcount - 1
- WHERE checksum = OLD.checksum;
-END;
-
-CREATE TRIGGER nodes_insert_trigger
-AFTER INSERT ON nodes
-WHEN NEW.checksum IS NOT NULL
-BEGIN
- UPDATE pristine SET refcount = refcount + 1
- WHERE checksum = NEW.checksum;
-END;
-
-CREATE TRIGGER nodes_delete_trigger
-AFTER DELETE ON nodes
-WHEN OLD.checksum IS NOT NULL
-BEGIN
- UPDATE pristine SET refcount = refcount - 1
- WHERE checksum = OLD.checksum;
-END;
-
-PRAGMA user_version = 29;
-
-/* ------------------------------------------------------------------------- */
-
/* Format 30 creates a new NODES index for move information, and a new
PRISTINE index for the md5_checksum column. It also activates use of
skel-based conflict storage -- see notes/wc-ng/conflict-storage-2.0.
@@ -870,9 +664,9 @@ WHERE wc_id = ?1 and local_relpath = ?2
/* Format 31 adds the inherited_props column to the NODES table. C code then
initializes the update/switch roots to make sure future updates fetch the
inherited properties */
--- STMT_UPGRADE_TO_31_ALTER_TABLE
+-- STMT_UPGRADE_TO_31
ALTER TABLE NODES ADD COLUMN inherited_props BLOB;
--- STMT_UPGRADE_TO_31_FINALIZE
+
DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST;
DROP INDEX IF EXISTS I_EXTERNALS_PARENT;
@@ -906,25 +700,8 @@ WHERE l.op_depth = 0
/* ------------------------------------------------------------------------- */
/* Format 32 .... */
--- STMT_UPGRADE_TO_32
-
-/* Drop old index. ### Remove this part from the upgrade to 31 once bumped */
-DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST;
-DROP INDEX IF EXISTS I_EXTERNALS_PARENT;
-CREATE INDEX I_EXTERNALS_PARENT ON EXTERNALS (wc_id, parent_relpath);
-
-DROP INDEX I_NODES_PARENT;
-CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath,
- local_relpath, op_depth);
-
-DROP INDEX I_ACTUAL_PARENT;
-CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath,
- local_relpath);
-
-/* ------------------------------------------------------------------------- */
-
-/* Format YYY introduces new handling for conflict information. */
--- format: YYY
+/* -- STMT_UPGRADE_TO_32
+PRAGMA user_version = 32; */
/* ------------------------------------------------------------------------- */
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc-queries.sql Wed Nov 7 12:30:06 2018
@@ -117,6 +117,17 @@ WHERE wc_id = ?1 AND local_relpath = ?2
ORDER BY op_depth DESC
LIMIT 1
+-- STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND
+SELECT presence, local_relpath
+FROM nodes n
+WHERE wc_id = ?1 AND local_relpath = RELPATH_JOIN(parent_relpath, ?2)
+ AND kind = ?3
+ AND presence in (MAP_NORMAL, MAP_INCOMPLETE)
+ AND op_depth = (SELECT MAX(op_depth)
+ FROM NODES w
+ WHERE w.wc_id = ?1
+ AND w.local_relpath = n.local_relpath)
+
-- STMT_SELECT_ACTUAL_NODE
SELECT changelist, properties, conflict_data
FROM actual_node
@@ -1293,7 +1304,7 @@ PRAGMA journal_mode = DELETE
-- STMT_FIND_REPOS_PATH_IN_WC
SELECT local_relpath FROM nodes_current
- WHERE wc_id = ?1 AND repos_path = ?2 AND revision = ?3
+ WHERE wc_id = ?1 AND repos_path = ?2
/* ------------------------------------------------------------------------- */
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc.h?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc.h Wed Nov 7 12:30:06 2018
@@ -159,6 +159,7 @@ extern "C" {
*
* == 1.8.x shipped with format 31
* == 1.9.x shipped with format 31
+ * == 1.10.x shipped with format 31
*
* Please document any further format changes here.
*/
@@ -288,6 +289,7 @@ struct svn_wc_traversal_info_t
#define SVN_WC__ADM_TMP "tmp"
#define SVN_WC__ADM_PRISTINE "pristine"
#define SVN_WC__ADM_NONEXISTENT_PATH "nonexistent-path"
+#define SVN_WC__ADM_EXPERIMENTAL "experimental"
/* The basename of the ".prej" file, if a directory ever has property
conflicts. This .prej file will appear *within* the conflicted
@@ -480,7 +482,7 @@ svn_wc__conflicted_for_update_p(svn_bool
/* Internal version of svn_wc_transmit_text_deltas3(). */
svn_error_t *
-svn_wc__internal_transmit_text_deltas(const char **tempfile,
+svn_wc__internal_transmit_text_deltas(svn_stream_t *tempstream,
const svn_checksum_t **new_text_base_md5_checksum,
const svn_checksum_t **new_text_base_sha1_checksum,
svn_wc__db_t *db,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db.c Wed Nov 7 12:30:06 2018
@@ -1371,9 +1371,6 @@ init_db(/* output values */
/* Create the database's schema. */
SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_SCHEMA));
- SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES));
- SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES_TRIGGERS));
- SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS));
SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
@@ -6842,7 +6839,7 @@ revert_maybe_raise_moved_away(svn_wc__db
}
SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, &action,
- NULL,
+ NULL, NULL,
db, wcroot->abspath,
conflict,
scratch_pool,
@@ -16528,8 +16525,8 @@ db_process_commit_queue(svn_wc__db_t *db
iterpool),
iterpool, iterpool));
- lock_remove_txn(queue->wcroot, cqi->local_relpath, work_item,
- iterpool);
+ SVN_ERR(lock_remove_txn(queue->wcroot, cqi->local_relpath,
+ work_item, iterpool));
}
if (cqi->remove_changelist)
SVN_ERR(svn_wc__db_op_set_changelist(db,
@@ -16581,13 +16578,12 @@ svn_wc__db_process_commit_queue(svn_wc__
}
svn_error_t *
-svn_wc__find_repos_node_in_wc(apr_array_header_t **local_abspath_list,
- svn_wc__db_t *db,
- const char *wri_abspath,
- const char *repos_relpath,
- svn_revnum_t rev,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_wc__db_find_repos_node_in_wc(apr_array_header_t **local_abspath_list,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
+ const char *repos_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_wc__db_wcroot_t *wcroot;
const char *wri_relpath;
@@ -16603,7 +16599,7 @@ svn_wc__find_repos_node_in_wc(apr_array_
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_FIND_REPOS_PATH_IN_WC));
- SVN_ERR(svn_sqlite__bindf(stmt, "isr", wcroot->wc_id, repos_relpath, rev));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, repos_relpath));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
*local_abspath_list = apr_array_make(result_pool, have_row ? 1 : 0,
@@ -16624,3 +16620,46 @@ svn_wc__find_repos_node_in_wc(apr_array_
return svn_error_trace(svn_sqlite__reset(stmt));
}
+svn_error_t *
+svn_wc__db_find_working_nodes_with_basename(apr_array_header_t **local_abspaths,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
+ const char *basename,
+ svn_node_kind_t kind,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_wcroot_t *wcroot;
+ const char *wri_relpath;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &wri_relpath, db,
+ wri_abspath, scratch_pool,
+ scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_PRESENT_HIGHEST_WORKING_NODES_BY_BASENAME_AND_KIND));
+ SVN_ERR(svn_sqlite__bindf(stmt, "ist", wcroot->wc_id, basename,
+ kind_map, kind));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ *local_abspaths = apr_array_make(result_pool, 1, sizeof(const char *));
+
+ while (have_row)
+ {
+ const char *local_relpath;
+ const char *local_abspath;
+
+ local_relpath = svn_sqlite__column_text(stmt, 1, NULL);
+ local_abspath = svn_dirent_join(wcroot->abspath, local_relpath,
+ result_pool);
+ APR_ARRAY_PUSH(*local_abspaths, const char *) = local_abspath;
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+
+ return svn_error_trace(svn_sqlite__reset(stmt));
+}
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db.h Wed Nov 7 12:30:06 2018
@@ -3420,6 +3420,17 @@ svn_wc__db_update_incoming_move(svn_wc__
void *notify_baton,
apr_pool_t *scratch_pool);
+/* Merge locally added dir tree conflict victim at LOCAL_ABSPATH with the
+ * directory since added to the BASE layer by an update operation. */
+svn_error_t *
+svn_wc__db_update_local_add(svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool);
+
/* LOCAL_ABSPATH is moved to MOVE_DST_ABSPATH. MOVE_SRC_ROOT_ABSPATH
* is the root of the move to MOVE_DST_OP_ROOT_ABSPATH.
* DELETE_ABSPATH is the op-root of the move; it's the same
@@ -3478,21 +3489,37 @@ svn_wc__required_lock_for_resolve(const
/* Return an array of const char * elements, which represent local absolute
* paths for nodes, within the working copy indicated by WRI_ABSPATH, which
- * correspond to REPOS_RELPATH@REV.
- * If no such nodes exist, return an empty array.
+ * correspond to REPOS_RELPATH. If no such nodes exist, return an empty array.
*
* Note that this function returns each and every such node that is known
* in the WC, including, for example, nodes that were children of a directory
* which has been replaced.
*/
svn_error_t *
-svn_wc__find_repos_node_in_wc(apr_array_header_t **local_abspath_list,
- svn_wc__db_t *db,
- const char *wri_abspath,
- const char *repos_relpath,
- svn_revnum_t rev,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
+svn_wc__db_find_repos_node_in_wc(apr_array_header_t **local_abspath_list,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
+ const char *repos_relpath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Return an array of const char * elements, which represent local absolute
+ * paths for nodes, within the working copy indicated by WRI_ABSPATH, which
+ * have a basename matching BASENAME and have node kind KIND.
+ * If no such nodes exist, return an empty array.
+ *
+ * This function returns only paths to nodes which are present in the highest
+ * layer of the WC. In other words, paths to deleted and/or excluded nodes are
+ * never returned.
+ */
+svn_error_t *
+svn_wc__db_find_working_nodes_with_basename(apr_array_header_t **local_abspaths,
+ svn_wc__db_t *db,
+ const char *wri_abspath,
+ const char *basename,
+ svn_node_kind_t kind,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* @} */
typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton,
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_update_move.c Wed Nov 7 12:30:06 2018
@@ -21,13 +21,14 @@
* ====================================================================
*/
-/* This implements editors and an edit drivers which are used to resolve
- * "incoming edit, local move-away" and "incoming move, local edit" tree
- * conflict resulting from an update (or switch).
- *
- * Our goal is to be able to resolve this conflict such that the end
- * result is just the same as if the user had run the update *before*
- * the local (or incoming) move.
+/* This implements editors and edit drivers which are used to resolve
+ * "incoming edit, local move-away", "incoming move, local edit", and
+ * "incoming add, local add" tree conflicts resulting from an update
+ * (or switch).
+ *
+ * Our goal is to be able to resolve conflicts such that the end result
+ * is just the same as if the user had run the update *before* the local
+ * (or incoming) move or local add.
*
* -- Updating local moves --
*
@@ -102,6 +103,30 @@
* to working files/directories in the move destination, and there should be
* tree-conflicts in the move destination where it was not possible to
* update the working files/directories.
+ *
+ * -- Updating local adds --
+ *
+ * When an update (or switch) adds a directory tree it creates corresponding
+ * nodes in the BASE tree. Any existing locally added nodes are bumped to a
+ * higher layer with the top-most locally added directory as op-root.
+ * In-between, the update inserts a base-deleted layer, i.e. it schedules the
+ * directory in the BASE tree for removal upon the next commit, to be replaced
+ * by the locally added directory.
+ *
+ * The driver sees two NODES trees: The BASE layer, and the WORKING layer
+ * which represents the locally added tree.
+ * The driver will compare the two NODES trees and drive an editor to
+ * merge WORKING tree nodes with the nodes in the BASE tree.
+ *
+ * The whole drive occurs as one single wc.db transaction.
+ * Directories which exist in both trees become part of the BASE tree, with
+ * properties merged.
+ * Files which exist in both trees are merged (there is no common ancestor,
+ * so the common ancestor in this merge is the empty file).
+ * Files and directories which exist only in the WORKING layer become
+ * local-add op-roots of their own.
+ * Mismatching node kinds produce new 'incoming add vs local add upon update'
+ * tree conflicts which must be resolved individually later on.
*/
#define SVN_WC__I_AM_WC_DB
@@ -386,8 +411,13 @@ create_tree_conflict(svn_skel_t **confli
? svn_dirent_join(wcroot->abspath,
move_src_op_root_relpath, scratch_pool)
: NULL;
+ const char *move_dst_op_root_abspath
+ = dst_op_root_relpath
+ ? svn_dirent_join(wcroot->abspath,
+ dst_op_root_relpath, scratch_pool)
+ : NULL;
const char *old_repos_relpath_part
- = old_repos_relpath
+ = old_repos_relpath && old_version
? svn_relpath_skip_ancestor(old_version->path_in_repos,
old_repos_relpath)
: NULL;
@@ -443,7 +473,7 @@ create_tree_conflict(svn_skel_t **confli
SVN_ERR(svn_wc__conflict_read_tree_conflict(&existing_reason,
&existing_action,
- &existing_abspath,
+ &existing_abspath, NULL,
db, wcroot->abspath,
conflict,
scratch_pool,
@@ -475,13 +505,18 @@ create_tree_conflict(svn_skel_t **confli
reason,
action,
move_src_op_root_abspath,
+ move_dst_op_root_abspath,
result_pool,
scratch_pool));
- conflict_old_version = svn_wc_conflict_version_create2(
- old_version->repos_url, old_version->repos_uuid,
- old_repos_relpath, old_version->peg_rev,
- old_kind, scratch_pool);
+ if (old_version)
+ conflict_old_version = svn_wc_conflict_version_create2(
+ old_version->repos_url,
+ old_version->repos_uuid,
+ old_repos_relpath, old_version->peg_rev,
+ old_kind, scratch_pool);
+ else
+ conflict_old_version = NULL;
conflict_new_version = svn_wc_conflict_version_create2(
new_version->repos_url, new_version->repos_uuid,
@@ -2813,6 +2848,774 @@ svn_wc__db_update_incoming_move(svn_wc__
return SVN_NO_ERROR;
}
+typedef struct update_local_add_baton_t {
+ int add_op_depth;
+ svn_wc__db_t *db;
+ svn_wc__db_wcroot_t *wcroot;
+ svn_cancel_func_t cancel_func;
+ void *cancel_baton;
+
+ /* We refer to these if raising new tree conflicts. */
+ const svn_wc_conflict_version_t *new_version;
+} update_local_add_baton_t;
+
+typedef struct added_node_baton_t {
+ struct update_local_add_baton_t *b;
+ struct added_node_baton_t *pb;
+ const char *local_relpath;
+ svn_boolean_t skip;
+ svn_boolean_t edited;
+} added_node_baton_t;
+
+
+static svn_error_t *
+update_local_add_mark_node_edited(added_node_baton_t *nb,
+ apr_pool_t *scratch_pool)
+{
+ if (nb->edited)
+ return SVN_NO_ERROR;
+
+ if (nb->pb)
+ {
+ SVN_ERR(update_local_add_mark_node_edited(nb->pb, scratch_pool));
+
+ if (nb->pb->skip)
+ nb->skip = TRUE;
+ }
+
+ nb->edited = TRUE;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_local_add_mark_parent_edited(added_node_baton_t *nb,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR_ASSERT(nb && nb->pb);
+
+ SVN_ERR(update_local_add_mark_node_edited(nb->pb, scratch_pool));
+
+ if (nb->pb->skip)
+ nb->skip = TRUE;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+mark_update_add_add_tree_conflict(added_node_baton_t *nb,
+ svn_node_kind_t base_kind,
+ svn_node_kind_t working_kind,
+ svn_wc_conflict_reason_t local_change,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+
+{
+ svn_wc__db_t *db = nb->b->db;
+ svn_wc__db_wcroot_t *wcroot = nb->b->wcroot;
+ svn_wc_conflict_version_t *new_version;
+ svn_skel_t *conflict;
+
+ new_version = svn_wc_conflict_version_dup(nb->b->new_version, result_pool);
+
+ /* Fill in conflict info templates with info for this node. */
+ SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, &new_version->peg_rev,
+ &new_version->path_in_repos,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ wcroot, nb->local_relpath,
+ scratch_pool, scratch_pool));
+ new_version->node_kind = base_kind;
+
+ SVN_ERR(create_tree_conflict(&conflict, wcroot, nb->local_relpath,
+ nb->local_relpath, db, NULL, new_version,
+ svn_wc_operation_update,
+ svn_node_none, base_kind, NULL,
+ local_change, svn_wc_conflict_action_add,
+ NULL, scratch_pool, scratch_pool));
+
+ SVN_ERR(update_move_list_add(wcroot, nb->local_relpath, db,
+ svn_wc_notify_tree_conflict, working_kind,
+ svn_wc_notify_state_inapplicable,
+ svn_wc_notify_state_inapplicable,
+ conflict, NULL, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_local_add_notify_obstructed_or_missing(added_node_baton_t *nb,
+ svn_node_kind_t working_kind,
+ svn_node_kind_t kind_on_disk,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc_notify_state_t content_state;
+
+ if (kind_on_disk == svn_node_none)
+ content_state = svn_wc_notify_state_missing;
+ else
+ content_state = svn_wc_notify_state_obstructed;
+
+ SVN_ERR(update_move_list_add(nb->b->wcroot, nb->local_relpath, nb->b->db,
+ svn_wc_notify_skip, working_kind,
+ content_state, svn_wc_notify_state_inapplicable,
+ NULL, NULL, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+tc_editor_update_add_new_file(added_node_baton_t *nb,
+ svn_node_kind_t base_kind,
+ const svn_checksum_t *base_checksum,
+ apr_hash_t *base_props,
+ svn_node_kind_t working_kind,
+ const svn_checksum_t *working_checksum,
+ apr_hash_t *working_props,
+ apr_pool_t *scratch_pool)
+{
+ const char *local_abspath;
+ svn_node_kind_t kind_on_disk;
+
+ SVN_ERR(update_local_add_mark_parent_edited(nb, scratch_pool));
+ if (nb->skip)
+ return SVN_NO_ERROR;
+
+ if (base_kind != svn_node_none)
+ {
+ SVN_ERR(mark_update_add_add_tree_conflict(nb, base_kind, svn_node_file,
+ svn_wc_conflict_reason_added,
+ scratch_pool, scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ /* Check for obstructions. */
+ local_abspath = svn_dirent_join(nb->b->wcroot->abspath, nb->local_relpath,
+ scratch_pool);
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool));
+ if (kind_on_disk != svn_node_file)
+ {
+ SVN_ERR(update_local_add_notify_obstructed_or_missing(nb, working_kind,
+ kind_on_disk,
+ scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ /* Nothing else to do. Locally added files are an op-root in NODES. */
+
+ SVN_ERR(update_move_list_add(nb->b->wcroot, nb->local_relpath, nb->b->db,
+ svn_wc_notify_update_add, svn_node_file,
+ svn_wc_notify_state_inapplicable,
+ svn_wc_notify_state_inapplicable,
+ NULL, NULL, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+tc_editor_update_add_new_directory(added_node_baton_t *nb,
+ svn_node_kind_t base_kind,
+ apr_hash_t *base_props,
+ apr_hash_t *working_props,
+ apr_pool_t *scratch_pool)
+{
+ const char *local_abspath;
+ svn_node_kind_t kind_on_disk;
+
+ SVN_ERR(update_local_add_mark_parent_edited(nb, scratch_pool));
+ if (nb->skip)
+ return SVN_NO_ERROR;
+
+ if (base_kind != svn_node_none)
+ {
+ SVN_ERR(mark_update_add_add_tree_conflict(nb, base_kind, svn_node_dir,
+ svn_wc_conflict_reason_added,
+ scratch_pool, scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ /* Check for obstructions. */
+ local_abspath = svn_dirent_join(nb->b->wcroot->abspath, nb->local_relpath,
+ scratch_pool);
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool));
+ if (kind_on_disk != svn_node_dir)
+ {
+ SVN_ERR(update_local_add_notify_obstructed_or_missing(nb, svn_node_dir,
+ kind_on_disk,
+ scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ /* Nothing else to do. Locally added directories are an op-root in NODES. */
+
+ SVN_ERR(update_move_list_add(nb->b->wcroot, nb->local_relpath, nb->b->db,
+ svn_wc_notify_update_add, svn_node_dir,
+ svn_wc_notify_state_inapplicable,
+ svn_wc_notify_state_inapplicable,
+ NULL, NULL, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_incoming_add_merge_props(svn_wc_notify_state_t *prop_state,
+ svn_skel_t **conflict_skel,
+ const char *local_relpath,
+ apr_hash_t *base_props,
+ apr_hash_t *working_props,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *new_actual_props;
+ apr_array_header_t *propchanges;
+ const char *local_abspath = svn_dirent_join(wcroot->abspath,
+ local_relpath,
+ scratch_pool);
+
+ /*
+ * Run a 3-way prop merge to update the props, using the empty props
+ * as the merge base, the post-update props as the merge-left version, and
+ * the current props of the added working file as the merge-right version.
+ */
+ SVN_ERR(svn_prop_diffs(&propchanges, working_props,
+ apr_hash_make(scratch_pool), scratch_pool));
+ SVN_ERR(svn_wc__merge_props(conflict_skel, prop_state, &new_actual_props,
+ db, local_abspath,
+ apr_hash_make(scratch_pool),
+ base_props, working_props, propchanges,
+ result_pool, scratch_pool));
+
+ /* Install the new actual props. */
+ if (apr_hash_count(new_actual_props) > 0)
+ SVN_ERR(svn_wc__db_op_set_props_internal(wcroot, local_relpath,
+ new_actual_props,
+ svn_wc__has_magic_property(
+ propchanges),
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+tc_editor_update_add_merge_files(added_node_baton_t *nb,
+ const svn_checksum_t *working_checksum,
+ const svn_checksum_t *base_checksum,
+ apr_hash_t *working_props,
+ apr_hash_t *base_props,
+ apr_pool_t *scratch_pool)
+{
+ update_local_add_baton_t *b = nb->b;
+ apr_array_header_t *propchanges;
+ svn_boolean_t is_modified;
+ enum svn_wc_merge_outcome_t merge_outcome;
+ svn_skel_t *conflict_skel = NULL;
+ svn_wc_notify_state_t prop_state, content_state;
+ svn_skel_t *work_items = NULL;
+ svn_node_kind_t kind_on_disk;
+ const char *local_abspath = svn_dirent_join(b->wcroot->abspath,
+ nb->local_relpath,
+ scratch_pool);
+
+ SVN_ERR(update_local_add_mark_node_edited(nb, scratch_pool));
+ if (nb->skip)
+ return SVN_NO_ERROR;
+
+ /* Check for on-disk obstructions or missing files. */
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool));
+ if (kind_on_disk != svn_node_file)
+ {
+ SVN_ERR(update_local_add_notify_obstructed_or_missing(nb, svn_node_file,
+ kind_on_disk,
+ scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(update_incoming_add_merge_props(&prop_state, &conflict_skel,
+ nb->local_relpath,
+ base_props, working_props,
+ b->db, b->wcroot,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_wc__internal_file_modified_p(&is_modified,
+ b->db, local_abspath,
+ FALSE /* exact_comparison */,
+ scratch_pool));
+ if (!is_modified)
+ {
+ svn_skel_t *work_item = NULL;
+
+ SVN_ERR(svn_wc__wq_build_file_install(&work_item, b->db,
+ local_abspath, NULL,
+ /* FIXME: use_commit_times? */
+ FALSE,
+ TRUE, /* record_file_info */
+ scratch_pool, scratch_pool));
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+ content_state = svn_wc_notify_state_changed;
+ }
+ else
+ {
+ const char *empty_file_abspath;
+ const char *pristine_abspath;
+ svn_skel_t *work_item = NULL;
+
+ /*
+ * Run a 3-way merge to update the file, using the empty file
+ * merge base, the post-update pristine text as the merge-left version,
+ * and the locally added content of the working file as the merge-right
+ * version.
+ */
+ SVN_ERR(svn_io_open_unique_file3(NULL, &empty_file_abspath, NULL,
+ svn_io_file_del_on_pool_cleanup,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_pristine_get_path(&pristine_abspath, b->db,
+ b->wcroot->abspath, base_checksum,
+ scratch_pool, scratch_pool));
+
+ /* Create a property diff which shows all props as added. */
+ SVN_ERR(svn_prop_diffs(&propchanges, working_props,
+ apr_hash_make(scratch_pool), scratch_pool));
+
+ SVN_ERR(svn_wc__internal_merge(&work_item, &conflict_skel,
+ &merge_outcome, b->db,
+ empty_file_abspath,
+ pristine_abspath,
+ local_abspath,
+ local_abspath,
+ NULL, NULL, NULL, /* diff labels */
+ apr_hash_make(scratch_pool),
+ FALSE, /* dry-run */
+ NULL, /* diff3-cmd */
+ NULL, /* merge options */
+ propchanges,
+ b->cancel_func, b->cancel_baton,
+ scratch_pool, scratch_pool));
+
+ work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+ if (merge_outcome == svn_wc_merge_conflict)
+ content_state = svn_wc_notify_state_conflicted;
+ else
+ content_state = svn_wc_notify_state_merged;
+ }
+
+ /* If there are any conflicts to be stored, convert them into work items
+ * too. */
+ if (conflict_skel)
+ {
+ svn_wc_conflict_version_t *new_version;
+ svn_node_kind_t new_kind;
+ svn_revnum_t new_rev;
+ const char *repos_relpath;
+
+ new_version = svn_wc_conflict_version_dup(nb->b->new_version,
+ scratch_pool);
+ SVN_ERR(svn_wc__db_base_get_info_internal(NULL, &new_kind, &new_rev,
+ &repos_relpath, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ b->wcroot, nb->local_relpath,
+ scratch_pool, scratch_pool));
+ /* Fill in conflict info templates with info for this node. */
+ new_version->path_in_repos = repos_relpath;
+ new_version->node_kind = new_kind;
+ new_version->peg_rev = new_rev;
+
+ /* Create conflict markers. */
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel, NULL,
+ new_version, scratch_pool,
+ scratch_pool));
+ if (prop_state == svn_wc_notify_state_conflicted)
+ SVN_ERR(svn_wc__conflict_create_markers(&work_items, b->db,
+ local_abspath,
+ conflict_skel,
+ scratch_pool,
+ scratch_pool));
+ }
+
+ SVN_ERR(update_move_list_add(b->wcroot, nb->local_relpath, b->db,
+ svn_wc_notify_update_update,
+ svn_node_file, content_state, prop_state,
+ conflict_skel, work_items, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+tc_editor_update_add_merge_dirprops(added_node_baton_t *nb,
+ apr_hash_t *working_props,
+ apr_hash_t *base_props,
+ apr_pool_t *scratch_pool)
+{
+ update_local_add_baton_t *b = nb->b;
+ svn_skel_t *conflict_skel = NULL;
+ svn_wc_notify_state_t prop_state;
+ svn_skel_t *work_items = NULL;
+ svn_node_kind_t kind_on_disk;
+ const char *local_abspath = svn_dirent_join(b->wcroot->abspath,
+ nb->local_relpath,
+ scratch_pool);
+
+ SVN_ERR(update_local_add_mark_node_edited(nb, scratch_pool));
+ if (nb->skip)
+ return SVN_NO_ERROR;
+
+ /* Check for on-disk obstructions or missing files. */
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk, scratch_pool));
+ if (kind_on_disk != svn_node_dir)
+ {
+ SVN_ERR(update_local_add_notify_obstructed_or_missing(nb, svn_node_dir,
+ kind_on_disk,
+ scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ SVN_ERR(update_incoming_add_merge_props(&prop_state, &conflict_skel,
+ nb->local_relpath,
+ base_props, working_props,
+ b->db, b->wcroot,
+ scratch_pool, scratch_pool));
+
+ /* If there are any conflicts to be stored, convert them into work items. */
+ if (conflict_skel && prop_state == svn_wc_notify_state_conflicted)
+ {
+ svn_wc_conflict_version_t *new_version;
+ svn_node_kind_t new_kind;
+ svn_revnum_t new_rev;
+ const char *repos_relpath;
+
+ new_version = svn_wc_conflict_version_dup(nb->b->new_version,
+ scratch_pool);
+ SVN_ERR(svn_wc__db_base_get_info_internal(NULL, &new_kind, &new_rev,
+ &repos_relpath, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ b->wcroot, nb->local_relpath,
+ scratch_pool, scratch_pool));
+ /* Fill in conflict info templates with info for this node. */
+ new_version->path_in_repos = repos_relpath;
+ new_version->node_kind = new_kind;
+ new_version->peg_rev = new_rev;
+
+ /* Create conflict markers. */
+ SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict_skel, NULL,
+ new_version, scratch_pool,
+ scratch_pool));
+ SVN_ERR(svn_wc__conflict_create_markers(&work_items, b->db,
+ local_abspath,
+ conflict_skel,
+ scratch_pool,
+ scratch_pool));
+ }
+
+ SVN_ERR(update_move_list_add(b->wcroot, nb->local_relpath, b->db,
+ svn_wc_notify_update_update, svn_node_dir,
+ svn_wc_notify_state_inapplicable, prop_state,
+ conflict_skel, work_items, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+update_locally_added_node(added_node_baton_t *nb,
+ apr_pool_t *scratch_pool)
+{
+ update_local_add_baton_t *b = nb->b;
+ svn_wc__db_wcroot_t *wcroot = b->wcroot;
+ svn_wc__db_t *db = b->db;
+ svn_node_kind_t base_kind, working_kind;
+ const svn_checksum_t *base_checksum;
+ apr_hash_t *base_props, *working_props;
+ apr_array_header_t *base_children, *working_children;
+ const char *local_abspath = svn_dirent_join(wcroot->abspath,
+ nb->local_relpath,
+ scratch_pool);
+
+ if (b->cancel_func)
+ SVN_ERR(b->cancel_func(b->cancel_baton));
+
+ if (nb->skip)
+ return SVN_NO_ERROR;
+
+ /* Compare the tree conflict victim's BASE layer to the working layer. */
+ SVN_ERR(get_info(&base_props, &base_checksum, &base_children, &base_kind,
+ nb->local_relpath, 0, wcroot, scratch_pool, scratch_pool));
+ SVN_ERR(get_working_info(&working_props, NULL, &working_children,
+ &working_kind, nb->local_relpath, wcroot,
+ scratch_pool, scratch_pool));
+ if (working_kind == svn_node_none)
+ {
+ svn_node_kind_t kind_on_disk;
+ svn_skel_t *work_item = NULL;
+
+ /* Skip obstructed nodes. */
+ SVN_ERR(svn_io_check_path(local_abspath, &kind_on_disk,
+ scratch_pool));
+ if (kind_on_disk != base_kind && kind_on_disk != svn_node_none)
+ {
+ SVN_ERR(update_move_list_add(nb->b->wcroot, nb->local_relpath,
+ nb->b->db,
+ svn_wc_notify_skip,
+ base_kind,
+ svn_wc_notify_state_obstructed,
+ svn_wc_notify_state_inapplicable,
+ NULL, NULL, scratch_pool));
+ nb->skip = TRUE;
+ return SVN_NO_ERROR;
+ }
+
+ /* The working tree has no node here. The working copy of this node
+ * is currently not installed because the base tree is shadowed.
+ * Queue an installation of this node into the working copy. */
+ if (base_kind == svn_node_file || base_kind == svn_node_symlink)
+ SVN_ERR(svn_wc__wq_build_file_install(&work_item, db, local_abspath,
+ NULL,
+ /* FIXME: use_commit_times? */
+ FALSE,
+ TRUE, /* record_file_info */
+ scratch_pool, scratch_pool));
+ else if (base_kind == svn_node_dir)
+ SVN_ERR(svn_wc__wq_build_dir_install(&work_item, db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (work_item)
+ SVN_ERR(update_move_list_add(wcroot, nb->local_relpath, db,
+ svn_wc_notify_update_add,
+ base_kind,
+ svn_wc_notify_state_inapplicable,
+ svn_wc_notify_state_inapplicable,
+ NULL, work_item, scratch_pool));
+ return SVN_NO_ERROR;
+ }
+
+ if (base_kind != working_kind)
+ {
+ if (working_kind == svn_node_file || working_kind == svn_node_symlink)
+ {
+ svn_checksum_t *working_checksum = NULL;
+
+ if (base_checksum)
+ SVN_ERR(svn_io_file_checksum2(&working_checksum, local_abspath,
+ base_checksum->kind, scratch_pool));
+ SVN_ERR(tc_editor_update_add_new_file(nb, base_kind, base_checksum,
+ base_props, working_kind,
+ working_checksum, working_props,
+ scratch_pool));
+ }
+ else if (working_kind == svn_node_dir)
+ SVN_ERR(tc_editor_update_add_new_directory(nb, base_kind, base_props,
+ working_props,
+ scratch_pool));
+ }
+ else
+ {
+ svn_boolean_t props_equal;
+
+ SVN_ERR(props_match(&props_equal, base_props, working_props,
+ scratch_pool));
+
+ if (working_kind == svn_node_file || working_kind == svn_node_symlink)
+ {
+ svn_checksum_t *working_checksum;
+
+ SVN_ERR_ASSERT(base_checksum);
+ SVN_ERR(svn_io_file_checksum2(&working_checksum, local_abspath,
+ base_checksum->kind, scratch_pool));
+ if (!props_equal || !svn_checksum_match(base_checksum,
+ working_checksum))
+ SVN_ERR(tc_editor_update_add_merge_files(nb, working_checksum,
+ base_checksum,
+ working_props, base_props,
+ scratch_pool));
+ }
+ else if (working_kind == svn_node_dir && !props_equal)
+ SVN_ERR(tc_editor_update_add_merge_dirprops(nb, working_props,
+ base_props,
+ scratch_pool));
+ }
+
+ if (nb->skip)
+ return SVN_NO_ERROR;
+
+ if (working_kind == svn_node_dir)
+ {
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int i = 0, j = 0;
+
+ while (i < base_children->nelts || j < working_children->nelts)
+ {
+ const char *child_name;
+ svn_boolean_t base_only = FALSE, working_only = FALSE;
+ added_node_baton_t cnb = { 0 };
+
+ cnb.pb = nb;
+ cnb.b = nb->b;
+ cnb.skip = FALSE;
+
+ svn_pool_clear(iterpool);
+ if (i >= base_children->nelts)
+ {
+ working_only = TRUE;
+ child_name = APR_ARRAY_IDX(working_children, j, const char *);
+ }
+ else if (j >= working_children->nelts)
+ {
+ base_only = TRUE;
+ child_name = APR_ARRAY_IDX(base_children, i, const char *);
+ }
+ else
+ {
+ const char *base_name = APR_ARRAY_IDX(base_children, i,
+ const char *);
+ const char *working_name = APR_ARRAY_IDX(working_children, j,
+ const char *);
+ int cmp = strcmp(base_name, working_name);
+
+ if (cmp > 0)
+ working_only = TRUE;
+ else if (cmp < 0)
+ base_only = TRUE;
+
+ child_name = working_only ? working_name : base_name;
+ }
+
+ cnb.local_relpath = svn_relpath_join(nb->local_relpath, child_name,
+ iterpool);
+
+ SVN_ERR(update_locally_added_node(&cnb, iterpool));
+
+ if (!working_only)
+ ++i;
+ if (!base_only)
+ ++j;
+
+ if (nb->skip) /* Does parent now want a skip? */
+ break;
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* The body of svn_wc__db_update_local_add(). */
+static svn_error_t *
+update_local_add(svn_revnum_t *new_rev,
+ svn_wc__db_t *db,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ update_local_add_baton_t b = { 0 };
+ added_node_baton_t nb = { 0 };
+ const char *repos_root_url;
+ const char *repos_uuid;
+ const char *repos_relpath;
+ apr_int64_t repos_id;
+ svn_node_kind_t new_kind;
+ svn_sqlite__stmt_t *stmt;
+
+ b.add_op_depth = relpath_depth(local_relpath); /* DST op-root */
+
+ SVN_ERR(verify_write_lock(wcroot, local_relpath, scratch_pool));
+
+ b.db = db;
+ b.wcroot = wcroot;
+ b.cancel_func = cancel_func;
+ b.cancel_baton = cancel_baton;
+
+ /* Read new version info from the updated BASE node. */
+ SVN_ERR(svn_wc__db_base_get_info_internal(NULL, &new_kind, new_rev,
+ &repos_relpath, &repos_id,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ wcroot, local_relpath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid, wcroot,
+ repos_id, scratch_pool));
+ b.new_version = svn_wc_conflict_version_create2(repos_root_url, repos_uuid,
+ repos_relpath, *new_rev,
+ new_kind, scratch_pool);
+
+ /* Create a new, and empty, list for notification information. */
+ SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
+ STMT_CREATE_UPDATE_MOVE_LIST));
+
+ /* Drive the editor... */
+ nb.b = &b;
+ nb.local_relpath = local_relpath;
+ nb.skip = FALSE;
+ SVN_ERR(update_locally_added_node(&nb, scratch_pool));
+
+ /* The conflict victim is now part of the base tree.
+ * Remove the locally added version of the conflict victim and its children.
+ * Any children we want to retain are at a higher op-depth so they won't
+ * be deleted by this statement. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_DELETE_WORKING_OP_DEPTH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+ relpath_depth(local_relpath)));
+ SVN_ERR(svn_sqlite__update(NULL, stmt));
+
+ /* Remove the tree conflict marker. */
+ SVN_ERR(svn_wc__db_op_mark_resolved_internal(wcroot, local_relpath, db,
+ FALSE, FALSE, TRUE,
+ NULL, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_update_local_add(svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_wcroot_t *wcroot;
+ svn_revnum_t new_rev;
+ const char *local_relpath;
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ SVN_WC__DB_WITH_TXN(update_local_add(&new_rev, db, wcroot,
+ local_relpath,
+ cancel_func, cancel_baton,
+ scratch_pool),
+ wcroot);
+
+ /* Send all queued up notifications. */
+ SVN_ERR(svn_wc__db_update_move_list_notify(wcroot, new_rev, new_rev,
+ notify_func, notify_baton,
+ scratch_pool));
+ if (notify_func)
+ {
+ svn_wc_notify_t *notify;
+
+ notify = svn_wc_create_notify(svn_dirent_join(wcroot->abspath,
+ local_relpath,
+ scratch_pool),
+ svn_wc_notify_update_completed,
+ scratch_pool);
+ notify->kind = svn_node_none;
+ notify->content_state = svn_wc_notify_state_inapplicable;
+ notify->prop_state = svn_wc_notify_state_inapplicable;
+ notify->revision = new_rev;
+ notify_func(notify_baton, notify, scratch_pool);
+ }
+
+
+ return SVN_NO_ERROR;
+}
/* Set *CAN_BUMP to TRUE if DEPTH is sufficient to cover the entire
tree LOCAL_RELPATH at OP_DEPTH, to FALSE otherwise. */
static svn_error_t *
@@ -3302,7 +4105,7 @@ fetch_conflict_details(int *src_op_depth
SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason,
action,
- &move_src_op_root_abspath,
+ &move_src_op_root_abspath, NULL,
db, local_abspath,
conflict_skel, result_pool,
scratch_pool));
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wc_db_wcroot.c Wed Nov 7 12:30:06 2018
@@ -528,6 +528,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
const char *adm_relpath;
/* Non-NULL if WCROOT is found through a symlink: */
const char *symlink_wcroot_abspath = NULL;
+ apr_pool_t *iterpool;
/* ### we need more logic for finding the database (if it is located
### outside of the wcroot) and then managing all of that within DB.
@@ -613,16 +614,20 @@ svn_wc__db_wcroot_parse_local_abspath(sv
database in the right place. If we find it... great! If not, then
peel off some components, and try again. */
+ iterpool = svn_pool_create(scratch_pool);
adm_relpath = svn_wc_get_adm_dir(scratch_pool);
while (TRUE)
{
svn_error_t *err;
svn_node_kind_t adm_subdir_kind;
- const char *adm_subdir = svn_dirent_join(local_abspath, adm_relpath,
- scratch_pool);
+ const char *adm_subdir;
- SVN_ERR(svn_io_check_path(adm_subdir, &adm_subdir_kind, scratch_pool));
+ svn_pool_clear(iterpool);
+
+ adm_subdir = svn_dirent_join(local_abspath, adm_relpath, iterpool);
+
+ SVN_ERR(svn_io_check_path(adm_subdir, &adm_subdir_kind, iterpool));
if (adm_subdir_kind == svn_node_dir)
{
@@ -673,7 +678,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
if (!moved_upwards || always_check)
{
SVN_ERR(get_old_version(&wc_format, local_abspath,
- scratch_pool));
+ iterpool));
if (wc_format != 0)
break;
}
@@ -697,7 +702,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
SVN_ERR(svn_io_check_resolved_path(local_abspath,
&resolved_kind,
- scratch_pool));
+ iterpool));
if (resolved_kind == svn_node_dir)
{
/* Is this directory recorded in our hash? */
@@ -973,6 +978,7 @@ try_symlink_as_dir:
}
while (strcmp(scan_abspath, local_abspath) != 0);
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
Modified: subversion/branches/ra-git/subversion/libsvn_wc/wcroot_anchor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_wc/wcroot_anchor.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_wc/wcroot_anchor.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_wc/wcroot_anchor.c Wed Nov 7 12:30:06 2018
@@ -183,6 +183,29 @@ svn_wc__get_wcroot(const char **wcroot_a
svn_error_t *
+svn_wc__get_shelves_dir(char **dir,
+ svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *wcroot_abspath;
+
+ SVN_ERR(svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ *dir = svn_dirent_join(wcroot_abspath,
+ SVN_WC_ADM_DIR_NAME "/" SVN_WC__ADM_EXPERIMENTAL "/"
+ "shelves/v2",
+ result_pool);
+
+ /* Ensure the directory exists. (Other versions of svn don't create it.) */
+ SVN_ERR(svn_io_make_dir_recursively(*dir, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
svn_wc_get_actual_target2(const char **anchor,
const char **target,
svn_wc_context_t *wc_ctx,
Modified: subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c?rev=1846002&r1=1846001&r2=1846002&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/ra-git/subversion/mod_authz_svn/mod_authz_svn.c Wed Nov 7 12:30:06 2018
@@ -154,7 +154,7 @@ canonicalize_access_file(const char *acc
}
/* We don't canonicalize repos relative urls since they get
- * canonicalized before calling svn_repos_authz_read2() when they
+ * canonicalized before calling svn_repos_authz_read3() when they
* are resolved. */
return access_file;
@@ -472,10 +472,10 @@ get_access_conf(request_rec *r, authz_sv
access_conf = user_data;
if (access_conf == NULL)
{
-
- svn_err = svn_repos_authz_read2(&access_conf, access_file,
- groups_file, TRUE,
- r->connection->pool);
+ svn_err = svn_repos_authz_read3(&access_conf, access_file,
+ groups_file, TRUE, NULL,
+ r->connection->pool,
+ scratch_pool);
if (svn_err)
{
@@ -912,7 +912,7 @@ access_checker(request_rec *r)
{
/* Set the note to force authn regardless of what access_checker_ex
hook requires */
- apr_table_setn(r->notes, FORCE_AUTHN_NOTE, (const char*)1);
+ apr_table_setn(r->notes, FORCE_AUTHN_NOTE, "1");
/* provide the proper return so the access_checker hook doesn't
* prevent the code from continuing on to the other auth hooks */
@@ -978,7 +978,7 @@ access_checker(request_rec *r)
* ap_some_authn_rquired() without triggering an infinite
* loop since the call will trigger this function to be
* called again. */
- apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, (const char*)1);
+ apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, "1");
authn_required = ap_some_authn_required(r);
apr_table_unset(r->notes, IN_SOME_AUTHN_NOTE);
if (authn_required)
@@ -1021,7 +1021,7 @@ check_user_id(request_rec *r)
status = req_check_access(r, conf, &repos_path, &dest_repos_path);
if (status == OK)
{
- apr_table_setn(r->notes, "authz_svn-anon-ok", (const char*)1);
+ apr_table_setn(r->notes, "authz_svn-anon-ok", "1");
log_access_verdict(APLOG_MARK, r, 1, FALSE, repos_path, dest_repos_path);
return OK;
}