diff options
author | peter <peter@FreeBSD.org> | 2013-11-11 01:00:29 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2013-11-11 01:00:29 +0000 |
commit | 68301b10e52aedbf076b5b08303439d75c192e18 (patch) | |
tree | c05673887167c7ecd55a62ed72830f5186f453c1 /subversion/libsvn_wc | |
parent | 3b9f7e96381479fb03ae2c36d490a38718f71083 (diff) | |
download | FreeBSD-src-68301b10e52aedbf076b5b08303439d75c192e18.zip FreeBSD-src-68301b10e52aedbf076b5b08303439d75c192e18.tar.gz |
Import svn-1.8.4, which includes fixes for both security and merge
handling.
Diffstat (limited to 'subversion/libsvn_wc')
-rw-r--r-- | subversion/libsvn_wc/diff_editor.c | 12 | ||||
-rw-r--r-- | subversion/libsvn_wc/diff_local.c | 24 | ||||
-rw-r--r-- | subversion/libsvn_wc/info.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_wc/old-and-busted.c | 4 | ||||
-rw-r--r-- | subversion/libsvn_wc/update_editor.c | 65 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc-checks.h | 2 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc-metadata.h | 2 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc-queries.h | 4 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc-queries.sql | 2 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc_db.c | 9 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc_db.h | 9 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc_db_private.h | 3 | ||||
-rw-r--r-- | subversion/libsvn_wc/wc_db_update_move.c | 45 |
13 files changed, 127 insertions, 56 deletions
diff --git a/subversion/libsvn_wc/diff_editor.c b/subversion/libsvn_wc/diff_editor.c index 839241f..b426884 100644 --- a/subversion/libsvn_wc/diff_editor.c +++ b/subversion/libsvn_wc/diff_editor.c @@ -474,14 +474,18 @@ svn_wc__diff_base_working_diff(svn_wc__db_t *db, { const svn_io_dirent2_t *dirent; + /* Verify truename to mimic status for iota/IOTA difference on Windows */ SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, - FALSE /* verify truename */, + TRUE /* verify truename */, TRUE /* ingore_enoent */, scratch_pool, scratch_pool)); - if (dirent->kind == svn_node_file - && dirent->filesize == recorded_size - && dirent->mtime == recorded_time) + /* If a file does not exist on disk (missing/obstructed) then we + can't provide a text diff */ + if (dirent->kind != svn_node_file + || (dirent->kind == svn_node_file + && dirent->filesize == recorded_size + && dirent->mtime == recorded_time)) { files_same = TRUE; } diff --git a/subversion/libsvn_wc/diff_local.c b/subversion/libsvn_wc/diff_local.c index ad87c76..620630a 100644 --- a/subversion/libsvn_wc/diff_local.c +++ b/subversion/libsvn_wc/diff_local.c @@ -195,23 +195,15 @@ diff_status_callback(void *baton, struct diff_baton *eb = baton; svn_wc__db_t *db = eb->db; - switch (status->node_status) - { - case svn_wc_status_unversioned: - case svn_wc_status_ignored: - return SVN_NO_ERROR; /* No diff */ - - case svn_wc_status_conflicted: - if (status->text_status == svn_wc_status_none - && status->prop_status == svn_wc_status_none) - { - /* Node is an actual only node describing a tree conflict */ - return SVN_NO_ERROR; - } - break; + if (! status->versioned) + return SVN_NO_ERROR; /* unversioned (includes dir externals) */ - default: - break; /* Go check other conditions */ + if (status->node_status == svn_wc_status_conflicted + && status->text_status == svn_wc_status_none + && status->prop_status == svn_wc_status_none) + { + /* Node is an actual only node describing a tree conflict */ + return SVN_NO_ERROR; } /* Not text/prop modified, not copied. Easy out */ diff --git a/subversion/libsvn_wc/info.c b/subversion/libsvn_wc/info.c index 4a37e00..dc80ee7 100644 --- a/subversion/libsvn_wc/info.c +++ b/subversion/libsvn_wc/info.c @@ -548,7 +548,7 @@ svn_wc__get_info(svn_wc_context_t *wc_ctx, &repos_uuid, wc_ctx->db, svn_dirent_dirname( - local_abspath, + this_abspath, iterpool), scratch_pool, iterpool)); diff --git a/subversion/libsvn_wc/old-and-busted.c b/subversion/libsvn_wc/old-and-busted.c index 20f7c6c..b87be85 100644 --- a/subversion/libsvn_wc/old-and-busted.c +++ b/subversion/libsvn_wc/old-and-busted.c @@ -811,11 +811,15 @@ atts_to_entry(svn_wc_entry_t **new_entry, ### not used by loggy; no need to set MODIFY_FLAGS */ entry->url = extract_string(atts, ENTRIES_ATTR_URL, pool); + if (entry->url) + entry->url = svn_uri_canonicalize(entry->url, pool); /* Set up repository root. Make sure it is a prefix of url. ### not used by loggy; no need to set MODIFY_FLAGS */ entry->repos = extract_string(atts, ENTRIES_ATTR_REPOS, pool); + if (entry->repos) + entry->repos = svn_uri_canonicalize(entry->repos, pool); if (entry->url && entry->repos && !svn_uri__is_ancestor(entry->repos, entry->url)) diff --git a/subversion/libsvn_wc/update_editor.c b/subversion/libsvn_wc/update_editor.c index a353b1b..e02dc30 100644 --- a/subversion/libsvn_wc/update_editor.c +++ b/subversion/libsvn_wc/update_editor.c @@ -1012,9 +1012,13 @@ window_handler(svn_txdelta_window_t *window, void *baton) if (err) { - /* We failed to apply the delta; clean up the temporary file. */ - svn_error_clear(svn_io_remove_file2(hb->new_text_base_tmp_abspath, TRUE, - hb->pool)); + /* We failed to apply the delta; clean up the temporary file if it + already created by lazy_open_target(). */ + if (hb->new_text_base_tmp_abspath) + { + svn_error_clear(svn_io_remove_file2(hb->new_text_base_tmp_abspath, + TRUE, hb->pool)); + } } else { @@ -3009,18 +3013,55 @@ absent_node(const char *path, kind = svn_node_unknown; } - if (status == svn_wc__db_status_normal - && kind == svn_node_dir) + if (status == svn_wc__db_status_normal) { - /* We found an obstructing working copy! + svn_boolean_t wcroot; + /* We found an obstructing working copy or a file external! */ - We can do two things now: - 1) notify the user, record a skip, etc. - 2) Just record the absent node in BASE in the parent - working copy. + SVN_ERR(svn_wc__db_is_wcroot(&wcroot, eb->db, local_abspath, + scratch_pool)); - As option 2 happens to be exactly what we do anyway, lets do that. - */ + if (wcroot) + { + /* + We have an obstructing working copy; possibly a directory external + + We can do two things now: + 1) notify the user, record a skip, etc. + 2) Just record the absent node in BASE in the parent + working copy. + + As option 2 happens to be exactly what we do anyway, fall through. + */ + } + else + { + /* The server asks us to replace a file external + (Existing BASE node; not reported by the working copy crawler or + there would have been a delete_entry() call. + + There is no way we can store this state in the working copy as + the BASE layer is already filled. + + We could error out, but that is not helping anybody; the user is not + even seeing with what the file external would be replaced, so let's + report a skip and continue the update. + */ + + if (eb->notify_func) + { + svn_wc_notify_t *notify; + notify = svn_wc_create_notify( + local_abspath, + svn_wc_notify_update_skip_obstruction, + scratch_pool); + + eb->notify_func(eb->notify_baton, notify, scratch_pool); + } + + svn_pool_destroy(scratch_pool); + return SVN_NO_ERROR; + } } else if (status == svn_wc__db_status_not_present || status == svn_wc__db_status_server_excluded diff --git a/subversion/libsvn_wc/wc-checks.h b/subversion/libsvn_wc/wc-checks.h index 43ab4cc..8b55d43 100644 --- a/subversion/libsvn_wc/wc-checks.h +++ b/subversion/libsvn_wc/wc-checks.h @@ -1,4 +1,4 @@ -/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.8.1/subversion/libsvn_wc/token-map.h. +/* This file is automatically generated from wc-checks.sql and .dist_sandbox/subversion-1.8.4/subversion/libsvn_wc/token-map.h. * Do not edit this file -- edit the source and rerun gen-make.py */ #define STMT_VERIFICATION_TRIGGERS 0 diff --git a/subversion/libsvn_wc/wc-metadata.h b/subversion/libsvn_wc/wc-metadata.h index d042178..b92a0474 100644 --- a/subversion/libsvn_wc/wc-metadata.h +++ b/subversion/libsvn_wc/wc-metadata.h @@ -1,4 +1,4 @@ -/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.8.1/subversion/libsvn_wc/token-map.h. +/* This file is automatically generated from wc-metadata.sql and .dist_sandbox/subversion-1.8.4/subversion/libsvn_wc/token-map.h. * Do not edit this file -- edit the source and rerun gen-make.py */ #define STMT_CREATE_SCHEMA 0 diff --git a/subversion/libsvn_wc/wc-queries.h b/subversion/libsvn_wc/wc-queries.h index 950f625..d864ca3 100644 --- a/subversion/libsvn_wc/wc-queries.h +++ b/subversion/libsvn_wc/wc-queries.h @@ -1,4 +1,4 @@ -/* This file is automatically generated from wc-queries.sql and .dist_sandbox/subversion-1.8.1/subversion/libsvn_wc/token-map.h. +/* This file is automatically generated from wc-queries.sql and .dist_sandbox/subversion-1.8.4/subversion/libsvn_wc/token-map.h. * Do not edit this file -- edit the source and rerun gen-make.py */ #define STMT_SELECT_NODE_INFO 0 @@ -2000,7 +2000,7 @@ #define STMT_SELECT_MOVED_OUTSIDE 191 #define STMT_191_INFO {"STMT_SELECT_MOVED_OUTSIDE", NULL} #define STMT_191 \ - "SELECT local_relpath, moved_to FROM nodes " \ + "SELECT local_relpath, moved_to, op_depth FROM nodes " \ "WHERE wc_id = ?1 " \ " AND (local_relpath = ?2 OR (((local_relpath) > (CASE (?2) WHEN '' THEN '' ELSE (?2) || '/' END)) AND ((local_relpath) < CASE (?2) WHEN '' THEN X'FFFF' ELSE (?2) || '0' END))) " \ " AND op_depth >= ?3 " \ diff --git a/subversion/libsvn_wc/wc-queries.sql b/subversion/libsvn_wc/wc-queries.sql index d5f7e82..d275a7b 100644 --- a/subversion/libsvn_wc/wc-queries.sql +++ b/subversion/libsvn_wc/wc-queries.sql @@ -1571,7 +1571,7 @@ WHERE wc_id = ?1 AND moved_to IS NOT NULL -- STMT_SELECT_MOVED_OUTSIDE -SELECT local_relpath, moved_to FROM nodes +SELECT local_relpath, moved_to, op_depth FROM nodes WHERE wc_id = ?1 AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2)) AND op_depth >= ?3 diff --git a/subversion/libsvn_wc/wc_db.c b/subversion/libsvn_wc/wc_db.c index e411657..8b024c2 100644 --- a/subversion/libsvn_wc/wc_db.c +++ b/subversion/libsvn_wc/wc_db.c @@ -2248,6 +2248,12 @@ db_base_remove(svn_wc__db_wcroot_t *wcroot, * might introduce actual-only nodes without direct parents, * and we're not yet sure if other existing code is prepared * to handle such nodes. To be revisited post-1.8. + * + * ### In case of a conflict we are most likely creating WORKING nodes + * describing a copy of what was in BASE. The move information + * should be updated to describe a move from the WORKING layer. + * When stored that way the resolver of the tree conflict still has + * the knowledge of what was moved. */ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_MOVED_OUTSIDE)); @@ -6388,6 +6394,7 @@ op_revert_txn(void *baton, { SVN_ERR(svn_wc__db_resolve_break_moved_away_internal(wcroot, local_relpath, + op_depth, scratch_pool)); } else @@ -6554,10 +6561,12 @@ op_revert_recursive_txn(void *baton, while (have_row) { const char *move_src_relpath = svn_sqlite__column_text(stmt, 0, NULL); + int move_op_depth = svn_sqlite__column_int(stmt, 2); svn_error_t *err; err = svn_wc__db_resolve_break_moved_away_internal(wcroot, move_src_relpath, + move_op_depth, scratch_pool); if (err) return svn_error_compose_create(err, svn_sqlite__reset(stmt)); diff --git a/subversion/libsvn_wc/wc_db.h b/subversion/libsvn_wc/wc_db.h index 88e455f..61906e3 100644 --- a/subversion/libsvn_wc/wc_db.h +++ b/subversion/libsvn_wc/wc_db.h @@ -3382,7 +3382,14 @@ svn_wc__db_resolve_delete_raise_moved_away(svn_wc__db_t *db, apr_pool_t *scratch_pool); /* Like svn_wc__db_resolve_delete_raise_moved_away this should be - combined. */ + combined. + + ### LOCAL_ABSPATH specifies the move origin, but the move origin + ### is not necessary unique enough. This function needs an op_root_abspath + ### argument to differentiate between different origins. + + ### See move_tests.py: move_many_update_delete for an example case. + */ svn_error_t * svn_wc__db_resolve_break_moved_away(svn_wc__db_t *db, const char *local_abspath, diff --git a/subversion/libsvn_wc/wc_db_private.h b/subversion/libsvn_wc/wc_db_private.h index 0679b32..e8f31d1 100644 --- a/subversion/libsvn_wc/wc_db_private.h +++ b/subversion/libsvn_wc/wc_db_private.h @@ -442,9 +442,12 @@ svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot, svn_wc__db_t *db, apr_pool_t *scratch_pool); +/* Unbreak the move from LOCAL_RELPATH on op-depth in WCROOT, by making + the destination a normal copy */ svn_error_t * svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot, const char *local_relpath, + int op_depth, apr_pool_t *scratch_pool); svn_error_t * diff --git a/subversion/libsvn_wc/wc_db_update_move.c b/subversion/libsvn_wc/wc_db_update_move.c index a8cce76..7f4f853 100644 --- a/subversion/libsvn_wc/wc_db_update_move.c +++ b/subversion/libsvn_wc/wc_db_update_move.c @@ -2284,30 +2284,34 @@ svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot, svn_wc__db_t *db, apr_pool_t *scratch_pool) { - const char *dummy1, *move_dst_op_root_relpath; - const char *move_src_root_relpath, *move_src_op_root_relpath; apr_hash_t *src_done; SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb, STMT_CREATE_UPDATE_MOVE_LIST)); - SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath, - &move_src_root_relpath, - &move_src_op_root_relpath, 0, - wcroot, local_relpath, - scratch_pool, scratch_pool)); - - if (move_src_root_relpath) + if (local_relpath[0] != '\0') { - if (strcmp(move_src_root_relpath, local_relpath)) + const char *dummy1, *move_dst_op_root_relpath; + const char *move_src_root_relpath, *move_src_op_root_relpath; + + /* Is the root of the update moved away? (Impossible for the wcroot) */ + SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath, + &move_src_root_relpath, + &move_src_op_root_relpath, 0, + wcroot, local_relpath, + scratch_pool, scratch_pool)); + + if (move_src_root_relpath) { - SVN_ERR(bump_mark_tree_conflict(wcroot, move_src_root_relpath, - move_src_op_root_relpath, - move_dst_op_root_relpath, - db, scratch_pool)); - return SVN_NO_ERROR; + if (strcmp(move_src_root_relpath, local_relpath)) + { + SVN_ERR(bump_mark_tree_conflict(wcroot, move_src_root_relpath, + move_src_op_root_relpath, + move_dst_op_root_relpath, + db, scratch_pool)); + return SVN_NO_ERROR; + } } - } src_done = apr_hash_make(scratch_pool); @@ -2440,17 +2444,23 @@ break_move(svn_wc__db_wcroot_t *wcroot, svn_error_t * svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot, const char *local_relpath, + int op_depth, apr_pool_t *scratch_pool) { const char *dummy1, *move_dst_op_root_relpath; const char *dummy2, *move_src_op_root_relpath; + /* We want to include the passed op-depth, but the function does a > check */ SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath, &dummy2, &move_src_op_root_relpath, - relpath_depth(local_relpath) - 1, + op_depth - 1, wcroot, local_relpath, scratch_pool, scratch_pool)); + + SVN_ERR_ASSERT(move_src_op_root_relpath != NULL + && move_dst_op_root_relpath != NULL); + SVN_ERR(break_move(wcroot, local_relpath, relpath_depth(move_src_op_root_relpath), move_dst_op_root_relpath, @@ -2519,6 +2529,7 @@ svn_wc__db_resolve_break_moved_away(svn_wc__db_t *db, SVN_WC__DB_WITH_TXN( svn_wc__db_resolve_break_moved_away_internal(wcroot, local_relpath, + relpath_depth(local_relpath), scratch_pool), wcroot); |