Author: brane
Date: Fri Feb 6 20:18:23 2015
New Revision: 1657947
URL: http://svn.apache.org/r1657947
Log:
On the reuse-ra-session branch: Sync with trunk up to r1657945.
Modified:
subversion/branches/reuse-ra-session/ (props changed)
subversion/branches/reuse-ra-session/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
subversion/branches/reuse-ra-session/subversion/libsvn_fs/fs-loader.h
subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/lock.c
subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/ (props
changed)
subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/dag.c
subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/revprops.c
subversion/branches/reuse-ra-session/subversion/libsvn_repos/hooks.c
subversion/branches/reuse-ra-session/subversion/libsvn_subr/cache-membuffer.c
subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c
subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc-queries.sql
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.c
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.h
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db_private.h
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db_update_move.c
subversion/branches/reuse-ra-session/subversion/svn/conflict-callbacks.c
subversion/branches/reuse-ra-session/subversion/svn/notify.c
subversion/branches/reuse-ra-session/subversion/tests/cmdline/externals_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/info_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/log_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/move_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/schedule_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svnadmin_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svndumpfilter_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svnrdump_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svnsync_authz_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svnsync_tests.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/actions.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/main.py
subversion/branches/reuse-ra-session/subversion/tests/cmdline/svntest/sandbox.py
subversion/branches/reuse-ra-session/subversion/tests/libsvn_fs/locks-test.c
subversion/branches/reuse-ra-session/subversion/tests/libsvn_repos/repos-test.c
subversion/branches/reuse-ra-session/subversion/tests/libsvn_wc/op-depth-test.c
Propchange: subversion/branches/reuse-ra-session/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Feb 6 20:18:23 2015
@@ -87,4 +87,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1501802-1657454
+/subversion/trunk:1501802-1657945
Modified:
subversion/branches/reuse-ra-session/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
---
subversion/branches/reuse-ra-session/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
(original)
+++
subversion/branches/reuse-ra-session/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
Fri Feb 6 20:18:23 2015
@@ -94,8 +94,8 @@ public:
/**
* Create a message object given an error code and error message.
*/
- Message(int errno, const std::string& message)
- : m_errno(errno),
+ Message(int errval, const std::string& message)
+ : m_errno(errval),
m_message(message),
m_trace(false)
{}
@@ -104,8 +104,8 @@ public:
* Create a message object given an error code and error message,
* and set the flag that tells if this is a debugging traceback entry.
*/
- Message(int errno, const std::string& message, bool trace)
- : m_errno(errno),
+ Message(int errval, const std::string& message, bool trace)
+ : m_errno(errval),
m_message(message),
m_trace(trace)
{}
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs/fs-loader.h
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs/fs-loader.h?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs/fs-loader.h
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs/fs-loader.h Fri
Feb 6 20:18:23 2015
@@ -548,7 +548,8 @@ struct svn_fs_access_t
const char *username;
/* A collection of lock-tokens supplied by the fs caller.
- Hash maps (const char *) UUID --> (void *) 1
+ Hash maps (const char *) UUID --> path where path can be the
+ magic value (void *) 1 if no path was specified.
fs functions should really only be interested whether a UUID
exists as a hash key at all; the value is irrelevant. */
apr_hash_t *lock_tokens;
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/lock.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/lock.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/lock.c
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_fs/lock.c Fri Feb
6 20:18:23 2015
@@ -853,9 +853,6 @@ lock_body(void *baton, apr_pool_t *pool)
int i, outstanding = 0;
apr_pool_t *iterpool = svn_pool_create(pool);
- lb->infos = apr_array_make(lb->result_pool, lb->targets->nelts,
- sizeof(struct lock_info_t));
-
/* Until we implement directory locks someday, we only allow locks
on files or non-existent paths. */
/* Use fs->vtable->foo instead of svn_fs_foo to avoid circular
@@ -1056,9 +1053,6 @@ unlock_body(void *baton, apr_pool_t *poo
int i, max_components = 0, outstanding = 0;
apr_pool_t *iterpool = svn_pool_create(pool);
- ub->infos = apr_array_make(ub->result_pool, ub->targets->nelts,
- sizeof(struct unlock_info_t));
-
SVN_ERR(ub->fs->vtable->youngest_rev(&youngest, ub->fs, pool));
SVN_ERR(ub->fs->vtable->revision_root(&root, ub->fs, youngest, pool));
@@ -1180,6 +1174,8 @@ unlock_single(svn_fs_t *fs,
ub.fs = fs;
ub.targets = targets;
+ ub.infos = apr_array_make(pool, targets->nelts,
+ sizeof(struct unlock_info_t));
ub.skip_check = TRUE;
ub.result_pool = pool;
@@ -1240,6 +1236,8 @@ svn_fs_fs__lock(svn_fs_t *fs,
lb.fs = fs;
lb.targets = sorted_targets;
+ lb.infos = apr_array_make(result_pool, sorted_targets->nelts,
+ sizeof(struct lock_info_t));
lb.comment = comment;
lb.is_dav_comment = is_dav_comment;
lb.expiration_date = expiration_date;
@@ -1330,6 +1328,8 @@ svn_fs_fs__unlock(svn_fs_t *fs,
ub.fs = fs;
ub.targets = sorted_targets;
+ ub.infos = apr_array_make(result_pool, sorted_targets->nelts,
+ sizeof(struct unlock_info_t));
ub.skip_check = FALSE;
ub.break_lock = break_lock;
ub.result_pool = result_pool;
Propchange: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Feb 6 20:18:23 2015
@@ -89,4 +89,4 @@
/subversion/branches/verify-keep-going/subversion/libsvn_fs_x:1439280-1492639,1546002-1546110
/subversion/branches/wc-collate-path/subversion/libsvn_fs_x:1402685-1480384
/subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1653608
-/subversion/trunk/subversion/libsvn_fs_x:1414756-1657328
+/subversion/trunk/subversion/libsvn_fs_x:1414756-1657945
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/dag.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/dag.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/dag.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/dag.c Fri Feb
6 20:18:23 2015
@@ -376,6 +376,12 @@ dir_entry_id_from_node(svn_fs_x__id_t *i
return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
_("Can't get entries of non-directory"));
+ /* Make sure that NAME is a single path component. */
+ if (! svn_path_is_single_path_component(name))
+ return svn_error_createf
+ (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL,
+ "Attempted to open node with an illegal name '%s'", name);
+
/* Get a dirent hash for this directory. */
SVN_ERR(svn_fs_x__rep_contents_dir_entry(&dirent, parent->fs, noderev,
name, &parent->hint,
@@ -1193,12 +1199,6 @@ svn_fs_x__dag_open(dag_node_t **child_p,
return SVN_NO_ERROR;
}
- /* Make sure that NAME is a single path component. */
- if (! svn_path_is_single_path_component(name))
- return svn_error_createf
- (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL,
- "Attempted to open node with an illegal name '%s'", name);
-
/* Now get the node that was requested. */
return svn_fs_x__dag_get_node(child_p, svn_fs_x__dag_get_fs(parent),
&node_id, result_pool, scratch_pool);
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/revprops.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/revprops.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/revprops.c
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_fs_x/revprops.c Fri
Feb 6 20:18:23 2015
@@ -1166,7 +1166,8 @@ svn_fs_x__get_revision_proplist(apr_hash
* file in *TMP_PATH and the file path that it must be moved to in
* *FINAL_PATH.
*
- * Use POOL for allocations.
+ * Allocate *FINAL_PATH and *TMP_PATH in RESULT_POOL. Use SCRATCH_POOL
+ * for temporary allocations.
*/
static svn_error_t *
write_non_packed_revprop(const char **final_path,
@@ -1174,17 +1175,21 @@ write_non_packed_revprop(const char **fi
svn_fs_t *fs,
svn_revnum_t rev,
apr_hash_t *proplist,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_stream_t *stream;
- *final_path = svn_fs_x__path_revprops(fs, rev, pool);
+ *final_path = svn_fs_x__path_revprops(fs, rev, result_pool);
/* ### do we have a directory sitting around already? we really shouldn't
### have to get the dirname here. */
SVN_ERR(svn_stream_open_unique(&stream, tmp_path,
- svn_dirent_dirname(*final_path, pool),
- svn_io_file_del_none, pool, pool));
- SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, pool));
+ svn_dirent_dirname(*final_path,
+ scratch_pool),
+ svn_io_file_del_none,
+ result_pool, scratch_pool));
+ SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR,
+ scratch_pool));
SVN_ERR(svn_stream_close(stream));
return SVN_NO_ERROR;
@@ -1360,7 +1365,10 @@ repack_revprops(svn_fs_t *fs,
* [REVPROPS->START_REVISION + START, REVPROPS->START_REVISION + END - 1]
* of REVPROPS->MANIFEST. Add the name of old file to FILES_TO_DELETE,
* auto-create that array if necessary. Return an open file stream to
- * the new file in *STREAM allocated in POOL.
+ * the new file in *STREAM allocated in RESULT_POOL. Allocate the paths
+ * in *FILES_TO_DELETE from the same pool that contains the array itself.
+ *
+ * Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
repack_stream_open(svn_stream_t **stream,
@@ -1369,7 +1377,8 @@ repack_stream_open(svn_stream_t **stream
int start,
int end,
apr_array_header_t **files_to_delete,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_int64_t tag;
const char *tag_string;
@@ -1385,10 +1394,11 @@ repack_stream_open(svn_stream_t **stream
const char*);
if (*files_to_delete == NULL)
- *files_to_delete = apr_array_make(pool, 3, sizeof(const char*));
+ *files_to_delete = apr_array_make(result_pool, 3, sizeof(const char*));
APR_ARRAY_PUSH(*files_to_delete, const char*)
- = svn_dirent_join(revprops->folder, old_filename, pool);
+ = svn_dirent_join(revprops->folder, old_filename,
+ (*files_to_delete)->pool);
/* increase the tag part, i.e. the counter after the dot */
tag_string = strchr(old_filename, '.');
@@ -1398,7 +1408,8 @@ repack_stream_open(svn_stream_t **stream
old_filename);
SVN_ERR(svn_cstring_atoi64(&tag, tag_string + 1));
- new_filename = svn_string_createf(pool, "%ld.%" APR_INT64_T_FMT,
+ new_filename = svn_string_createf((*files_to_delete)->pool,
+ "%ld.%" APR_INT64_T_FMT,
revprops->start_revision + start,
++tag);
@@ -1410,9 +1421,10 @@ repack_stream_open(svn_stream_t **stream
/* create a file stream for the new file */
SVN_ERR(svn_io_file_open(&file, svn_dirent_join(revprops->folder,
new_filename->data,
- pool),
- APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));
- *stream = svn_stream_from_aprfile2(file, FALSE, pool);
+ scratch_pool),
+ APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
+ result_pool));
+ *stream = svn_stream_from_aprfile2(file, FALSE, result_pool);
return SVN_NO_ERROR;
}
@@ -1421,7 +1433,8 @@ repack_stream_open(svn_stream_t **stream
* PROPLIST. Return a new file in *TMP_PATH that the caller shall move
* to *FINAL_PATH to make the change visible. Files to be deleted will
* be listed in *FILES_TO_DELETE which may remain unchanged / unallocated.
- * Use POOL for allocations.
+ *
+ * Allocate output values in RESULT_POOL and temporaries from SCRATCH_POOL.
*/
static svn_error_t *
write_packed_revprop(const char **final_path,
@@ -1430,7 +1443,8 @@ write_packed_revprop(const char **final_
svn_fs_t *fs,
svn_revnum_t rev,
apr_hash_t *proplist,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_fs_x__data_t *ffd = fs->fsap_data;
packed_revprops_t *revprops;
@@ -1442,17 +1456,18 @@ write_packed_revprop(const char **final_
/* read the current revprop generation. This value will not change
* while we hold the global write lock to this FS. */
- if (has_revprop_cache(fs, pool))
- SVN_ERR(read_revprop_generation(&generation, fs, pool));
+ if (has_revprop_cache(fs, scratch_pool))
+ SVN_ERR(read_revprop_generation(&generation, fs, scratch_pool));
/* read contents of the current pack file */
- SVN_ERR(read_pack_revprop(&revprops, fs, rev, generation, TRUE, pool,
- pool));
+ SVN_ERR(read_pack_revprop(&revprops, fs, rev, generation, TRUE,
+ scratch_pool, scratch_pool));
/* serialize the new revprops */
- serialized = svn_stringbuf_create_empty(pool);
- stream = svn_stream_from_stringbuf(serialized, pool);
- SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, pool));
+ serialized = svn_stringbuf_create_empty(scratch_pool);
+ stream = svn_stream_from_stringbuf(serialized, scratch_pool);
+ SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR,
+ scratch_pool));
SVN_ERR(svn_stream_close(stream));
/* calculate the size of the new data */
@@ -1471,12 +1486,13 @@ write_packed_revprop(const char **final_
* in the non-packed case */
*final_path = svn_dirent_join(revprops->folder, revprops->filename,
- pool);
+ result_pool);
SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
- svn_io_file_del_none, pool, pool));
+ svn_io_file_del_none, result_pool,
+ scratch_pool));
SVN_ERR(repack_revprops(fs, revprops, 0, revprops->sizes->nelts,
changed_index, serialized, new_total_size,
- stream, pool));
+ stream, scratch_pool));
}
else
{
@@ -1519,25 +1535,32 @@ write_packed_revprop(const char **final_
right_count = revprops->sizes->nelts - left_count - 1;
}
+ /* Allocate this here such that we can call the repack functions with
+ * the scratch pool alone. */
+ if (*files_to_delete == NULL)
+ *files_to_delete = apr_array_make(result_pool, 3,
+ sizeof(const char*));
+
/* write the new, split files */
if (left_count)
{
SVN_ERR(repack_stream_open(&stream, fs, revprops, 0,
- left_count, files_to_delete, pool));
+ left_count, files_to_delete,
+ scratch_pool, scratch_pool));
SVN_ERR(repack_revprops(fs, revprops, 0, left_count,
changed_index, serialized, new_total_size,
- stream, pool));
+ stream, scratch_pool));
}
if (left_count + right_count < revprops->sizes->nelts)
{
SVN_ERR(repack_stream_open(&stream, fs, revprops, changed_index,
changed_index + 1, files_to_delete,
- pool));
+ scratch_pool, scratch_pool));
SVN_ERR(repack_revprops(fs, revprops, changed_index,
changed_index + 1,
changed_index, serialized, new_total_size,
- stream, pool));
+ stream, scratch_pool));
}
if (right_count)
@@ -1545,24 +1568,27 @@ write_packed_revprop(const char **final_
SVN_ERR(repack_stream_open(&stream, fs, revprops,
revprops->sizes->nelts - right_count,
revprops->sizes->nelts,
- files_to_delete, pool));
+ files_to_delete, scratch_pool,
+ scratch_pool));
SVN_ERR(repack_revprops(fs, revprops,
revprops->sizes->nelts - right_count,
revprops->sizes->nelts, changed_index,
serialized, new_total_size, stream,
- pool));
+ scratch_pool));
}
/* write the new manifest */
- *final_path = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool);
+ *final_path = svn_dirent_join(revprops->folder, PATH_MANIFEST,
+ result_pool);
SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
- svn_io_file_del_none, pool, pool));
+ svn_io_file_del_none, result_pool,
+ scratch_pool));
for (i = 0; i < revprops->manifest->nelts; ++i)
{
const char *filename = APR_ARRAY_IDX(revprops->manifest, i,
const char*);
- SVN_ERR(svn_stream_printf(stream, pool, "%s\n", filename));
+ SVN_ERR(svn_stream_printf(stream, scratch_pool, "%s\n", filename));
}
SVN_ERR(svn_stream_close(stream));
@@ -1610,10 +1636,12 @@ svn_fs_x__set_revision_proplist(svn_fs_t
/* Serialize the new revprop data */
if (is_packed)
SVN_ERR(write_packed_revprop(&final_path, &tmp_path, &files_to_delete,
- fs, rev, proplist, scratch_pool));
+ fs, rev, proplist, scratch_pool,
+ scratch_pool));
else
SVN_ERR(write_non_packed_revprop(&final_path, &tmp_path,
- fs, rev, proplist, scratch_pool));
+ fs, rev, proplist, scratch_pool,
+ scratch_pool));
/* We use the rev file of this revision as the perms reference,
* because when setting revprops for the first time, the revprop
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_repos/hooks.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_repos/hooks.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_repos/hooks.c
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_repos/hooks.c Fri
Feb 6 20:18:23 2015
@@ -522,10 +522,19 @@ lock_token_content(apr_file_t **handle,
const char *token = apr_hash_this_key(hi);
const char *path = apr_hash_this_val(hi);
+ if (path == (const char *) 1)
+ {
+ /* Special handling for svn_fs_access_t * created by using deprecated
+ svn_fs_access_add_lock_token() function. */
+ path = "";
+ }
+ else
+ {
+ path = svn_path_uri_autoescape(path, pool);
+ }
+
svn_stringbuf_appendstr(lock_str,
- svn_stringbuf_createf(pool, "%s|%s\n",
- svn_path_uri_autoescape(path, pool),
- token));
+ svn_stringbuf_createf(pool, "%s|%s\n", path, token));
}
svn_stringbuf_appendcstr(lock_str, "\n");
Modified:
subversion/branches/reuse-ra-session/subversion/libsvn_subr/cache-membuffer.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/cache-membuffer.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
---
subversion/branches/reuse-ra-session/subversion/libsvn_subr/cache-membuffer.c
(original)
+++
subversion/branches/reuse-ra-session/subversion/libsvn_subr/cache-membuffer.c
Fri Feb 6 20:18:23 2015
@@ -123,7 +123,7 @@
* Use a simple mutex on Windows. Because there is one mutex per segment,
* large machines should (and usually can) be configured with large caches
* such that read contention is kept low. This is basically the situation
- * we head before 1.8.
+ * we had before 1.8.
*/
#ifdef WIN32
# define USE_SIMPLE_MUTEX 1
@@ -587,16 +587,15 @@ struct svn_membuffer_t
*/
apr_uint64_t total_hits;
-#if APR_HAS_THREADS
+#if (APR_HAS_THREADS && USE_SIMPLE_MUTEX)
/* A lock for intra-process synchronization to the cache, or NULL if
* the cache's creator doesn't feel the cache needs to be
* thread-safe.
*/
-# if USE_SIMPLE_MUTEX
svn_mutex__t *lock;
-# else
+#elif (APR_HAS_THREADS && !USE_SIMPLE_MUTEX)
+ /* Same for read-write lock. */
apr_thread_rwlock_t *lock;
-# endif
/* If set, write access will wait until they get exclusive access.
* Otherwise, they will become no-ops if the segment is currently
@@ -619,33 +618,32 @@ struct svn_membuffer_t
static svn_error_t *
read_lock_cache(svn_membuffer_t *cache)
{
-#if APR_HAS_THREADS
-# if USE_SIMPLE_MUTEX
+#if (APR_HAS_THREADS && USE_SIMPLE_MUTEX)
return svn_mutex__lock(cache->lock);
-# else
+#elif (APR_HAS_THREADS && !USE_SIMPLE_MUTEX)
if (cache->lock)
{
apr_status_t status = apr_thread_rwlock_rdlock(cache->lock);
if (status)
return svn_error_wrap_apr(status, _("Can't lock cache mutex"));
}
-# endif
-#endif
+
+ return SVN_NO_ERROR;
+#else
return SVN_NO_ERROR;
+#endif
}
/* If locking is supported for CACHE, acquire a write lock for it.
+ * Set *SUCCESS to FALSE, if we couldn't acquire the write lock;
+ * leave it untouched otherwise.
*/
static svn_error_t *
write_lock_cache(svn_membuffer_t *cache, svn_boolean_t *success)
{
-#if APR_HAS_THREADS
-# if USE_SIMPLE_MUTEX
-
+#if (APR_HAS_THREADS && USE_SIMPLE_MUTEX)
return svn_mutex__lock(cache->lock);
-
-# else
-
+#elif (APR_HAS_THREADS && !USE_SIMPLE_MUTEX)
if (cache->lock)
{
apr_status_t status;
@@ -668,9 +666,10 @@ write_lock_cache(svn_membuffer_t *cache,
_("Can't write-lock cache mutex"));
}
-# endif
-#endif
return SVN_NO_ERROR;
+#else
+ return SVN_NO_ERROR;
+#endif
}
/* If locking is supported for CACHE, acquire an unconditional write lock
@@ -679,36 +678,29 @@ write_lock_cache(svn_membuffer_t *cache,
static svn_error_t *
force_write_lock_cache(svn_membuffer_t *cache)
{
-#if APR_HAS_THREADS
-# if USE_SIMPLE_MUTEX
-
+#if (APR_HAS_THREADS && USE_SIMPLE_MUTEX)
return svn_mutex__lock(cache->lock);
-
-# else
-
+#elif (APR_HAS_THREADS && !USE_SIMPLE_MUTEX)
apr_status_t status = apr_thread_rwlock_wrlock(cache->lock);
if (status)
return svn_error_wrap_apr(status,
_("Can't write-lock cache mutex"));
-# endif
-#endif
return SVN_NO_ERROR;
+#else
+ return SVN_NO_ERROR;
+#endif
}
/* If locking is supported for CACHE, release the current lock
- * (read or write).
+ * (read or write). Return ERR upon success.
*/
static svn_error_t *
unlock_cache(svn_membuffer_t *cache, svn_error_t *err)
{
-#if APR_HAS_THREADS
-# if USE_SIMPLE_MUTEX
-
+#if (APR_HAS_THREADS && USE_SIMPLE_MUTEX)
return svn_mutex__unlock(cache->lock, err);
-
-# else
-
+#elif (APR_HAS_THREADS && !USE_SIMPLE_MUTEX)
if (cache->lock)
{
apr_status_t status = apr_thread_rwlock_unlock(cache->lock);
@@ -719,13 +711,14 @@ unlock_cache(svn_membuffer_t *cache, svn
return svn_error_wrap_apr(status, _("Can't unlock cache mutex"));
}
-# endif
-#endif
return err;
+#else
+ return err;
+#endif
}
-/* If supported, guard the execution of EXPR with a read lock to cache.
- * Macro has been modeled after SVN_MUTEX__WITH_LOCK.
+/* If supported, guard the execution of EXPR with a read lock to CACHE.
+ * The macro has been modeled after SVN_MUTEX__WITH_LOCK.
*/
#define WITH_READ_LOCK(cache, expr) \
do { \
@@ -733,8 +726,8 @@ do {
SVN_ERR(unlock_cache(cache, (expr))); \
} while (0)
-/* If supported, guard the execution of EXPR with a write lock to cache.
- * Macro has been modeled after SVN_MUTEX__WITH_LOCK.
+/* If supported, guard the execution of EXPR with a write lock to CACHE.
+ * The macro has been modeled after SVN_MUTEX__WITH_LOCK.
*
* The write lock process is complicated if we don't allow to wait for
* the lock: If we didn't get the lock, we may still need to remove an
@@ -1797,17 +1790,14 @@ svn_cache__membuffer_cache_create(svn_me
return svn_error_wrap_apr(APR_ENOMEM, "OOM");
}
-#if APR_HAS_THREADS
+#if (APR_HAS_THREADS && USE_SIMPLE_MUTEX)
/* A lock for intra-process synchronization to the cache, or NULL if
* the cache's creator doesn't feel the cache needs to be
* thread-safe.
*/
-# if USE_SIMPLE_MUTEX
-
SVN_ERR(svn_mutex__init(&c[seg].lock, thread_safe, pool));
-
-# else
-
+#elif (APR_HAS_THREADS && !USE_SIMPLE_MUTEX)
+ /* Same for read-write lock. */
c[seg].lock = NULL;
if (thread_safe)
{
@@ -1817,8 +1807,6 @@ svn_cache__membuffer_cache_create(svn_me
return svn_error_wrap_apr(status, _("Can't create cache mutex"));
}
-# endif
-
/* Select the behavior of write operations.
*/
c[seg].allow_blocking_writes = allow_blocking_writes;
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/io.c Fri Feb 6
20:18:23 2015
@@ -352,6 +352,25 @@ file_open(apr_file_t **f,
if (retry_on_failure)
{
+#ifdef WIN32
+ if (status == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED))
+ {
+ if ((flag & (APR_CREATE | APR_EXCL)) == (APR_CREATE | APR_EXCL))
+ return status; /* Can't create if there is something */
+
+ if (flag & (APR_WRITE | APR_CREATE))
+ {
+ apr_finfo_t finfo;
+
+ if (!apr_stat(&finfo, fname_apr, SVN__APR_FINFO_READONLY, pool))
+ {
+ if (finfo.protection & APR_FREADONLY)
+ return status; /* Retrying won't fix this */
+ }
+ }
+ }
+#endif
+
WIN32_RETRY_LOOP(status, apr_file_open(f, fname_apr, flag, perm, pool));
}
return status;
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/copy.c Fri Feb 6
20:18:23 2015
@@ -42,6 +42,7 @@
#include "svn_private_config.h"
#include "private/svn_wc_private.h"
+/* #define RECORD_MIXED_MOVE */
/*** Code. ***/
@@ -567,10 +568,10 @@ copy_versioned_dir(svn_wc__db_t *db,
* The additional parameter IS_MOVE indicates whether this is a copy or
* a move operation.
*
- * If MOVE_DEGRADED_TO_COPY is not NULL and a move had to be degraded
- * to a copy, then set *MOVE_DEGRADED_TO_COPY. */
+ * If RECORD_MOVE_ON_DELETE is not NULL and a move had to be degraded
+ * to a copy, then set *RECORD_MOVE_ON_DELETE to FALSE. */
static svn_error_t *
-copy_or_move(svn_boolean_t *move_degraded_to_copy,
+copy_or_move(svn_boolean_t *record_move_on_delete,
svn_wc_context_t *wc_ctx,
const char *src_abspath,
const char *dst_abspath,
@@ -820,8 +821,8 @@ copy_or_move(svn_boolean_t *move_degrade
if (is_move
&& !within_one_wc)
{
- if (move_degraded_to_copy)
- *move_degraded_to_copy = TRUE;
+ if (record_move_on_delete)
+ *record_move_on_delete = FALSE;
is_move = FALSE;
}
@@ -865,9 +866,11 @@ copy_or_move(svn_boolean_t *move_degrade
scratch_pool),
min_rev, max_rev);
+#ifndef RECORD_MIXED_MOVE
is_move = FALSE;
- if (move_degraded_to_copy)
- *move_degraded_to_copy = TRUE;
+ if (record_move_on_delete)
+ *record_move_on_delete = FALSE;
+#endif
}
}
@@ -1054,7 +1057,7 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
apr_pool_t *scratch_pool)
{
svn_wc__db_t *db = wc_ctx->db;
- svn_boolean_t move_degraded_to_copy = FALSE;
+ svn_boolean_t record_on_delete = TRUE;
svn_node_kind_t kind;
svn_boolean_t conflicted;
@@ -1066,7 +1069,7 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
svn_dirent_dirname(dst_abspath, scratch_pool),
scratch_pool));
- SVN_ERR(copy_or_move(&move_degraded_to_copy,
+ SVN_ERR(copy_or_move(&record_on_delete,
wc_ctx, src_abspath, dst_abspath,
TRUE /* metadata_only */,
TRUE /* is_move */,
@@ -1109,7 +1112,7 @@ svn_wc__move2(svn_wc_context_t *wc_ctx,
scratch_pool));
SVN_ERR(svn_wc__db_op_delete(db, src_abspath,
- move_degraded_to_copy ? NULL : dst_abspath,
+ record_on_delete ? dst_abspath : NULL,
TRUE /* delete_dir_externals */,
NULL /* conflict */, NULL /* work_items */,
cancel_func, cancel_baton,
Modified:
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc-queries.sql?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc-queries.sql
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc-queries.sql
Fri Feb 6 20:18:23 2015
@@ -257,30 +257,35 @@ WHERE wc_id = ?1
AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
AND op_depth = ?3
--- STMT_DELETE_WORKING_OP_DEPTH_ABOVE
-DELETE FROM nodes
-WHERE wc_id = ?1
- AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
- AND op_depth > ?3
-
--- STMT_SELECT_LOCAL_RELPATH_OP_DEPTH
-SELECT local_relpath, kind
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
+/* Full layer replacement check code for handling moves
+The op_root must exist (or there is no layer to replace) and an op-root
+ always has presence 'normal' */
+-- STMT_SELECT_LAYER_FOR_REPLACE
+SELECT s.local_relpath, s.kind,
+ RELPATH_SKIP_JOIN(?2, ?4, s.local_relpath) drp, 'normal', 0
+FROM nodes s
+WHERE s.wc_id = ?1 AND s.local_relpath = ?2 AND s.op_depth = ?3
UNION ALL
-SELECT local_relpath, kind
-FROM nodes
-WHERE wc_id = ?1
- AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
- AND op_depth = ?3
-ORDER BY local_relpath
+SELECT s.local_relpath, s.kind,
+ RELPATH_SKIP_JOIN(?2, ?4, s.local_relpath) drp, d.presence,
+ EXISTS(SELECT * FROM nodes sh
+ WHERE sh.wc_id = ?1 AND sh.op_depth > ?5
+ AND sh.local_relpath = d.local_relpath) shadowed
+FROM nodes s
+LEFT OUTER JOIN nodes d ON d.wc_id= ?1 AND d.op_depth = ?5
+ AND d.local_relpath = drp
+WHERE s.wc_id = ?1
+ AND IS_STRICT_DESCENDANT_OF(s.local_relpath, ?2)
+ AND s.op_depth = ?3
+ORDER BY s.local_relpath
--- STMT_SELECT_CHILDREN_OP_DEPTH
+-- STMT_SELECT_DESCENDANTS_OP_DEPTH_RV
SELECT local_relpath, kind
FROM nodes
WHERE wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
AND op_depth = ?3
+ AND presence in (MAP_NORMAL, MAP_INCOMPLETE)
ORDER BY local_relpath DESC
-- STMT_COPY_NODE_MOVE
@@ -302,6 +307,24 @@ SELECT
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
+-- STMT_SELECT_NO_LONGER_MOVED_RV
+SELECT d.local_relpath, RELPATH_SKIP_JOIN(?2, ?4, d.local_relpath) srp,
+ b.presence, b.op_depth
+FROM nodes d
+LEFT OUTER JOIN nodes b ON b.wc_id = ?1 AND b.local_relpath = d.local_relpath
+ AND b.op_depth = (SELECT MAX(x.op_depth) FROM nodes x
+ WHERE x.wc_id = ?1
+ AND x.local_relpath = b.local_relpath
+ AND x.op_depth < ?3)
+WHERE d.wc_id = ?1
+ AND IS_STRICT_DESCENDANT_OF(d.local_relpath, ?2)
+ AND d.op_depth = ?3
+ AND NOT EXISTS(SELECT * FROM nodes s
+ WHERE s.wc_id = ?1
+ AND s.local_relpath = srp
+ AND s.op_depth = ?5)
+ORDER BY d.local_relpath DESC
+
-- STMT_SELECT_OP_DEPTH_CHILDREN
SELECT local_relpath, kind FROM nodes
WHERE wc_id = ?1
@@ -945,17 +968,6 @@ INSERT INTO nodes (
parent_relpath, presence, kind)
VALUES(?1, ?2, ?3, ?4, MAP_BASE_DELETED, ?5)
--- STMT_DELETE_NO_LOWER_LAYER
-DELETE FROM nodes
- WHERE wc_id = ?1
- AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
- AND op_depth = ?3
- AND NOT EXISTS (SELECT 1 FROM nodes n
- WHERE n.wc_id = ?1
- AND n.local_relpath = nodes.local_relpath
- AND n.op_depth = ?4
- AND n.presence IN (MAP_NORMAL, MAP_INCOMPLETE))
-
-- STMT_REPLACE_WITH_BASE_DELETED
INSERT OR REPLACE INTO nodes (wc_id, local_relpath, op_depth, parent_relpath,
kind, moved_to, presence)
@@ -963,7 +975,7 @@ SELECT wc_id, local_relpath, op_depth, p
kind, moved_to, MAP_BASE_DELETED
FROM nodes
WHERE wc_id = ?1
- AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+ AND local_relpath = ?2
AND op_depth = ?3
/* If this query is updated, STMT_INSERT_DELETE_LIST should too.
@@ -1014,11 +1026,30 @@ WHERE wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
AND op_depth = ?3
--- STMT_UPDATE_OP_DEPTH_RECURSIVE
-UPDATE nodes SET op_depth = ?4, moved_here = NULL
-WHERE wc_id = ?1
- AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
- AND op_depth = ?3
+/* Duplicated SELECT body to avoid creating temporary table */
+-- STMT_COPY_OP_DEPTH_RECURSIVE
+INSERT INTO nodes (
+ wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
+ revision, presence, depth, kind, changed_revision, changed_date,
+ changed_author, checksum, properties, translated_size, last_mod_time,
+ symlink_target, moved_here, moved_to )
+SELECT
+ wc_id, local_relpath, ?4, parent_relpath, repos_id,
+ repos_path, revision, presence, depth, kind, changed_revision,
+ changed_date, changed_author, checksum, properties, translated_size,
+ last_mod_time, symlink_target, NULL, NULL
+FROM nodes
+WHERE wc_id = ?1 AND op_depth = ?3 AND local_relpath = ?2
+UNION ALL
+SELECT
+ wc_id, local_relpath, ?4, parent_relpath, repos_id,
+ repos_path, revision, presence, depth, kind, changed_revision,
+ changed_date, changed_author, checksum, properties, translated_size,
+ last_mod_time, symlink_target, NULL, NULL
+FROM nodes
+WHERE wc_id = ?1 AND op_depth = ?3
+ AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+ORDER BY local_relpath
-- STMT_DOES_NODE_EXIST
SELECT 1 FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2
@@ -1588,16 +1619,29 @@ UPDATE nodes SET moved_to = NULL
AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
-- STMT_SELECT_MOVED_PAIR3
-SELECT local_relpath, moved_to, op_depth, kind FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3
- AND moved_to IS NOT NULL
+SELECT n.local_relpath, d.moved_to, d.op_depth, n.kind
+FROM nodes n
+JOIN nodes d ON d.wc_id = ?1 AND d.local_relpath = n.local_relpath
+ AND d.op_depth = (SELECT MIN(dd.op_depth)
+ FROM nodes dd
+ WHERE dd.wc_id = ?1
+ AND dd.local_relpath = d.local_relpath
+ AND dd.op_depth > ?3)
+WHERE n.wc_id = ?1 AND n.local_relpath = ?2 AND n.op_depth = ?3
+ AND d.moved_to IS NOT NULL
UNION ALL
-SELECT local_relpath, moved_to, op_depth, kind FROM nodes
-WHERE wc_id = ?1
- AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
- AND op_depth > ?3
- AND moved_to IS NOT NULL
-ORDER BY local_relpath, op_depth
+SELECT n.local_relpath, d.moved_to, d.op_depth, n.kind
+FROM nodes n
+JOIN nodes d ON d.wc_id = ?1 AND d.local_relpath = n.local_relpath
+ AND d.op_depth = (SELECT MIN(dd.op_depth)
+ FROM nodes dd
+ WHERE dd.wc_id = ?1
+ AND dd.local_relpath = d.local_relpath
+ AND dd.op_depth > ?3)
+WHERE n.wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
+ AND n.op_depth = ?3
+ AND d.moved_to IS NOT NULL
+ORDER BY n.local_relpath
-- STMT_SELECT_MOVED_OUTSIDE
SELECT local_relpath, moved_to, op_depth FROM nodes
@@ -1609,16 +1653,12 @@ WHERE wc_id = ?1
-- STMT_SELECT_OP_DEPTH_MOVED_PAIR
SELECT n.local_relpath, p.kind, n.moved_to, p.repos_path
-FROM nodes AS n
-JOIN (SELECT local_relpath, kind, repos_path
- FROM nodes AS o
- WHERE o.wc_id = ?1
- AND o.op_depth=(SELECT MAX(d.op_depth)
- FROM nodes AS d
- WHERE d.wc_id = ?1
- AND d.local_relpath = o.local_relpath
- AND d.op_depth < ?3)) AS p
- ON n.local_relpath = p.local_relpath
+FROM nodes n
+JOIN nodes p ON p.wc_id = ?1 AND p.local_relpath = ?2
+ AND p.op_depth=(SELECT MAX(d.op_depth)
+ FROM nodes d
+ WHERE d.wc_id = ?1 AND d.local_relpath = ?2
+ AND d.op_depth < ?3)
WHERE n.wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
AND n.op_depth = ?3
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.c?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.c Fri Feb
6 20:18:23 2015
@@ -569,12 +569,54 @@ blank_ibb(insert_base_baton_t *pibb)
}
-svn_error_t *
-svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- svn_node_kind_t kind,
- int op_depth,
- apr_pool_t *scratch_pool)
+/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
+
+ ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm
+ discussing on dev@ whether we can let that be null for presence
+ == base-deleted. OP_DEPTH is the op-depth of what, and why?
+ It is used to select the lowest working node higher than OP_DEPTH,
+ so, in terms of the API, OP_DEPTH means ...?
+
+ Given a wc:
+
+ 0 1 2 3 4
+ normal
+ A normal
+ A/B normal normal
+ A/B/C not-pres normal
+ A/B/C/D normal
+
+ That is checkout, delete A/B, copy a replacement A/B, delete copied
+ child A/B/C, add replacement A/B/C, add A/B/C/D.
+
+ Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
+ must extend the A/B deletion:
+
+ 0 1 2 3 4
+ normal
+ A normal
+ A/B normal normal
+ A/B/C normal not-pres normal
+ A/B/C/D normal base-del normal
+ A/B/C/D/E normal base-del
+
+ When adding a node if the parent has a higher working node then the
+ parent node is deleted (or replaced) and the delete must be extended
+ to cover new node.
+
+ In the example above A/B/C/D and A/B/C/D/E are the nodes that get
+ the extended delete, A/B/C is already deleted.
+
+ If ADDED_DELETE is not NULL, set *ADDED_DELETE to TRUE if a new delete
+ was recorded, otherwise to FALSE.
+ */
+static svn_error_t *
+db_extend_parent_delete(svn_boolean_t *added_delete,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ svn_node_kind_t kind,
+ int op_depth,
+ apr_pool_t *scratch_pool)
{
svn_boolean_t have_row;
svn_sqlite__stmt_t *stmt;
@@ -583,6 +625,9 @@ svn_wc__db_extend_parent_delete(svn_wc__
SVN_ERR_ASSERT(local_relpath[0]);
+ if (added_delete)
+ *added_delete = FALSE;
+
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_LOWEST_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, parent_relpath,
@@ -609,6 +654,9 @@ svn_wc__db_extend_parent_delete(svn_wc__
local_relpath, parent_op_depth,
parent_relpath, kind_map, kind));
SVN_ERR(svn_sqlite__update(NULL, stmt));
+
+ if (added_delete)
+ *added_delete = TRUE;
}
}
@@ -616,7 +664,7 @@ svn_wc__db_extend_parent_delete(svn_wc__
}
-/* This is the reverse of svn_wc__db_extend_parent_delete.
+/* This is the reverse of db_extend_parent_delete.
When removing a node if the parent has a higher working node then
the parent node and this node are both deleted or replaced and any
@@ -626,11 +674,11 @@ svn_wc__db_extend_parent_delete(svn_wc__
only uses this function within an sqlite transaction if atomic
behavior is needed.
*/
-svn_error_t *
-svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- int op_depth,
- apr_pool_t *scratch_pool)
+static svn_error_t *
+db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ int op_depth,
+ apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
@@ -833,16 +881,17 @@ insert_base_node(const insert_base_baton
|| (pibb->status == svn_wc__db_status_incomplete))
&& ! pibb->file_external)
{
- SVN_ERR(svn_wc__db_extend_parent_delete(wcroot, local_relpath,
- pibb->kind, 0,
- scratch_pool));
+ SVN_ERR(db_extend_parent_delete(NULL,
+ wcroot, local_relpath,
+ pibb->kind, 0,
+ scratch_pool));
}
else if (pibb->status == svn_wc__db_status_not_present
|| pibb->status == svn_wc__db_status_server_excluded
|| pibb->status == svn_wc__db_status_excluded)
{
- SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
- scratch_pool));
+ SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0,
+ scratch_pool));
}
}
@@ -2387,8 +2436,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
- SVN_ERR(svn_wc__db_retract_parent_delete(wcroot, local_relpath, 0,
- scratch_pool));
+ SVN_ERR(db_retract_parent_delete(wcroot, local_relpath, 0, scratch_pool));
/* Step 6: Delete actual node if we don't keep working */
if (! keep_working)
@@ -4797,6 +4845,187 @@ svn_wc__db_op_copy(svn_wc__db_t *db,
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *src_op_relpath,
+ int src_op_depth,
+ const char *dst_op_relpath,
+ svn_skel_t *conflict,
+ svn_skel_t *work_items,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt, *stmt2;
+ svn_boolean_t have_row;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int dst_op_depth = relpath_depth(dst_op_relpath);
+ svn_boolean_t locked;
+ svn_error_t *err = NULL;
+
+ SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot, dst_op_relpath,
+ FALSE, scratch_pool));
+
+ if (!locked)
+ return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
+ _("No write-lock in '%s'"),
+ path_for_error_message(wcroot, dst_op_relpath,
+ scratch_pool));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_COPY_NODE_MOVE));
+
+ /* Replace entire subtree at one op-depth. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_LAYER_FOR_REPLACE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
+ src_op_relpath, src_op_depth,
+ dst_op_relpath, dst_op_depth));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ const char *src_relpath;
+ const char *dst_relpath;
+ svn_boolean_t exists;
+
+ svn_pool_clear(iterpool);
+
+ src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+ dst_relpath = svn_sqlite__column_text(stmt, 2, iterpool);
+
+ exists = !svn_sqlite__column_is_null(stmt, 3);
+
+ err = svn_sqlite__bindf(stmt2, "isdsds", wcroot->wc_id,
+ src_relpath, src_op_depth,
+ dst_relpath, dst_op_depth,
+ svn_relpath_dirname(dst_relpath, iterpool));
+ if (!err)
+ err = svn_sqlite__step_done(stmt2);
+
+ /* stmt2 is reset (never modified or by step_done) */
+
+ if (err)
+ break;
+
+ if (strlen(dst_relpath) > strlen(dst_op_relpath))
+ {
+ svn_boolean_t added_delete = FALSE;
+ svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
+
+ /* The op root can't be shadowed, so extension of a parent delete
+ is only needed when the parent can be deleted */
+ if (relpath_depth(dst_relpath) > (dst_op_depth+1))
+ {
+ err = db_extend_parent_delete(&added_delete, wcroot, dst_relpath,
+ kind, dst_op_depth, iterpool);
+
+ if (err)
+ break;
+ }
+
+ if (exists)
+ {
+ svn_wc__db_status_t presence;
+
+ presence = svn_sqlite__column_token(stmt, 3, presence_map);
+
+ if (presence == svn_wc__db_status_not_present)
+ exists = FALSE;
+ }
+
+ /* ### Fails in a few tests... Needs further research */
+ /*SVN_ERR_ASSERT(!(exists && added_delete));*/
+
+ if (!exists)
+ {
+ svn_boolean_t shadowed;
+
+ shadowed = svn_sqlite__column_int(stmt, 4);
+
+ /*if (!shadowed && !added_delete)
+ {
+ err = svn_error_createf(
+ SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+ _("Node '%s' was unexpectedly added unshadowed"),
+ path_for_error_message(wcroot, dst_relpath,
+ iterpool));
+ break;
+ }*/
+ }
+ }
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+ /* And now remove the records that are no longer needed */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_NO_LONGER_MOVED_RV));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdsd", wcroot->wc_id,
+ dst_op_relpath, dst_op_depth,
+ src_op_relpath, src_op_depth));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ const char *dst_relpath;
+ svn_wc__db_status_t shadowed_presence;
+
+ svn_pool_clear(iterpool);
+
+ dst_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+
+ if (!svn_sqlite__column_is_null(stmt, 2))
+ shadowed_presence = svn_sqlite__column_token(stmt, 2, presence_map);
+ else
+ shadowed_presence = svn_wc__db_status_not_present;
+
+ if (shadowed_presence != svn_wc__db_status_normal
+ && shadowed_presence != svn_wc__db_status_incomplete)
+ {
+ err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_DELETE_NODE);
+ }
+ else
+ {
+ err =svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+ STMT_REPLACE_WITH_BASE_DELETED);
+ }
+
+ if (!err)
+ err = svn_sqlite__bindf(stmt2, "isd", wcroot->wc_id, dst_relpath,
+ dst_op_depth);
+
+ if (!err)
+ err = svn_sqlite__step_done(stmt2);
+
+ /* stmt2 is reset (never modified or by step_done) */
+
+ if (err)
+ break;
+
+ /* Retract base-delete for the node itself */
+ err = db_retract_parent_delete(wcroot, dst_relpath, dst_op_depth,
+ scratch_pool);
+
+ if (err)
+ break;
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ svn_pool_destroy(iterpool);
+
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+
+ /* ### TODO: Did we handle ACTUAL as intended? */
+
+ SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
+
+ if (conflict)
+ SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, dst_op_relpath /* ## */,
+ conflict, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
/* The txn body of svn_wc__db_op_handle_move_back */
static svn_error_t *
handle_move_back(svn_boolean_t *moved_back,
@@ -14625,8 +14854,6 @@ static svn_error_t *
make_copy_txn(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
int op_depth,
- const svn_skel_t *conflicts,
- const svn_skel_t *work_items,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
@@ -14707,21 +14934,68 @@ make_copy_txn(svn_wc__db_wcroot_t *wcroo
copy_relpath = svn_relpath_join(local_relpath, name, iterpool);
- SVN_ERR(make_copy_txn(wcroot, copy_relpath, op_depth, NULL, NULL,
- iterpool));
+ SVN_ERR(make_copy_txn(wcroot, copy_relpath, op_depth, iterpool));
}
- SVN_ERR(flush_entries(wcroot, svn_dirent_join(wcroot->abspath, local_relpath,
- iterpool),
- svn_depth_empty, iterpool));
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_op_make_copy_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ const svn_skel_t *conflicts,
+ const svn_skel_t *work_items,
+ apr_pool_t *scratch_pool)
+{
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ int op_depth = -1;
+
+ /* The update editor is supposed to call this function when there is
+ no working node for LOCAL_ABSPATH. */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ op_depth = svn_sqlite__column_int(stmt, 0);
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (have_row)
+ {
+ if (op_depth == relpath_depth(local_relpath))
+ return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
+ _("Modification of '%s' already exists"),
+ path_for_error_message(wcroot,
+ local_relpath,
+ scratch_pool));
+
+ /* We have a working layer, but not one at the op-depth of local-relpath,
+ so we can create a copy by just copying the lower layer */
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_COPY_OP_DEPTH_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, local_relpath,
+ op_depth, relpath_depth(local_relpath)));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+ else
+ {
+ /* We don't allow copies to contain server-excluded nodes;
+ the update editor is going to have to bail out. */
+ SVN_ERR(catch_copy_of_server_excluded(wcroot, local_relpath,
scratch_pool));
+
+ SVN_ERR(make_copy_txn(wcroot, local_relpath,
+ relpath_depth(local_relpath), scratch_pool));
+ }
if (conflicts)
SVN_ERR(svn_wc__db_mark_conflict_internal(wcroot, local_relpath,
- conflicts, iterpool));
-
- SVN_ERR(add_work_items(wcroot->sdb, work_items, iterpool));
+ conflicts, scratch_pool));
- svn_pool_destroy(iterpool);
+ SVN_ERR(add_work_items(wcroot->sdb, work_items, scratch_pool));
return SVN_NO_ERROR;
}
@@ -14736,8 +15010,6 @@ svn_wc__db_op_make_copy(svn_wc__db_t *db
{
svn_wc__db_wcroot_t *wcroot;
const char *local_relpath;
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
@@ -14745,30 +15017,14 @@ svn_wc__db_op_make_copy(svn_wc__db_t *db
local_abspath, scratch_pool, scratch_pool));
VERIFY_USABLE_WCROOT(wcroot);
- /* The update editor is supposed to call this function when there is
- no working node for LOCAL_ABSPATH. */
- SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_WORKING_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- SVN_ERR(svn_sqlite__reset(stmt));
- if (have_row)
- return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
- _("Modification of '%s' already exists"),
- path_for_error_message(wcroot,
- local_relpath,
- scratch_pool));
-
- /* We don't allow copies to contain server-excluded nodes;
- the update editor is going to have to bail out. */
- SVN_ERR(catch_copy_of_server_excluded(wcroot, local_relpath, scratch_pool));
-
SVN_WC__DB_WITH_TXN(
- make_copy_txn(wcroot, local_relpath,
- relpath_depth(local_relpath), conflicts, work_items,
- scratch_pool),
+ svn_wc__db_op_make_copy_internal(wcroot, local_relpath, conflicts,
work_items,
+ scratch_pool),
wcroot);
+ SVN_ERR(flush_entries(wcroot, local_abspath,
+ svn_depth_infinity, scratch_pool));
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.h
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.h?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db.h Fri Feb
6 20:18:23 2015
@@ -3246,9 +3246,21 @@ svn_wc__db_temp_op_end_directory_update(
apr_pool_t *scratch_pool);
-/* Copy the base tree at LOCAL_ABSPATH into the working tree as copy,
- leaving any subtree additions and copies as-is. This allows the
- base node tree to be removed. */
+/* When local_abspath has no WORKING layer, copy the base tree at
+ LOCAL_ABSPATH into the working tree as copy, leaving any subtree
+ additions and copies as-is. This may introduce multiple layers if
+ the tree is mixed revision.
+
+ When local_abspath has a WORKING node, but is not an op-root, copy
+ all descendants at the same op-depth to the op-depth of local_abspath,
+ thereby turning this node in a copy of what was already there.
+
+ Fails with a SVN_ERR_WC_PATH_UNEXPECTED_STATUS error if LOCAL_RELPATH
+ is already an op-root (as in that case it can't be copied as that
+ would overwrite what is already there).
+
+ After this operation the copied layer (E.g. BASE) can be removed, without
+ the WORKING nodes chaning. Typical usecase: tree conflict handling */
svn_error_t *
svn_wc__db_op_make_copy(svn_wc__db_t *db,
const char *local_abspath,
Modified:
subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db_private.h
URL:
http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db_private.h?rev=1657947&r1=1657946&r2=1657947&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db_private.h
(original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_wc/wc_db_private.h
Fri Feb 6 20:18:23 2015
@@ -394,58 +394,27 @@ svn_wc__db_get_children_op_depth(apr_has
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-
-/* Extend any delete of the parent of LOCAL_RELPATH to LOCAL_RELPATH.
-
- ### What about KIND and OP_DEPTH? KIND ought to be redundant; I'm
- discussing on dev@ whether we can let that be null for presence
- == base-deleted. OP_DEPTH is the op-depth of what, and why?
- It is used to select the lowest working node higher than OP_DEPTH,
- so, in terms of the API, OP_DEPTH means ...?
-
- Given a wc:
-
- 0 1 2 3 4
- normal
- A normal
- A/B normal normal
- A/B/C not-pres normal
- A/B/C/D normal
-
- That is checkout, delete A/B, copy a replacement A/B, delete copied
- child A/B/C, add replacement A/B/C, add A/B/C/D.
-
- Now an update that adds base nodes for A/B/C, A/B/C/D and A/B/C/D/E
- must extend the A/B deletion:
-
- 0 1 2 3 4
- normal
- A normal
- A/B normal normal
- A/B/C normal not-pres normal
- A/B/C/D normal base-del normal
- A/B/C/D/E normal base-del
-
- When adding a node if the parent has a higher working node then the
- parent node is deleted (or replaced) and the delete must be extended
- to cover new node.
-
- In the example above A/B/C/D and A/B/C/D/E are the nodes that get
- the extended delete, A/B/C is already deleted.
- */
+/* Update the single op-depth layer in the move destination subtree
+ rooted at DST_RELPATH to make it match the move source subtree
+ rooted at SRC_RELPATH. */
svn_error_t *
-svn_wc__db_extend_parent_delete(svn_wc__db_wcroot_t *wcroot,
- const char *local_relpath,
- svn_node_kind_t kind,
- int op_depth,
- apr_pool_t *scratch_pool);
+svn_wc__db_op_copy_layer_internal(svn_wc__db_wcroot_t *wcroot,
+ const char *src_op_relpath,
+ int src_op_depth,
+ const char *dst_op_relpath,
+ svn_skel_t *conflict,
+ svn_skel_t *work_items,
+ apr_pool_t *scratch_pool);
+/* Like svn_wc__db_op_make_copy but with wcroot, local_relpath */
svn_error_t *
-svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
+svn_wc__db_op_make_copy_internal(svn_wc__db_wcroot_t *wcroot,
const char *local_relpath,
- int op_depth,
+ const svn_skel_t *conflicts,
+ const svn_skel_t *work_items,
apr_pool_t *scratch_pool);
+
/* Extract the moved-to information for LOCAL_RELPATH at OP-DEPTH by
examining the lowest working node above OP_DEPTH. The output paths
are NULL if there is no move, otherwise: