aboutsummaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_wc
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2013-11-11 01:00:29 +0000
committerPeter Wemm <peter@FreeBSD.org>2013-11-11 01:00:29 +0000
commit6573976d8d3ffbe3d00487ebc8c11e3eb4033f17 (patch)
treec05673887167c7ecd55a62ed72830f5186f453c1 /subversion/libsvn_wc
parent97551b2898eb459e9b616947d87d026d27b61518 (diff)
downloadsrc-6573976d8d3ffbe3d00487ebc8c11e3eb4033f17.tar.gz
src-6573976d8d3ffbe3d00487ebc8c11e3eb4033f17.zip
Import svn-1.8.4, which includes fixes for both security and mergevendor/subversion/subversion-1.8.4
handling.
Notes
Notes: svn path=/vendor/subversion/dist/; revision=257934 svn path=/vendor/subversion/subversion-1.8.4/; revision=257935; tag=vendor/subversion/subversion-1.8.4
Diffstat (limited to 'subversion/libsvn_wc')
-rw-r--r--subversion/libsvn_wc/diff_editor.c12
-rw-r--r--subversion/libsvn_wc/diff_local.c24
-rw-r--r--subversion/libsvn_wc/info.c2
-rw-r--r--subversion/libsvn_wc/old-and-busted.c4
-rw-r--r--subversion/libsvn_wc/update_editor.c65
-rw-r--r--subversion/libsvn_wc/wc-checks.h2
-rw-r--r--subversion/libsvn_wc/wc-metadata.h2
-rw-r--r--subversion/libsvn_wc/wc-queries.h4
-rw-r--r--subversion/libsvn_wc/wc-queries.sql2
-rw-r--r--subversion/libsvn_wc/wc_db.c9
-rw-r--r--subversion/libsvn_wc/wc_db.h9
-rw-r--r--subversion/libsvn_wc/wc_db_private.h3
-rw-r--r--subversion/libsvn_wc/wc_db_update_move.c45
13 files changed, 127 insertions, 56 deletions
diff --git a/subversion/libsvn_wc/diff_editor.c b/subversion/libsvn_wc/diff_editor.c
index 839241f9db62..b4268843893b 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 ad87c76a6033..620630a53a63 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 4a37e00ab571..dc80ee72d27e 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 20f7c6ca9c7e..b87be85550bb 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 a353b1b07178..e02dc301637a 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 43ab4cc18ee1..8b55d430bb7a 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 d0421788d8ad..b92a04741a92 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 950f6257f9a2..d864ca3768d4 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 d5f7e82557f0..d275a7bada0a 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 e41165765d42..8b024c2f18eb 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 88e455fb51df..61906e3cb64f 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 0679b32e7e3a..e8f31d132374 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 a8cce76c0c0d..7f4f85399520 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);