You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2010/12/16 17:01:35 UTC
svn commit: r1050019 - in /subversion/trunk/subversion:
libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c tests/cmdline/upgrade_tests.py
tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2
Author: philip
Date: Thu Dec 16 16:01:35 2010
New Revision: 1050019
URL: http://svn.apache.org/viewvc?rev=1050019&view=rev
Log:
Make upgrades handle revert properties for working-only replaced files.
* subversion/libsvn_wc/wc-queries.sql
(STMT_PLAN_PROP_UPGRADE): Remove.
(STMT_SELECT_NODE_UPGRADE, STMT_UPDATE_NODE_PROPS): New.
* subversion/libsvn_wc/wc_db.c
(prop_upgrade_trees): Remove.
(svn_wc__db_upgrade_apply_props): Handle revert-props for working-only
replaces.
* subversion/tests/cmdline/upgrade_tests.py
(replaced_files): New.
(test_list): Mark replaced_files PASS.
* subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2: New.
Added:
subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2 (with props)
Modified:
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1050019&r1=1050018&r2=1050019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Dec 16 16:01:35 2010
@@ -712,14 +712,15 @@ UPDATE actual_node SET tree_conflict_dat
SELECT DISTINCT local_relpath FROM nodes
WHERE kind = 'file' AND parent_relpath = ?1;
--- STMT_PLAN_PROP_UPGRADE
-SELECT 0, nodes_base.presence, nodes_base.wc_id FROM nodes nodes_base
-WHERE nodes_base.local_relpath = ?1 AND nodes_base.op_depth = 0
-UNION ALL
-SELECT 1, nodes_work.presence, nodes_work.wc_id FROM nodes nodes_work
-WHERE nodes_work.local_relpath = ?1
- AND nodes_work.op_depth = (SELECT MAX(op_depth) FROM nodes
- WHERE local_relpath = ?1 AND op_depth > 0);
+-- STMT_SELECT_NODE_UPGRADE
+SELECT op_depth, presence, wc_id
+FROM nodes
+WHERE local_relpath = ?1
+ORDER BY op_depth DESC;
+
+-- STMT_UPDATE_NODE_PROPS
+UPDATE nodes SET properties = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3;
-- STMT_HAS_WORKING_NODES
SELECT 1 FROM nodes WHERE op_depth > 0;
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1050019&r1=1050018&r2=1050019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Dec 16 16:01:35 2010
@@ -1244,73 +1244,6 @@ which_trees_exist(svn_boolean_t *base_ex
}
-/* Determine which trees' nodes exist for a given LOCAL_RELPATH in the
- specified SDB.
-
- Note: this is VERY similar to the above which_trees_exist() except that
- we return a WC_ID and verify some additional constraints. */
-static svn_error_t *
-prop_upgrade_trees(svn_boolean_t *base_exists,
- svn_wc__db_status_t *base_presence,
- svn_boolean_t *working_exists,
- svn_wc__db_status_t *work_presence,
- apr_int64_t *wc_id,
- svn_sqlite__db_t *sdb,
- const char *local_relpath)
-{
- svn_sqlite__stmt_t *stmt;
- svn_boolean_t have_row;
-
- *base_exists = FALSE;
- *working_exists = FALSE;
-
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PLAN_PROP_UPGRADE));
- SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
- /* During a property upgrade, there better be a row corresponding to
- the provided LOCAL_RELPATH. We shouldn't even be here without a
- query for available rows. */
- SVN_ERR_ASSERT(have_row);
-
- /* Use the first column to detect which table this row came from. */
- if (svn_sqlite__column_int(stmt, 0))
- {
- *working_exists = TRUE; /* value == 1 */
- *work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
- }
- else
- {
- *base_exists = TRUE; /* value == 0 */
- *base_presence = svn_sqlite__column_token(stmt, 1, presence_map);
- }
-
- /* Return the WC_ID that was assigned. */
- *wc_id = svn_sqlite__column_int64(stmt, 2);
-
- SVN_ERR(svn_sqlite__step(&have_row, stmt));
- if (have_row)
- {
- /* If both rows, then both tables. */
- *base_exists = TRUE;
- *working_exists = TRUE;
-
- /* If the second row came from WORKING_NODE, then we should also
- fetch the 'presence' column value. */
- if (svn_sqlite__column_int(stmt, 0))
- *work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
- else
- *base_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-
- /* During an upgrade, there should be just one working copy, so both
- rows should refer to the same value. */
- SVN_ERR_ASSERT(*wc_id == svn_sqlite__column_int64(stmt, 2));
- }
-
- return svn_error_return(svn_sqlite__reset(stmt));
-}
-
-
/* */
static svn_error_t *
create_db(svn_sqlite__db_t **sdb,
@@ -7094,12 +7027,10 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
int original_format,
apr_pool_t *scratch_pool)
{
- svn_boolean_t have_base;
- svn_wc__db_status_t base_presence;
- svn_boolean_t have_work;
- svn_wc__db_status_t work_presence;
- apr_int64_t wc_id;
svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ apr_int64_t wc_id, top_op_depth = -1, below_op_depth = -1;
+ svn_wc__db_status_t top_presence, below_presence;
int affected_rows;
/* ### working_props: use set_props_txn.
@@ -7129,19 +7060,31 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
the handling of our inputs, relative to the state of this node.
*/
- /* Collect information about this node. */
- SVN_ERR(prop_upgrade_trees(&have_base, &base_presence,
- &have_work, &work_presence,
- &wc_id, sdb, local_relpath));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODE_UPGRADE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ {
+ top_op_depth = svn_sqlite__column_int64(stmt, 0);
+ top_presence = svn_sqlite__column_token(stmt, 1, presence_map);
+ wc_id = svn_sqlite__column_int64(stmt, 2);
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ if (have_row)
+ {
+ below_op_depth = svn_sqlite__column_int64(stmt, 0);
+ below_presence = svn_sqlite__column_token(stmt, 1, presence_map);
+ }
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
/* Detect the buggy scenario described above. We cannot upgrade this
working copy if we have no idea where BASE_PROPS should go. */
if (original_format > SVN_WC__NO_REVERT_FILES
&& revert_props == NULL
- && have_work
- && work_presence == svn_wc__db_status_normal
- && have_base
- && base_presence != svn_wc__db_status_not_present)
+ && top_op_depth != -1
+ && top_presence == svn_wc__db_status_normal
+ && below_op_depth != -1
+ && below_presence != svn_wc__db_status_not_present)
{
/* There should be REVERT_PROPS, so it appears that we just ran into
the described bug. Sigh. */
@@ -7154,48 +7097,44 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
scratch_pool), scratch_pool));
}
- if (have_base
- && (base_presence == svn_wc__db_status_normal
- || base_presence == svn_wc__db_status_incomplete))
- {
- apr_hash_t *props = revert_props ? revert_props : base_props;
+ /* Need at least one row, or two rows if there are revert props */
+ if (top_op_depth == -1
+ || (below_op_depth == -1 && revert_props))
+ return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+ _("Insufficient NODES rows for '%s'"),
+ svn_dirent_local_style(
+ svn_dirent_join(dir_abspath, local_relpath,
+ scratch_pool), scratch_pool));
+
+ /* one row, base props only: upper row gets base props
+ two rows, base props only: lower row gets base props
+ two rows, base and revert props: upper row gets base, lower gets revert */
+
+ if (revert_props || below_op_depth == -1)
+ {
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPDATE_NODE_BASE_PROPS));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
- SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
+ STMT_UPDATE_NODE_PROPS));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+ wc_id, local_relpath, top_op_depth));
+ SVN_ERR(svn_sqlite__bind_properties(stmt, 4, base_props, scratch_pool));
SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
- /* ### should we provide a nicer error message? */
SVN_ERR_ASSERT(affected_rows == 1);
}
- if (have_work)
+ if (below_op_depth != -1)
{
- /* WORKING_NODE has very limited 'presence' values. */
- SVN_ERR_ASSERT(work_presence == svn_wc__db_status_normal
- || work_presence == svn_wc__db_status_not_present
- || work_presence == svn_wc__db_status_base_deleted
- || work_presence == svn_wc__db_status_incomplete);
+ apr_hash_t *props = revert_props ? revert_props : base_props;
- /* Do we have a replaced node? It has properties: an empty set for
- adds, and a non-empty set for copies/moves. */
- if (original_format > SVN_WC__NO_REVERT_FILES
- && (work_presence == svn_wc__db_status_normal
- || work_presence == svn_wc__db_status_incomplete))
- {
- SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPDATE_NODE_WORKING_PROPS));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
- SVN_ERR(svn_sqlite__bind_properties(stmt, 3, base_props,
- scratch_pool));
- SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_UPDATE_NODE_PROPS));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+ wc_id, local_relpath, below_op_depth));
+ SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
+ SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
- /* ### should we provide a nicer error message? */
- SVN_ERR_ASSERT(affected_rows == 1);
- }
- /* else other states should have no properties. */
- /* ### should we insert empty props for <= SVN_WC__NO_REVERT_FILES? */
+ SVN_ERR_ASSERT(affected_rows == 1);
}
/* If there are WORKING_PROPS, then they always go into ACTUAL_NODE. */
Modified: subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests.py?rev=1050019&r1=1050018&r2=1050019&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/upgrade_tests.py Thu Dec 16 16:01:35 2010
@@ -754,6 +754,47 @@ def delete_in_copy_upgrade(sbox):
})
run_and_verify_status_no_server(sbox.wc_dir, expected_status)
+def replaced_files(sbox):
+ "upgrade with base and working replaced files"
+
+ sbox.build(create_wc = False)
+ wc_dir = sbox.wc_dir
+ replace_sbox_with_tarfile(sbox, 'replaced-files.tar.bz2')
+
+ svntest.actions.run_and_verify_svn(None, None, [],
+ 'upgrade', sbox.wc_dir)
+
+ # A/f is a base file that is replaced with a copy of A/g, B is a
+ # working-only copy of A, and B/f is a working-only file replaced
+ # with a copy of A/g
+ expected_status = svntest.wc.State(sbox.wc_dir,
+ {
+ '' : Item(status=' ', wc_rev='5'),
+ 'A' : Item(status=' ', wc_rev='5'),
+ 'A/f' : Item(status='R ', wc_rev='-', copied='+'),
+ 'A/g' : Item(status=' ', wc_rev='5'),
+ 'B' : Item(status='A ', wc_rev='-', copied='+'),
+ 'B/f' : Item(status='R ', wc_rev='-', copied='+'),
+ 'B/g' : Item(status=' ', wc_rev='-', copied='+'),
+ })
+ run_and_verify_status_no_server(sbox.wc_dir, expected_status)
+
+ simple_property_verify(sbox.wc_dir, {
+ 'A/f' : {'pAg' : 'vAg' },
+ 'A/g' : {'pAg' : 'vAg' },
+ 'B/f' : {'pAg' : 'vAg' },
+ 'B/g' : {'pAg' : 'vAg' },
+ })
+
+ svntest.actions.run_and_verify_svn(None, 'Reverted.*', [], 'revert',
+ sbox.ospath('A/f'), sbox.ospath('B/f'))
+
+ simple_property_verify(sbox.wc_dir, {
+ 'A/f' : {'pAf' : 'vAf' },
+ 'A/g' : {'pAg' : 'vAg' },
+ 'B/f' : {'pAf' : 'vAf' },
+ 'B/g' : {'pAg' : 'vAg' },
+ })
########################################################################
# Run the tests
@@ -778,6 +819,7 @@ test_list = [ None,
dirs_only_upgrade,
upgrade_tree_conflict_data,
delete_in_copy_upgrade,
+ replaced_files,
]
Added: subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2?rev=1050019&view=auto
==============================================================================
Binary file - no diff available.
Propchange: subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream