Modified: subversion/branches/fsx-1.10/subversion/libsvn_wc/entries.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_wc/entries.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/libsvn_wc/entries.c (original) +++ subversion/branches/fsx-1.10/subversion/libsvn_wc/entries.c Sun Jun 14 20:58:10 2015 @@ -45,9 +45,14 @@ #include "wc_db.h" #include "wc-queries.h" /* for STMT_* */ +#define SVN_WC__I_AM_WC_DB + #include "svn_private_config.h" #include "private/svn_wc_private.h" #include "private/svn_sqlite.h" +#include "token-map.h" + +#include "wc_db_private.h" #define MAYBE_ALLOC(x,p) ((x) ? (x) : apr_pcalloc((p), sizeof(*(x)))) @@ -213,6 +218,8 @@ get_info_for_deleted(svn_wc_entry_t *ent svn_wc__db_lock_t **lock, svn_wc__db_t *db, const char *entry_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *entry_relpath, const svn_wc_entry_t *parent_entry, svn_boolean_t have_base, svn_boolean_t have_more_work, @@ -221,12 +228,13 @@ get_info_for_deleted(svn_wc_entry_t *ent { if (have_base && !have_more_work) { + apr_int64_t repos_id; /* This is the delete of a BASE node */ - SVN_ERR(svn_wc__db_base_get_info(NULL, kind, + SVN_ERR(svn_wc__db_base_get_info_internal( + NULL, kind, &entry->revision, repos_relpath, - &entry->repos, - &entry->uuid, + &repos_id, &entry->cmt_rev, &entry->cmt_date, &entry->cmt_author, @@ -236,16 +244,18 @@ get_info_for_deleted(svn_wc_entry_t *ent lock, &entry->has_props, NULL, NULL, - db, - entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); } else { - const char *work_del_abspath; + const char *work_del_relpath; const char *parent_repos_relpath; - const char *parent_abspath; + const char *parent_relpath; + apr_int64_t repos_id; /* This is a deleted child of a copy/move-here, so we need to scan up the WORKING tree to find the root of @@ -265,30 +275,33 @@ get_info_for_deleted(svn_wc_entry_t *ent scratch_pool)); /* working_size and text_time unavailable */ - SVN_ERR(svn_wc__db_scan_deletion(NULL, + SVN_ERR(svn_wc__db_scan_deletion_internal( NULL, - &work_del_abspath, NULL, - db, entry_abspath, + NULL, + &work_del_relpath, NULL, + wcroot, entry_relpath, scratch_pool, scratch_pool)); - SVN_ERR_ASSERT(work_del_abspath != NULL); - parent_abspath = svn_dirent_dirname(work_del_abspath, scratch_pool); + SVN_ERR_ASSERT(work_del_relpath != NULL); + parent_relpath = svn_relpath_dirname(work_del_relpath, scratch_pool); /* The parent directory of the delete root must be added, so we can find the required information there */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, + SVN_ERR(svn_wc__db_scan_addition_internal( + NULL, NULL, &parent_repos_relpath, - &entry->repos, - &entry->uuid, - NULL, NULL, NULL, NULL, - db, parent_abspath, + &repos_id, + NULL, NULL, NULL, + wcroot, parent_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); /* Now glue it all together */ *repos_relpath = svn_relpath_join(parent_repos_relpath, - svn_dirent_is_child(parent_abspath, - entry_abspath, - NULL), + svn_relpath_skip_ancestor( + parent_relpath, + entry_relpath), result_pool); @@ -297,11 +310,12 @@ get_info_for_deleted(svn_wc_entry_t *ent if (have_base) { svn_wc__db_status_t status; - SVN_ERR(svn_wc__db_base_get_info(&status, NULL, &entry->revision, + SVN_ERR(svn_wc__db_base_get_info_internal( + &status, NULL, &entry->revision, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, lock, NULL, NULL, + NULL, NULL, lock, NULL, NULL, NULL, - db, entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); if (status == svn_wc__db_status_not_present) @@ -369,12 +383,17 @@ write_tree_conflicts(const char **confli If this node is "this dir", then PARENT_ENTRY should be NULL. Otherwise, it should refer to the entry for the child's parent directory. + ### All database read operations should really use wcroot, dir_relpath, + as that restores obstruction compatibility with <= 1.6.0 + but that has been the case since the introduction of WC-NG in 1.7.0 + Temporary allocations are made in SCRATCH_POOL. */ static svn_error_t * read_one_entry(const svn_wc_entry_t **new_entry, svn_wc__db_t *db, - apr_int64_t wc_id, const char *dir_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *dir_relpath, const char *name, const svn_wc_entry_t *parent_entry, apr_pool_t *result_pool, @@ -387,24 +406,28 @@ read_one_entry(const svn_wc_entry_t **ne const svn_checksum_t *checksum; svn_filesize_t translated_size; svn_wc_entry_t *entry = alloc_entry(result_pool); + const char *entry_relpath; const char *entry_abspath; + apr_int64_t repos_id; + apr_int64_t original_repos_id; const char *original_repos_relpath; const char *original_root_url; svn_boolean_t conflicted; svn_boolean_t have_base; svn_boolean_t have_more_work; + svn_boolean_t op_root; - entry->name = name; + entry->name = apr_pstrdup(result_pool, name); + entry_relpath = svn_relpath_join(dir_relpath, entry->name, scratch_pool); entry_abspath = svn_dirent_join(dir_abspath, entry->name, scratch_pool); - SVN_ERR(svn_wc__db_read_info( + SVN_ERR(svn_wc__db_read_info_internal( &status, &kind, &entry->revision, &repos_relpath, - &entry->repos, - &entry->uuid, + &repos_id, &entry->cmt_rev, &entry->cmt_date, &entry->cmt_author, @@ -412,24 +435,27 @@ read_one_entry(const svn_wc_entry_t **ne &checksum, NULL, &original_repos_relpath, - &original_root_url, - NULL, + &original_repos_id, &entry->copyfrom_rev, &lock, &translated_size, &entry->text_time, &entry->changelist, &conflicted, - NULL /* op_root */, + &op_root, &entry->has_props /* have_props */, &entry->has_prop_mods /* props_mod */, &have_base, &have_more_work, NULL /* have_work */, - db, - entry_abspath, - result_pool, - scratch_pool)); + wcroot, entry_relpath, + result_pool, scratch_pool)); + + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&original_root_url, NULL, + wcroot, original_repos_id, + result_pool)); if (entry->has_prop_mods) entry->has_props = TRUE; @@ -457,9 +483,10 @@ read_one_entry(const svn_wc_entry_t **ne child_abspath = svn_dirent_join(dir_abspath, child_name, scratch_pool); - SVN_ERR(svn_wc__read_conflicts(&child_conflicts, + SVN_ERR(svn_wc__read_conflicts(&child_conflicts, NULL, db, child_abspath, FALSE /* create tempfiles */, + TRUE /* tree_conflicts_only */, scratch_pool, scratch_pool)); for (j = 0; j < child_conflicts->nelts; j++) @@ -493,13 +520,15 @@ read_one_entry(const svn_wc_entry_t **ne /* Grab inherited repository information, if necessary. */ if (repos_relpath == NULL) { - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, &repos_relpath, - &entry->repos, - &entry->uuid, NULL, NULL, NULL, + SVN_ERR(svn_wc__db_base_get_info_internal( + NULL, NULL, NULL, &repos_relpath, + &repos_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - db, entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); } entry->incomplete = (status == svn_wc__db_status_incomplete); @@ -519,13 +548,14 @@ read_one_entry(const svn_wc_entry_t **ne entry->copied = FALSE; else { - const char *work_del_abspath; - SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, - &work_del_abspath, NULL, - db, entry_abspath, + const char *work_del_relpath; + SVN_ERR(svn_wc__db_scan_deletion_internal( + NULL, NULL, + &work_del_relpath, NULL, + wcroot, entry_relpath, scratch_pool, scratch_pool)); - if (work_del_abspath) + if (work_del_relpath) entry->copied = TRUE; } @@ -563,13 +593,14 @@ read_one_entry(const svn_wc_entry_t **ne /* ENTRY->REVISION is overloaded. When a node is schedule-add or -replace, then REVISION refers to the BASE node's revision that is being overwritten. We need to fetch it now. */ - SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, + SVN_ERR(svn_wc__db_base_get_info_internal( + &base_status, NULL, &entry->revision, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - db, entry_abspath, + NULL, NULL, NULL, + wcroot, entry_relpath, scratch_pool, scratch_pool)); @@ -603,18 +634,27 @@ read_one_entry(const svn_wc_entry_t **ne have important data. Set up stuff to kill that idea off, and finish up this entry. */ { - SVN_ERR(svn_wc__db_scan_addition(&work_status, - &op_root_abspath, + const char *op_root_relpath; + SVN_ERR(svn_wc__db_scan_addition_internal( + &work_status, + &op_root_relpath, &repos_relpath, - &entry->repos, - &entry->uuid, + &repos_id, &scanned_original_relpath, - NULL, NULL, /* original_root|uuid */ + NULL /* original_repos_id */, &original_revision, - db, - entry_abspath, + wcroot, entry_relpath, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_fetch_repos_info(&entry->repos, &entry->uuid, + wcroot, repos_id, result_pool)); + + if (!op_root_relpath) + op_root_abspath = NULL; + else + op_root_abspath = svn_dirent_join(wcroot->abspath, op_root_relpath, + scratch_pool); + /* In wc.db we want to keep the valid revision of the not-present BASE_REV, but when we used entries we set the revision to 0 when adding a new node over a not present base node. */ @@ -675,10 +715,12 @@ read_one_entry(const svn_wc_entry_t **ne mixed-revision situation. */ if (!is_copied_child) { - const char *parent_abspath; + const char *parent_relpath; svn_error_t *err; const char *parent_repos_relpath; const char *parent_root_url; + apr_int64_t parent_repos_id; + const char *op_root_relpath; /* When we insert entries into the database, we will construct additional copyfrom records for mixed-revision @@ -705,15 +747,16 @@ read_one_entry(const svn_wc_entry_t **ne Note that the parent could be added/copied/moved-here. There is no way for it to be deleted/moved-away and have *this* node appear as copied. */ - parent_abspath = svn_dirent_dirname(entry_abspath, - scratch_pool); - err = svn_wc__db_scan_addition(NULL, - &op_root_abspath, - NULL, NULL, NULL, - &parent_repos_relpath, - &parent_root_url, + parent_relpath = svn_relpath_dirname(entry_relpath, + scratch_pool); + err = svn_wc__db_scan_addition_internal( + NULL, + &op_root_relpath, NULL, NULL, - db, parent_abspath, + &parent_repos_relpath, + &parent_repos_id, + NULL, + wcroot, parent_relpath, scratch_pool, scratch_pool); if (err) @@ -721,10 +764,24 @@ read_one_entry(const svn_wc_entry_t **ne if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND) return svn_error_trace(err); svn_error_clear(err); + op_root_abspath = NULL; + parent_repos_relpath = NULL; + parent_root_url = NULL; } - else if (parent_root_url != NULL + else + { + SVN_ERR(svn_wc__db_fetch_repos_info(&parent_root_url, NULL, + wcroot, parent_repos_id, + scratch_pool)); + op_root_abspath = svn_dirent_join(wcroot->abspath, + op_root_relpath, + scratch_pool); + } + + if (parent_root_url != NULL && strcmp(original_root_url, parent_root_url) == 0) { + const char *relpath_to_entry = svn_dirent_is_child( op_root_abspath, entry_abspath, NULL); const char *entry_repos_relpath = svn_relpath_join( @@ -827,6 +884,7 @@ read_one_entry(const svn_wc_entry_t **ne &checksum, &lock, db, entry_abspath, + wcroot, entry_relpath, parent_entry, have_base, have_more_work, result_pool, scratch_pool)); @@ -869,7 +927,7 @@ read_one_entry(const svn_wc_entry_t **ne /* We got a SHA-1, get the corresponding MD-5. */ if (checksum->kind != svn_checksum_md5) SVN_ERR(svn_wc__db_pristine_get_md5(&checksum, db, - entry_abspath, checksum, + dir_abspath, checksum, scratch_pool, scratch_pool)); SVN_ERR_ASSERT(checksum->kind == svn_checksum_md5); @@ -881,8 +939,9 @@ read_one_entry(const svn_wc_entry_t **ne svn_skel_t *conflict; svn_boolean_t text_conflicted; svn_boolean_t prop_conflicted; - SVN_ERR(svn_wc__db_read_conflict(&conflict, db, entry_abspath, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, NULL, NULL, + wcroot, entry_relpath, + scratch_pool, scratch_pool)); SVN_ERR(svn_wc__conflict_read_info(NULL, NULL, &text_conflicted, &prop_conflicted, NULL, @@ -955,7 +1014,9 @@ read_one_entry(const svn_wc_entry_t **ne static svn_error_t * read_entries_new(apr_hash_t **result_entries, svn_wc__db_t *db, - const char *local_abspath, + const char *dir_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *dir_relpath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { @@ -964,11 +1025,12 @@ read_entries_new(apr_hash_t **result_ent apr_pool_t *iterpool = svn_pool_create(scratch_pool); int i; const svn_wc_entry_t *parent_entry; - apr_int64_t wc_id = 1; /* ### hacky. should remove. */ entries = apr_hash_make(result_pool); - SVN_ERR(read_one_entry(&parent_entry, db, wc_id, local_abspath, + SVN_ERR(read_one_entry(&parent_entry, + db, dir_abspath, + wcroot, dir_relpath, "" /* name */, NULL /* parent_entry */, result_pool, iterpool)); @@ -977,8 +1039,8 @@ read_entries_new(apr_hash_t **result_ent /* Use result_pool so that the child names (used by reference, rather than copied) appear in result_pool. */ SVN_ERR(svn_wc__db_read_children(&children, db, - local_abspath, - result_pool, iterpool)); + dir_abspath, + scratch_pool, iterpool)); for (i = children->nelts; i--; ) { const char *name = APR_ARRAY_IDX(children, i, const char *); @@ -987,7 +1049,9 @@ read_entries_new(apr_hash_t **result_ent svn_pool_clear(iterpool); SVN_ERR(read_one_entry(&entry, - db, wc_id, local_abspath, name, parent_entry, + db, dir_abspath, + wcroot, dir_relpath, + name, parent_entry, result_pool, iterpool)); svn_hash_sets(entries, entry->name, entry); } @@ -1000,28 +1064,20 @@ read_entries_new(apr_hash_t **result_ent } -/* Read a pair of entries from wc_db in the directory DIR_ABSPATH. Return - the directory's entry in *PARENT_ENTRY and NAME's entry in *ENTRY. The - two returned pointers will be the same if NAME=="" ("this dir"). - - The parent entry must exist. - - The requested entry MAY exist. If it does not, then NULL will be returned. - - The resulting entries are allocated in RESULT_POOL, and all temporary - allocations are made in SCRATCH_POOL. */ static svn_error_t * -read_entry_pair(const svn_wc_entry_t **parent_entry, - const svn_wc_entry_t **entry, - svn_wc__db_t *db, - const char *dir_abspath, - const char *name, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +read_entry_pair_txn(const svn_wc_entry_t **parent_entry, + const svn_wc_entry_t **entry, + svn_wc__db_t *db, + const char *dir_abspath, + svn_wc__db_wcroot_t *wcroot, + const char *dir_relpath, + const char *name, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - apr_int64_t wc_id = 1; /* ### hacky. should remove. */ - - SVN_ERR(read_one_entry(parent_entry, db, wc_id, dir_abspath, + SVN_ERR(read_one_entry(parent_entry, + db, dir_abspath, + wcroot, dir_relpath, "" /* name */, NULL /* parent_entry */, result_pool, scratch_pool)); @@ -1073,7 +1129,9 @@ read_entry_pair(const svn_wc_entry_t **p svn_error_t *err; err = read_one_entry(entry, - db, wc_id, dir_abspath, name, *parent_entry, + db, dir_abspath, + wcroot, dir_relpath, + name, *parent_entry, result_pool, scratch_pool); if (err) { @@ -1096,28 +1154,76 @@ read_entry_pair(const svn_wc_entry_t **p return SVN_NO_ERROR; } +/* Read a pair of entries from wc_db in the directory DIR_ABSPATH. Return + the directory's entry in *PARENT_ENTRY and NAME's entry in *ENTRY. The + two returned pointers will be the same if NAME=="" ("this dir"). + + The parent entry must exist. + + The requested entry MAY exist. If it does not, then NULL will be returned. + + The resulting entries are allocated in RESULT_POOL, and all temporary + allocations are made in SCRATCH_POOL. */ +static svn_error_t * +read_entry_pair(const svn_wc_entry_t **parent_entry, + const svn_wc_entry_t **entry, + svn_wc__db_t *db, + const char *dir_abspath, + const char *name, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *dir_relpath; + + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, + db, dir_abspath, + scratch_pool, scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_WC__DB_WITH_TXN(read_entry_pair_txn(parent_entry, entry, + db, dir_abspath, + wcroot, dir_relpath, + name, + result_pool, scratch_pool), + wcroot); + + return SVN_NO_ERROR; +} /* */ static svn_error_t * read_entries(apr_hash_t **entries, svn_wc__db_t *db, - const char *wcroot_abspath, + const char *dir_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { + svn_wc__db_wcroot_t *wcroot; + const char *dir_relpath; int wc_format; - SVN_ERR(svn_wc__db_temp_get_format(&wc_format, db, wcroot_abspath, + SVN_ERR(svn_wc__db_temp_get_format(&wc_format, db, dir_abspath, scratch_pool)); if (wc_format < SVN_WC__WC_NG_VERSION) return svn_error_trace(svn_wc__read_entries_old(entries, - wcroot_abspath, + dir_abspath, result_pool, scratch_pool)); - return svn_error_trace(read_entries_new(entries, db, wcroot_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &dir_relpath, + db, dir_abspath, + scratch_pool, scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_WC__DB_WITH_TXN(read_entries_new(entries, + db, dir_abspath, + wcroot, dir_relpath, + result_pool, scratch_pool), + wcroot); + + return SVN_NO_ERROR; } @@ -1372,25 +1478,6 @@ prune_deleted(apr_hash_t **entries_prune return SVN_NO_ERROR; } -struct entries_read_baton_t -{ - apr_hash_t **new_entries; - svn_wc__db_t *db; - const char *local_abspath; - apr_pool_t *result_pool; -}; - -static svn_error_t * -entries_read_txn(void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool) -{ - struct entries_read_baton_t *erb = baton; - - SVN_ERR(read_entries(erb->new_entries, erb->db, erb->local_abspath, - erb->result_pool, scratch_pool)); - - return NULL; -} - svn_error_t * svn_wc__entries_read_internal(apr_hash_t **entries, svn_wc_adm_access_t *adm_access, @@ -1405,21 +1492,9 @@ svn_wc__entries_read_internal(apr_hash_t svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); const char *local_abspath = svn_wc__adm_access_abspath(adm_access); apr_pool_t *result_pool = svn_wc__adm_access_pool_internal(adm_access); - svn_sqlite__db_t *sdb; - struct entries_read_baton_t erb; - - /* ### Use the borrow DB api to handle all calls in a single read - ### transaction. This api is used extensively in our test suite - ### via the entries-read application. */ - SVN_ERR(svn_wc__db_temp_borrow_sdb(&sdb, db, local_abspath, pool)); - - erb.db = db; - erb.local_abspath = local_abspath; - erb.new_entries = &new_entries; - erb.result_pool = result_pool; - - SVN_ERR(svn_sqlite__with_lock(sdb, entries_read_txn, &erb, pool)); + SVN_ERR(read_entries(&new_entries, db, local_abspath, + result_pool, pool)); svn_wc__adm_access_set_entries(adm_access, new_entries); } @@ -1452,23 +1527,31 @@ insert_node(svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool) { svn_sqlite__stmt_t *stmt; + svn_boolean_t present = (node->presence == svn_wc__db_status_normal + || node->presence == svn_wc__db_status_incomplete); SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath); SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE)); - SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsnrisnnni", + SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsn", node->wc_id, node->local_relpath, node->op_depth, node->parent_relpath, /* Setting depth for files? */ - svn_depth_to_word(node->depth), - node->changed_rev, - node->changed_date, - node->changed_author, - node->recorded_time)); + (node->kind == svn_node_dir && present) + ? svn_depth_to_word(node->depth) + : NULL)); - if (node->repos_relpath) + if (present && node->repos_relpath) + { + SVN_ERR(svn_sqlite__bind_revnum(stmt, 11, node->changed_rev)); + SVN_ERR(svn_sqlite__bind_int64(stmt, 12, node->changed_date)); + SVN_ERR(svn_sqlite__bind_text(stmt, 13, node->changed_author)); + } + + if (node->repos_relpath + && node->presence != svn_wc__db_status_base_deleted) { SVN_ERR(svn_sqlite__bind_int64(stmt, 5, node->repos_id)); @@ -1477,26 +1560,14 @@ insert_node(svn_sqlite__db_t *sdb, SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision)); } - if (node->presence == svn_wc__db_status_normal) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "normal")); - else if (node->presence == svn_wc__db_status_not_present) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "not-present")); - else if (node->presence == svn_wc__db_status_base_deleted) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "base-deleted")); - else if (node->presence == svn_wc__db_status_incomplete) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "incomplete")); - else if (node->presence == svn_wc__db_status_excluded) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "excluded")); - else if (node->presence == svn_wc__db_status_server_excluded) - SVN_ERR(svn_sqlite__bind_text(stmt, 8, "server-excluded")); + SVN_ERR(svn_sqlite__bind_token(stmt, 8, presence_map, node->presence)); if (node->kind == svn_node_none) SVN_ERR(svn_sqlite__bind_text(stmt, 10, "unknown")); else - SVN_ERR(svn_sqlite__bind_text(stmt, 10, - svn_node_kind_to_word(node->kind))); + SVN_ERR(svn_sqlite__bind_token(stmt, 10, kind_map, node->kind)); - if (node->kind == svn_node_file) + if (node->kind == svn_node_file && present) { if (!node->checksum && node->op_depth == 0 @@ -1510,19 +1581,25 @@ insert_node(svn_sqlite__db_t *sdb, SVN_ERR(svn_sqlite__bind_checksum(stmt, 14, node->checksum, scratch_pool)); + + if (node->repos_relpath) + { + if (node->recorded_size != SVN_INVALID_FILESIZE) + SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size)); + + SVN_ERR(svn_sqlite__bind_int64(stmt, 17, node->recorded_time)); + } } - if (node->properties) /* ### Never set, props done later */ + /* ### Never set, props done later */ + if (node->properties && present && node->repos_relpath) SVN_ERR(svn_sqlite__bind_properties(stmt, 15, node->properties, scratch_pool)); - if (node->recorded_size != SVN_INVALID_FILESIZE) - SVN_ERR(svn_sqlite__bind_int64(stmt, 16, node->recorded_size)); - if (node->file_external) SVN_ERR(svn_sqlite__bind_int(stmt, 20, 1)); - if (node->inherited_props) + if (node->inherited_props && present) SVN_ERR(svn_sqlite__bind_iprops(stmt, 23, node->inherited_props, scratch_pool)); @@ -1801,6 +1878,10 @@ write_entry(struct write_baton **entry_n if (entry->copied) { + db_node_t *work = parent_node->work + ? parent_node->work + : parent_node->below_work; + if (entry->copyfrom_url) { working_node->repos_id = repos_id; @@ -1810,20 +1891,37 @@ write_entry(struct write_baton **entry_n working_node->revision = entry->copyfrom_rev; working_node->op_depth = svn_wc__db_op_depth_for_upgrade(local_relpath); + + if (work && work->repos_relpath + && work->repos_id == repos_id + && work->revision == entry->copyfrom_rev) + { + const char *name; + + name = svn_relpath_skip_ancestor(work->repos_relpath, + working_node->repos_relpath); + + if (name + && !strcmp(name, svn_relpath_basename(local_relpath, NULL))) + { + working_node->op_depth = work->op_depth; + } + } } - else if (parent_node->work && parent_node->work->repos_relpath) + else if (work && work->repos_relpath) { working_node->repos_id = repos_id; working_node->repos_relpath - = svn_relpath_join(parent_node->work->repos_relpath, + = svn_relpath_join(work->repos_relpath, svn_relpath_basename(local_relpath, NULL), result_pool); - working_node->revision = parent_node->work->revision; - working_node->op_depth = parent_node->work->op_depth; + working_node->revision = work->revision; + working_node->op_depth = work->op_depth; } else if (parent_node->below_work && parent_node->below_work->repos_relpath) { + /* Parent deleted, this not-present or similar */ working_node->repos_id = repos_id; working_node->repos_relpath = svn_relpath_join(parent_node->below_work->repos_relpath, @@ -1837,6 +1935,29 @@ write_entry(struct write_baton **entry_n _("No copyfrom URL for '%s'"), svn_dirent_local_style(local_relpath, scratch_pool)); + + if (work && work->op_depth != working_node->op_depth + && work->repos_relpath + && work->repos_id == working_node->repos_id + && work->presence == svn_wc__db_status_normal + && !below_working_node) + { + /* Introduce a not-present node! */ + below_working_node = MAYBE_ALLOC(below_working_node, scratch_pool); + + below_working_node->wc_id = wc_id; + below_working_node->op_depth = work->op_depth; + below_working_node->local_relpath = local_relpath; + below_working_node->parent_relpath = parent_relpath; + + below_working_node->presence = svn_wc__db_status_not_present; + below_working_node->repos_id = repos_id; + below_working_node->repos_relpath = working_node->local_relpath; + + SVN_ERR(insert_node(sdb, below_working_node, scratch_pool)); + + below_working_node = NULL; /* Don't write a present intermediate! */ + } } if (entry->conflict_old) @@ -1909,11 +2030,6 @@ write_entry(struct write_baton **entry_n WRITE_ENTRY_ASSERT(conflict->kind == svn_wc_conflict_kind_tree); - /* Fix dubious data stored by old clients, local adds don't have - a repository URL. */ - if (conflict->reason == svn_wc_conflict_reason_added) - conflict->src_left_version = NULL; - SVN_ERR(svn_wc__serialize_conflict(&new_skel, conflict, scratch_pool, scratch_pool)); @@ -2140,17 +2256,18 @@ write_entry(struct write_baton **entry_n below_working_node->presence = svn_wc__db_status_normal; below_working_node->kind = entry->kind; below_working_node->repos_id = work->repos_id; + below_working_node->revision = work->revision; /* This is just guessing. If the node below would have been switched or if it was updated to a different version, the guess would fail. But we don't have better information pre wc-ng :( */ if (work->repos_relpath) below_working_node->repos_relpath - = svn_relpath_join(work->repos_relpath, entry->name, + = svn_relpath_join(work->repos_relpath, + svn_relpath_basename(local_relpath, NULL), result_pool); else below_working_node->repos_relpath = NULL; - below_working_node->revision = parent_node->work->revision; /* The revert_base checksum isn't available in the entry structure, so the caller provides it. */ @@ -2294,6 +2411,11 @@ write_entry(struct write_baton **entry_n { working_node->op_depth = parent_node->work->op_depth; } + else if (working_node->presence == svn_wc__db_status_excluded + && parent_node->work) + { + working_node->op_depth = parent_node->work->op_depth; + } else if (!entry->copied) { working_node->op_depth @@ -2660,11 +2782,11 @@ svn_wc_walk_entries3(const char *path, svn_wc__db_t *db = svn_wc__adm_get_db(adm_access); svn_error_t *err; svn_node_kind_t kind; - svn_depth_t depth; + svn_wc__db_status_t status; SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool)); - err = svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, &depth, NULL, NULL, + err = svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -2683,7 +2805,9 @@ svn_wc_walk_entries3(const char *path, walk_baton, pool); } - if (kind == svn_node_file || depth == svn_depth_exclude) + if (kind == svn_node_file + || status == svn_wc__db_status_excluded + || status == svn_wc__db_status_server_excluded) { const svn_wc_entry_t *entry; @@ -2692,27 +2816,24 @@ svn_wc_walk_entries3(const char *path, ### we should not call handle_error for an error the *callback* ### gave us. let it deal with the problem before returning. */ - if (!show_hidden) - { - svn_boolean_t hidden; - SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, pool)); - - if (hidden) - { - /* The fool asked to walk a "hidden" node. Report the node as - unversioned. - - ### this is incorrect behavior. see depth_test 36. the walk - ### API will be revamped to avoid entry structures. we should - ### be able to solve the problem with the new API. (since we - ### shouldn't return a hidden entry here) */ - return walk_callbacks->handle_error( - path, svn_error_createf( - SVN_ERR_UNVERSIONED_RESOURCE, NULL, - _("'%s' is not under version control"), - svn_dirent_local_style(local_abspath, pool)), - walk_baton, pool); - } + if (!show_hidden + && (status == svn_wc__db_status_not_present + || status == svn_wc__db_status_excluded + || status == svn_wc__db_status_server_excluded)) + { + /* The fool asked to walk a "hidden" node. Report the node as + unversioned. + + ### this is incorrect behavior. see depth_test 36. the walk + ### API will be revamped to avoid entry structures. we should + ### be able to solve the problem with the new API. (since we + ### shouldn't return a hidden entry here) */ + return walk_callbacks->handle_error( + path, svn_error_createf( + SVN_ERR_UNVERSIONED_RESOURCE, NULL, + _("'%s' is not under version control"), + svn_dirent_local_style(local_abspath, pool)), + walk_baton, pool); } SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, FALSE,
Modified: subversion/branches/fsx-1.10/subversion/libsvn_wc/externals.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_wc/externals.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/libsvn_wc/externals.c (original) +++ subversion/branches/fsx-1.10/subversion/libsvn_wc/externals.c Sun Jun 14 20:58:10 2015 @@ -68,6 +68,7 @@ * the revision if the revision is found. Set REV_IDX to the index in * LINE_PARTS where the revision specification starts. Remove from * LINE_PARTS the element(s) that specify the revision. + * Set REV_STR to the element that specifies the revision. * PARENT_DIRECTORY_DISPLAY and LINE are given to return a nice error * string. * @@ -76,6 +77,7 @@ */ static svn_error_t * find_and_remove_externals_revision(int *rev_idx, + const char **rev_str, const char **line_parts, int num_line_parts, svn_wc_external_item2_t *item, @@ -137,6 +139,8 @@ find_and_remove_externals_revision(int * line_parts[j] = line_parts[j+shift_count]; line_parts[num_line_parts-shift_count] = NULL; + *rev_str = apr_psprintf(pool, "-r%s", digits_ptr); + /* Found the revision, so leave the function immediately, do * not continue looking for additional revisions. */ return SVN_NO_ERROR; @@ -158,7 +162,8 @@ find_and_remove_externals_revision(int * } svn_error_t * -svn_wc_parse_externals_description3(apr_array_header_t **externals_p, +svn_wc__parse_externals_description(apr_array_header_t **externals_p, + apr_array_header_t **parser_infos_p, const char *defining_directory, const char *desc, svn_boolean_t canonicalize_url, @@ -166,6 +171,7 @@ svn_wc_parse_externals_description3(apr_ { int i; apr_array_header_t *externals = NULL; + apr_array_header_t *parser_infos = NULL; apr_array_header_t *lines = svn_cstring_split(desc, "\n\r", TRUE, pool); const char *defining_directory_display = svn_path_is_url(defining_directory) ? defining_directory : svn_dirent_local_style(defining_directory, pool); @@ -175,6 +181,10 @@ svn_wc_parse_externals_description3(apr_ if (externals_p) externals = apr_array_make(pool, 1, sizeof(svn_wc_external_item2_t *)); + if (parser_infos_p) + parser_infos = + apr_array_make(pool, 1, sizeof(svn_wc__externals_parser_info_t *)); + for (i = 0; i < lines->nelts; i++) { const char *line = APR_ARRAY_IDX(lines, i, const char *); @@ -186,10 +196,12 @@ svn_wc_parse_externals_description3(apr_ const char *token1; svn_boolean_t token0_is_url; svn_boolean_t token1_is_url; + svn_wc__externals_parser_info_t *info = NULL; /* Index into line_parts where the revision specification started. */ int rev_idx = -1; + const char *rev_str = NULL; if ((! line) || (line[0] == '#')) continue; @@ -209,6 +221,9 @@ svn_wc_parse_externals_description3(apr_ item->revision.kind = svn_opt_revision_unspecified; item->peg_revision.kind = svn_opt_revision_unspecified; + if (parser_infos) + info = apr_pcalloc(pool, sizeof(*info)); + /* * There are six different formats of externals: * @@ -240,6 +255,7 @@ svn_wc_parse_externals_description3(apr_ set item->revision to the parsed revision. */ /* ### ugh. stupid cast. */ SVN_ERR(find_and_remove_externals_revision(&rev_idx, + &rev_str, (const char **)line_parts, num_line_parts, item, defining_directory_display, @@ -290,12 +306,34 @@ svn_wc_parse_externals_description3(apr_ SVN_ERR(svn_opt_parse_path(&item->peg_revision, &item->url, token0, pool)); item->target_dir = token1; + + if (info) + { + info->format = svn_wc__external_description_format_2; + + if (rev_str) + info->rev_str = apr_pstrdup(pool, rev_str); + + if (item->peg_revision.kind != svn_opt_revision_unspecified) + info->peg_rev_str = strrchr(token0, '@'); + } } else { item->target_dir = token0; item->url = token1; item->peg_revision = item->revision; + + if (info) + { + info->format = svn_wc__external_description_format_1; + + if (rev_str) + { + info->rev_str = apr_pstrdup(pool, rev_str); + info->peg_rev_str = info->rev_str; + } + } } SVN_ERR(svn_opt_resolve_revisions(&item->peg_revision, @@ -333,15 +371,34 @@ svn_wc_parse_externals_description3(apr_ if (externals) APR_ARRAY_PUSH(externals, svn_wc_external_item2_t *) = item; + if (parser_infos) + APR_ARRAY_PUSH(parser_infos, svn_wc__externals_parser_info_t *) = info; } if (externals_p) *externals_p = externals; + if (parser_infos_p) + *parser_infos_p = parser_infos; return SVN_NO_ERROR; } svn_error_t * +svn_wc_parse_externals_description3(apr_array_header_t **externals_p, + const char *defining_directory, + const char *desc, + svn_boolean_t canonicalize_url, + apr_pool_t *pool) +{ + return svn_error_trace(svn_wc__parse_externals_description(externals_p, + NULL, + defining_directory, + desc, + canonicalize_url, + pool)); +} + +svn_error_t * svn_wc__externals_find_target_dups(apr_array_header_t **duplicate_targets, apr_array_header_t *externals, apr_pool_t *pool, @@ -405,9 +462,10 @@ struct edit_baton const apr_array_header_t *ext_patterns; const char *diff3cmd; - const char *url; const char *repos_root_url; const char *repos_uuid; + const char *old_repos_relpath; + const char *new_repos_relpath; const char *record_ancestor_abspath; const char *recorded_repos_relpath; @@ -417,6 +475,8 @@ struct edit_baton /* Introducing a new file external */ svn_boolean_t added; + svn_wc_conflict_resolver_func2_t conflict_func; + void *conflict_baton; svn_cancel_func_t cancel_func; void *cancel_baton; svn_wc_notify_func2_t notify_func; @@ -515,7 +575,8 @@ open_file(const char *path, *file_baton = eb; SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &eb->original_revision, - NULL, NULL, NULL, &eb->changed_rev, + &eb->old_repos_relpath, NULL, NULL, + &eb->changed_rev, &eb->changed_date, &eb->changed_author, NULL, &eb->original_checksum, NULL, NULL, &eb->had_props, NULL, NULL, @@ -676,8 +737,6 @@ close_file(void *file_baton, const svn_checksum_t *original_checksum = NULL; svn_boolean_t added = !SVN_IS_VALID_REVNUM(eb->original_revision); - const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, - eb->url, pool); if (! added) { @@ -851,14 +910,14 @@ close_file(void *file_baton, svn_wc_conflict_version_create2( eb->repos_root_url, eb->repos_uuid, - repos_relpath, + eb->old_repos_relpath, eb->original_revision, svn_node_file, pool), svn_wc_conflict_version_create2( eb->repos_root_url, eb->repos_uuid, - repos_relpath, + eb->new_repos_relpath, *eb->target_revision, svn_node_file, pool), @@ -876,7 +935,7 @@ close_file(void *file_baton, eb->db, eb->local_abspath, eb->wri_abspath, - repos_relpath, + eb->new_repos_relpath, eb->repos_root_url, eb->repos_uuid, *eb->target_revision, @@ -906,6 +965,18 @@ close_file(void *file_baton, /* Run the work queue to complete the installation */ SVN_ERR(svn_wc__wq_run(eb->db, eb->wri_abspath, eb->cancel_func, eb->cancel_baton, pool)); + + if (conflict_skel && eb->conflict_func) + SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, + eb->local_abspath, + svn_node_file, + conflict_skel, + NULL /* merge_options */, + eb->conflict_func, + eb->conflict_baton, + eb->cancel_func, + eb->cancel_baton, + pool)); } /* Notify */ @@ -945,6 +1016,7 @@ close_edit(void *edit_baton, if (!eb->file_closed) { + apr_hash_t *wcroot_iprops = NULL; /* The file wasn't updated, but its url or revision might have... e.g. switch between branches for relative externals. @@ -952,53 +1024,26 @@ close_edit(void *edit_baton, investigating when we should and shouldn't update it... and avoid hard to debug edge cases */ - svn_node_kind_t kind; - const char *old_repos_relpath; - svn_revnum_t changed_rev; - apr_time_t changed_date; - const char *changed_author; - const svn_checksum_t *checksum; - apr_hash_t *pristine_props; - const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, - eb->url, pool); - - SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath, - NULL, NULL, &changed_rev, &changed_date, - &changed_author, NULL, &checksum, NULL, - NULL, NULL, &pristine_props, NULL, - eb->db, eb->local_abspath, - pool, pool)); + if (eb->iprops) + { + wcroot_iprops = apr_hash_make(pool); + svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops); + } - if (kind != svn_node_file) - return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL, - _("Node '%s' is no existing file external"), - svn_dirent_local_style(eb->local_abspath, - pool)); - - SVN_ERR(svn_wc__db_external_add_file( - eb->db, - eb->local_abspath, - eb->wri_abspath, - repos_relpath, - eb->repos_root_url, - eb->repos_uuid, - *eb->target_revision, - pristine_props, - eb->iprops, - eb->changed_rev, - eb->changed_date, - eb->changed_author, - checksum, - NULL /* clear dav props */, - eb->record_ancestor_abspath, - eb->recorded_repos_relpath, - eb->recorded_peg_revision, - eb->recorded_revision, - FALSE, NULL, - TRUE /* keep_recorded_info */, - NULL /* conflict_skel */, - NULL /* work_items */, - pool)); + SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db, + eb->local_abspath, + svn_depth_infinity, + eb->new_repos_relpath, + eb->repos_root_url, + eb->repos_uuid, + *eb->target_revision, + apr_hash_make(pool) + /* exclude_relpaths */, + wcroot_iprops, + TRUE /* empty update */, + eb->notify_func, + eb->notify_baton, + pool)); } return SVN_NO_ERROR; @@ -1022,6 +1067,8 @@ svn_wc__get_file_external_editor(const s const char *recorded_url, const svn_opt_revision_t *recorded_peg_rev, const svn_opt_revision_t *recorded_rev, + svn_wc_conflict_resolver_func2_t conflict_func, + void *conflict_baton, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -1044,9 +1091,12 @@ svn_wc__get_file_external_editor(const s eb->name = svn_dirent_basename(eb->local_abspath, NULL); eb->target_revision = target_revision; - eb->url = apr_pstrdup(edit_pool, url); eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url); eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid); + eb->new_repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, url, edit_pool); + eb->old_repos_relpath = eb->new_repos_relpath; + + eb->original_revision = SVN_INVALID_REVNUM; eb->iprops = iprops; @@ -1070,6 +1120,8 @@ svn_wc__get_file_external_editor(const s else eb->recorded_revision = SVN_INVALID_REVNUM; /* Not fixed/HEAD */ + eb->conflict_func = conflict_func; + eb->conflict_baton = conflict_baton; eb->cancel_func = cancel_func; eb->cancel_baton = cancel_baton; eb->notify_func = notify_func; @@ -1439,10 +1491,8 @@ svn_wc__external_remove(svn_wc_context_t else { SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath, - FALSE /* keep_as_working */, - TRUE /* queue_deletes */, - FALSE /* remove_locks */, - SVN_INVALID_REVNUM, + FALSE, TRUE, FALSE, + 0, NULL, NULL, scratch_pool)); SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath, cancel_func, cancel_baton, Modified: subversion/branches/fsx-1.10/subversion/libsvn_wc/info.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_wc/info.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/libsvn_wc/info.c (original) +++ subversion/branches/fsx-1.10/subversion/libsvn_wc/info.c Sun Jun 14 20:58:10 2015 @@ -141,7 +141,6 @@ build_info_for_node(svn_wc__info2_t **in { /* Root or child of copy */ tmpinfo->rev = original_revision; - repos_relpath = original_repos_relpath; if (op_root) { @@ -167,34 +166,6 @@ build_info_for_node(svn_wc__info2_t **in } } } - else if (op_root) - { - /* Local addition */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, - NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - - if (have_base) - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &tmpinfo->rev, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - } - else - { - /* Child of copy. ### Not WC-NG like */ - SVN_ERR(svn_wc__internal_get_origin(NULL, &tmpinfo->rev, - &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, NULL, NULL, - db, local_abspath, TRUE, - result_pool, scratch_pool)); - } /* ### We should be able to avoid both these calls with the information from read_info() in most cases */ @@ -222,14 +193,20 @@ build_info_for_node(svn_wc__info2_t **in else wc_info->schedule = svn_wc_schedule_add; } - SVN_ERR(svn_wc__db_read_url(&tmpinfo->URL, db, local_abspath, - result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath, + &tmpinfo->repos_root_URL, + &tmpinfo->repos_UUID, + db, local_abspath, + result_pool, scratch_pool)); + + tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, + repos_relpath, result_pool); } else if (status == svn_wc__db_status_deleted) { - const char *work_del_abspath; + svn_wc__db_status_t w_status; - SVN_ERR(svn_wc__db_read_pristine_info(NULL, NULL, + SVN_ERR(svn_wc__db_read_pristine_info(&w_status, &tmpinfo->kind, &tmpinfo->last_changed_rev, &tmpinfo->last_changed_date, &tmpinfo->last_changed_author, @@ -239,51 +216,32 @@ build_info_for_node(svn_wc__info2_t **in db, local_abspath, result_pool, scratch_pool)); + if (w_status == svn_wc__db_status_deleted) + { + /* We have a working not-present status. We don't know anything + about this node, but it *is visible* in STATUS. + + Let's tell that it is excluded */ + + wc_info->depth = svn_depth_exclude; + tmpinfo->kind = svn_node_unknown; + } + /* And now fetch the url and revision of what will be deleted */ SVN_ERR(svn_wc__db_scan_deletion(NULL, &wc_info->moved_to_abspath, - &work_del_abspath, NULL, + NULL, NULL, db, local_abspath, scratch_pool, scratch_pool)); - if (work_del_abspath != NULL) - { - /* This is a deletion within a copied subtree. Get the copied-from - * revision. */ - const char *added_abspath = svn_dirent_dirname(work_del_abspath, - scratch_pool); - - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, - NULL, NULL, NULL, - &tmpinfo->rev, - db, added_abspath, - result_pool, scratch_pool)); - - tmpinfo->URL = svn_path_url_add_component2( - tmpinfo->repos_root_URL, - svn_relpath_join(repos_relpath, - svn_dirent_skip_ancestor(added_abspath, - local_abspath), - scratch_pool), - result_pool); - } - else - { - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &tmpinfo->rev, - &repos_relpath, - &tmpinfo->repos_root_URL, - &tmpinfo->repos_UUID, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - - tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, - repos_relpath, - result_pool); - } + + SVN_ERR(svn_wc__db_read_repos_info(&tmpinfo->rev, &repos_relpath, + &tmpinfo->repos_root_URL, + &tmpinfo->repos_UUID, + db, local_abspath, + result_pool, scratch_pool)); wc_info->schedule = svn_wc_schedule_delete; + tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, + repos_relpath, result_pool); } else if (status == svn_wc__db_status_not_present || status == svn_wc__db_status_server_excluded) @@ -291,6 +249,21 @@ build_info_for_node(svn_wc__info2_t **in *info = NULL; return SVN_NO_ERROR; } + else if (status == svn_wc__db_status_excluded && !repos_relpath) + { + /* We have a WORKING exclude. Avoid segfault on no repos info */ + + SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath, + &tmpinfo->repos_root_URL, + &tmpinfo->repos_UUID, + db, local_abspath, + result_pool, scratch_pool)); + + wc_info->schedule = svn_wc_schedule_normal; + tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL, + repos_relpath, result_pool); + tmpinfo->wc_info->depth = svn_depth_exclude; + } else { /* Just a BASE node. We have all the info we need */ @@ -298,10 +271,10 @@ build_info_for_node(svn_wc__info2_t **in repos_relpath, result_pool); wc_info->schedule = svn_wc_schedule_normal; - } - if (status == svn_wc__db_status_excluded) - tmpinfo->wc_info->depth = svn_depth_exclude; + if (status == svn_wc__db_status_excluded) + wc_info->depth = svn_depth_exclude; + } /* A default */ tmpinfo->size = SVN_INVALID_FILESIZE; @@ -310,9 +283,10 @@ build_info_for_node(svn_wc__info2_t **in local_abspath, result_pool, scratch_pool)); if (conflicted) - SVN_ERR(svn_wc__read_conflicts(&wc_info->conflicts, db, - local_abspath, - TRUE /* ### create tempfiles */, + SVN_ERR(svn_wc__read_conflicts(&wc_info->conflicts, NULL, + db, local_abspath, + FALSE /* create tempfiles */, + FALSE /* only tree conflicts */, result_pool, scratch_pool)); else wc_info->conflicts = NULL; @@ -544,23 +518,23 @@ svn_wc__get_info(svn_wc_context_t *wc_ct if (!repos_root_url) { - SVN_ERR(svn_wc__internal_get_repos_info(NULL, NULL, - &repos_root_url, - &repos_uuid, - wc_ctx->db, - svn_dirent_dirname( + SVN_ERR(svn_wc__db_read_repos_info(NULL, NULL, + &repos_root_url, + &repos_uuid, + wc_ctx->db, + svn_dirent_dirname( this_abspath, iterpool), - scratch_pool, - iterpool)); + scratch_pool, iterpool)); } info->repos_root_URL = repos_root_url; info->repos_UUID = repos_uuid; - SVN_ERR(svn_wc__read_conflicts(&conflicts, + SVN_ERR(svn_wc__read_conflicts(&conflicts, NULL, wc_ctx->db, this_abspath, - TRUE /* ### create tempfiles */, + FALSE /* create tempfiles */, + FALSE /* only tree conflicts */, iterpool, iterpool)); if (! conflicts || ! conflicts->nelts) continue; Modified: subversion/branches/fsx-1.10/subversion/libsvn_wc/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_wc/merge.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/libsvn_wc/merge.c (original) +++ subversion/branches/fsx-1.10/subversion/libsvn_wc/merge.c Sun Jun 14 20:58:10 2015 @@ -1230,6 +1230,7 @@ svn_wc_merge5(enum svn_wc_merge_outcome_ apr_hash_t *pristine_props = NULL; apr_hash_t *old_actual_props; apr_hash_t *new_actual_props = NULL; + svn_node_kind_t kind; SVN_ERR_ASSERT(svn_dirent_is_absolute(left_abspath)); SVN_ERR_ASSERT(svn_dirent_is_absolute(right_abspath)); @@ -1242,7 +1243,6 @@ svn_wc_merge5(enum svn_wc_merge_outcome_ /* Sanity check: the merge target must be a file under revision control */ { svn_wc__db_status_t status; - svn_node_kind_t kind; svn_boolean_t had_props; svn_boolean_t props_mod; svn_boolean_t conflicted; @@ -1405,7 +1405,7 @@ svn_wc_merge5(enum svn_wc_merge_outcome_ svn_boolean_t text_conflicted, prop_conflicted; SVN_ERR(svn_wc__conflict_invoke_resolver( - wc_ctx->db, target_abspath, + wc_ctx->db, target_abspath, kind, conflict_skel, merge_options, conflict_func, conflict_baton, cancel_func, cancel_baton, Modified: subversion/branches/fsx-1.10/subversion/libsvn_wc/node.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_wc/node.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/libsvn_wc/node.c (original) +++ subversion/branches/fsx-1.10/subversion/libsvn_wc/node.c Sun Jun 14 20:58:10 2015 @@ -54,18 +54,14 @@ /* Set *CHILDREN_ABSPATHS to a new array of the full paths formed by joining - * each name in REL_CHILDREN onto DIR_ABSPATH. If SHOW_HIDDEN is false then - * omit any paths that are reported as 'hidden' by svn_wc__db_node_hidden(). + * each name in REL_CHILDREN onto DIR_ABSPATH. * * Allocate the output array and its elements in RESULT_POOL. */ -static svn_error_t * -filter_and_make_absolute(const apr_array_header_t **children_abspaths, - svn_wc_context_t *wc_ctx, - const char *dir_abspath, - const apr_array_header_t *rel_children, - svn_boolean_t show_hidden, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +static void +make_absolute(const apr_array_header_t **children_abspaths, + const char *dir_abspath, + const apr_array_header_t *rel_children, + apr_pool_t *result_pool) { apr_array_header_t *children; int i; @@ -74,29 +70,13 @@ filter_and_make_absolute(const apr_array sizeof(const char *)); for (i = 0; i < rel_children->nelts; i++) { - const char *child_abspath = svn_dirent_join(dir_abspath, - APR_ARRAY_IDX(rel_children, - i, - const char *), - result_pool); - - /* Don't add hidden nodes to *CHILDREN if we don't want them. */ - if (!show_hidden) - { - svn_boolean_t child_is_hidden; - - SVN_ERR(svn_wc__db_node_hidden(&child_is_hidden, wc_ctx->db, - child_abspath, scratch_pool)); - if (child_is_hidden) - continue; - } - - APR_ARRAY_PUSH(children, const char *) = child_abspath; + const char *name = APR_ARRAY_IDX(rel_children, i, const char *); + APR_ARRAY_PUSH(children, const char *) = + svn_dirent_join(dir_abspath, name, + result_pool); } *children_abspaths = children; - - return SVN_NO_ERROR; } @@ -104,136 +84,36 @@ svn_error_t * svn_wc__node_get_children_of_working_node(const apr_array_header_t **children, svn_wc_context_t *wc_ctx, const char *dir_abspath, - svn_boolean_t show_hidden, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - const apr_array_header_t *rel_children; + const apr_array_header_t *child_names; - SVN_ERR(svn_wc__db_read_children_of_working_node(&rel_children, + SVN_ERR(svn_wc__db_read_children_of_working_node(&child_names, wc_ctx->db, dir_abspath, scratch_pool, scratch_pool)); - SVN_ERR(filter_and_make_absolute(children, wc_ctx, dir_abspath, - rel_children, show_hidden, - result_pool, scratch_pool)); - return SVN_NO_ERROR; -} - -svn_error_t * -svn_wc__node_get_children(const apr_array_header_t **children, - svn_wc_context_t *wc_ctx, - const char *dir_abspath, - svn_boolean_t show_hidden, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - const apr_array_header_t *rel_children; - - SVN_ERR(svn_wc__db_read_children(&rel_children, wc_ctx->db, dir_abspath, - scratch_pool, scratch_pool)); - SVN_ERR(filter_and_make_absolute(children, wc_ctx, dir_abspath, - rel_children, show_hidden, - result_pool, scratch_pool)); + make_absolute(children, dir_abspath, child_names, result_pool); return SVN_NO_ERROR; } - svn_error_t * -svn_wc__internal_get_repos_info(svn_revnum_t *revision, - const char **repos_relpath, - const char **repos_root_url, - const char **repos_uuid, - svn_wc__db_t *db, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - svn_boolean_t have_work; - - SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, repos_relpath, - repos_root_url, repos_uuid, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, &have_work, - db, local_abspath, - result_pool, scratch_pool)); - - if ((repos_relpath ? *repos_relpath != NULL : TRUE) - && (repos_root_url ? *repos_root_url != NULL: TRUE) - && (repos_uuid ? *repos_uuid != NULL : TRUE)) - return SVN_NO_ERROR; /* We got the requested information */ - - if (!have_work) /* not-present, (server-)excluded? */ - { - return SVN_NO_ERROR; /* Can't fetch more */ - } - - if (status == svn_wc__db_status_deleted) - { - const char *base_del_abspath, *wrk_del_abspath; - - SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL, - &wrk_del_abspath, NULL, - db, local_abspath, - scratch_pool, scratch_pool)); - - if (base_del_abspath) - { - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, repos_relpath, - repos_root_url, repos_uuid, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - db, base_del_abspath, - result_pool, scratch_pool)); - - /* If we have a repos_relpath, it is of the op-root */ - if (repos_relpath) - *repos_relpath = svn_relpath_join(*repos_relpath, - svn_dirent_skip_ancestor(base_del_abspath, - local_abspath), - result_pool); - /* We keep revision as SVN_INVALID_REVNUM */ - } - else if (wrk_del_abspath) - { - const char *op_root_abspath = NULL; - - SVN_ERR(svn_wc__db_scan_addition(NULL, repos_relpath - ? &op_root_abspath : NULL, - repos_relpath, repos_root_url, - repos_uuid, NULL, NULL, NULL, NULL, - db, svn_dirent_dirname( - wrk_del_abspath, - scratch_pool), - result_pool, scratch_pool)); - - /* If we have a repos_relpath, it is of the op-root */ - if (repos_relpath) - *repos_relpath = svn_relpath_join( - *repos_relpath, - svn_dirent_skip_ancestor(op_root_abspath, - local_abspath), - result_pool); - } - } - else /* added, or WORKING incomplete */ - { - /* We have an addition. scan_addition() will find the intended - repository location by scanning up the tree. */ - SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, - repos_relpath, repos_root_url, - repos_uuid, NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - } - - SVN_ERR_ASSERT(repos_root_url == NULL || *repos_root_url != NULL); - SVN_ERR_ASSERT(repos_uuid == NULL || *repos_uuid != NULL); +svn_wc__node_get_not_present_children(const apr_array_header_t **children, + svn_wc_context_t *wc_ctx, + const char *dir_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + const apr_array_header_t *child_names; + + SVN_ERR(svn_wc__db_base_read_not_present_children( + &child_names, + wc_ctx->db, dir_abspath, + scratch_pool, scratch_pool)); + make_absolute(children, dir_abspath, child_names, result_pool); return SVN_NO_ERROR; } + svn_error_t * svn_wc__node_get_repos_info(svn_revnum_t *revision, const char **repos_relpath, @@ -245,12 +125,12 @@ svn_wc__node_get_repos_info(svn_revnum_t apr_pool_t *scratch_pool) { return svn_error_trace( - svn_wc__internal_get_repos_info(revision, - repos_relpath, - repos_root_url, - repos_uuid, - wc_ctx->db, local_abspath, - result_pool, scratch_pool)); + svn_wc__db_read_repos_info(revision, + repos_relpath, + repos_root_url, + repos_uuid, + wc_ctx->db, local_abspath, + result_pool, scratch_pool)); } /* Convert DB_KIND into the appropriate NODE_KIND value. @@ -344,8 +224,18 @@ svn_wc__node_get_url(const char **url, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - return svn_error_trace(svn_wc__db_read_url(url, wc_ctx->db, local_abspath, - result_pool, scratch_pool)); + const char *repos_root_url; + const char *repos_relpath; + + SVN_ERR(svn_wc__db_read_repos_info(NULL, &repos_relpath, &repos_root_url, + NULL, + wc_ctx->db, local_abspath, + scratch_pool, scratch_pool)); + + *url = svn_path_url_add_component2(repos_root_url, repos_relpath, + result_pool); + + return SVN_NO_ERROR; } /* A recursive node-walker, helper for svn_wc__internal_walk_children(). @@ -370,25 +260,24 @@ walker_helper(svn_wc__db_t *db, void *cancel_baton, apr_pool_t *scratch_pool) { - apr_hash_t *rel_children_info; - apr_hash_index_t *hi; apr_pool_t *iterpool; + const apr_array_header_t *items; + int i; if (depth == svn_depth_empty) return SVN_NO_ERROR; - SVN_ERR(svn_wc__db_read_children_walker_info(&rel_children_info, db, - dir_abspath, scratch_pool, - scratch_pool)); + iterpool = svn_pool_create(scratch_pool); + SVN_ERR(svn_wc__db_read_children_walker_info(&items, db, + dir_abspath, scratch_pool, + iterpool)); - iterpool = svn_pool_create(scratch_pool); - for (hi = apr_hash_first(scratch_pool, rel_children_info); - hi; - hi = apr_hash_next(hi)) + for (i = 0; i < items->nelts; i++) { - const char *child_name = apr_hash_this_key(hi); - struct svn_wc__db_walker_info_t *wi = apr_hash_this_val(hi); + struct svn_wc__db_walker_info_t *wi = + APR_ARRAY_IDX(items, i, struct svn_wc__db_walker_info_t *); + const char *child_name = wi->name; svn_node_kind_t child_kind = wi->kind; svn_wc__db_status_t child_status = wi->status; const char *child_abspath; @@ -517,33 +406,6 @@ svn_wc__internal_walk_children(svn_wc__d } svn_error_t * -svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - svn_wc__db_status_t status; - - *deleted_ancestor_abspath = NULL; - - SVN_ERR(svn_wc__db_read_info(&status, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - wc_ctx->db, local_abspath, - scratch_pool, scratch_pool)); - - if (status == svn_wc__db_status_deleted) - SVN_ERR(svn_wc__db_scan_deletion(deleted_ancestor_abspath, NULL, NULL, - NULL, wc_ctx->db, local_abspath, - result_pool, scratch_pool)); - - return SVN_NO_ERROR; -} - -svn_error_t * svn_wc__node_is_not_present(svn_boolean_t *is_not_present, svn_boolean_t *is_excluded, svn_boolean_t *is_server_excluded, Modified: subversion/branches/fsx-1.10/subversion/libsvn_wc/props.c URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/libsvn_wc/props.c?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/libsvn_wc/props.c (original) +++ subversion/branches/fsx-1.10/subversion/libsvn_wc/props.c Sun Jun 14 20:58:10 2015 @@ -327,7 +327,8 @@ svn_wc_merge_props3(svn_wc_notify_state_ { svn_boolean_t prop_conflicted; - SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, conflict_skel, + SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, kind, + conflict_skel, NULL /* merge_options */, conflict_func, conflict_baton, cancel_func, cancel_baton, @@ -541,7 +542,7 @@ prop_conflict_new(const svn_string_t **c /* How we render the conflict: - We have four sides: original, mine, incoming_base, incoming. + We have four sides: original, mine, incoming_base, incoming. We render the conflict as a 3-way diff. A diff3 API has three parts, called: @@ -750,7 +751,8 @@ svn_wc__create_prejfile(const char **tmp apr_hash_t *conflicted_props; svn_skel_t *conflicts; - SVN_ERR(svn_wc__db_read_conflict(&conflicts, db, local_abspath, + SVN_ERR(svn_wc__db_read_conflict(&conflicts, NULL, NULL, + db, local_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_wc__conflict_read_info(&operation, NULL, NULL, NULL, NULL,
