Author: rhuijben
Date: Thu Feb 19 12:00:51 2015
New Revision: 1660861
URL: http://svn.apache.org/r1660861
Log:
Properly record single-revision copies from the svn_wc_entry_t world as a
single op-root, and add not-present nodes when handling a multi revision
copy... just like how we would handle this in wc-ng.
The original kind of working copy state would be impossible to commit
without this patch as the child copies would collide with what was copied
from the ancestor.
(Users would just revert... as this kind of commit problems (w/c)ould have
caused similar problems in the versions they just have upgraded from)
* subversion/libsvn_wc/entries.c
(write_entry): Calculate proper-op depth for copies that are implied
by their parent directory. Add not-present at parent op-depth when
we don't know if there is something there (or not), just like in
wc-ng.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_upgrade_apply_props): Skip intermediate layers that don't
hold properties.
* subversion/tests/cmdline/upgrade_tests.py
(tree_replace1,
tree_replace2): Update expected status results.
Modified:
subversion/trunk/subversion/libsvn_wc/entries.c
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=1660861&r1=1660860&r2=1660861&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Thu Feb 19 12:00:51 2015
@@ -1804,6 +1804,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;
@@ -1813,20 +1817,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,
@@ -1840,6 +1861,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)
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1660861&r1=1660860&r2=1660861&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb 19 12:00:51 2015
@@ -13314,8 +13314,19 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
SVN_ERR(svn_sqlite__step(&have_row, stmt));
if (have_row)
{
- below_op_depth = svn_sqlite__column_int(stmt, 0);
below_presence = svn_sqlite__column_token(stmt, 3, presence_map);
+
+ /* There might be an intermediate layer on mixed-revision copies,
+ or when BASE is shadowed */
+ if (below_presence == svn_wc__db_status_not_present
+ || below_presence == svn_wc__db_status_deleted)
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (have_row)
+ {
+ below_presence = svn_sqlite__column_token(stmt, 3, presence_map);
+ below_op_depth = svn_sqlite__column_int(stmt, 0);
+ }
}
}
SVN_ERR(svn_sqlite__reset(stmt));
Modified: subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests.py?rev=1660861&r1=1660860&r2=1660861&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/upgrade_tests.py Thu Feb 19
12:00:51 2015
@@ -935,15 +935,15 @@ def tree_replace1(sbox):
{
'' : Item(status=' M', wc_rev=17),
'B' : Item(status='R ', copied='+', wc_rev='-'),
- 'B/f' : Item(status='R ', copied='+', wc_rev='-'),
+ 'B/f' : Item(status=' ', copied='+', wc_rev='-'),
'B/g' : Item(status='D ', wc_rev=17),
- 'B/h' : Item(status='A ', copied='+', wc_rev='-'),
- 'B/C' : Item(status='R ', copied='+', wc_rev='-'),
- 'B/C/f' : Item(status='R ', copied='+', wc_rev='-'),
+ 'B/h' : Item(status=' ', copied='+', wc_rev='-'),
+ 'B/C' : Item(status=' ', copied='+', wc_rev='-'),
+ 'B/C/f' : Item(status=' ', copied='+', wc_rev='-'),
'B/D' : Item(status='D ', wc_rev=17),
'B/D/f' : Item(status='D ', wc_rev=17),
- 'B/E' : Item(status='A ', copied='+', wc_rev='-'),
- 'B/E/f' : Item(status='A ', copied='+', wc_rev='-'),
+ 'B/E' : Item(status=' ', copied='+', wc_rev='-'),
+ 'B/E/f' : Item(status=' ', copied='+', wc_rev='-'),
})
run_and_verify_status_no_server(sbox.wc_dir, expected_status)
@@ -961,11 +961,11 @@ def tree_replace2(sbox):
'B' : Item(status='R ', copied='+', wc_rev='-'),
'B/f' : Item(status='D ', wc_rev=12),
'B/D' : Item(status='D ', wc_rev=12),
- 'B/g' : Item(status='A ', copied='+', wc_rev='-'),
- 'B/E' : Item(status='A ', copied='+', wc_rev='-'),
+ 'B/g' : Item(status=' ', copied='+', wc_rev='-'),
+ 'B/E' : Item(status=' ', copied='+', wc_rev='-'),
'C' : Item(status='R ', copied='+', wc_rev='-'),
- 'C/f' : Item(status='A ', copied='+', wc_rev='-'),
- 'C/D' : Item(status='A ', copied='+', wc_rev='-'),
+ 'C/f' : Item(status=' ', copied='+', wc_rev='-'),
+ 'C/D' : Item(status=' ', copied='+', wc_rev='-'),
'C/g' : Item(status='D ', wc_rev=12),
'C/E' : Item(status='D ', wc_rev=12),
})