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/06/09 20:02:42 UTC
svn commit: r953101 - in /subversion/trunk/subversion: libsvn_wc/wc_db.c
tests/cmdline/switch_tests.py
Author: philip
Date: Wed Jun 9 18:02:41 2010
New Revision: 953101
URL: http://svn.apache.org/viewvc?rev=953101&view=rev
Log:
Make switch --relocate handle more node types. This also reverts
r952728 which is no longer needed.
* subversion/libsvn_wc/wc_db.c
(svn_wc__db_global_relocate): Handle copied/deleted/excluded nodes.
(svn_wc__db_scan_addition): Don't expect excluded (reverts r952728).
* subversion/tests/cmdline/switch_tests.py
(relocate_deleted_missing_copied): Extend to include a delete within
a copy.
Modified:
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/tests/cmdline/switch_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=953101&r1=953100&r2=953101&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Jun 9 18:02:41 2010
@@ -4834,8 +4834,9 @@ svn_wc__db_global_relocate(svn_wc__db_t
apr_pool_t *scratch_pool)
{
svn_wc__db_pdh_t *pdh;
+ svn_wc__db_status_t status;
struct relocate_baton rb;
- svn_sqlite__stmt_t *stmt;
+ const char *old_repos_root_url, *stored_local_dir_abspath;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_dir_abspath));
/* ### assert that we were passed a directory? */
@@ -4845,32 +4846,98 @@ svn_wc__db_global_relocate(svn_wc__db_t
scratch_pool, scratch_pool));
VERIFY_USABLE_PDH(pdh);
- /* Get the existing repos_id of the base node, since we'll need it to
- update a potential lock. */
- /* ### is it faster to fetch fewer columns? */
- SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
- STMT_SELECT_BASE_NODE));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id,
- rb.local_relpath));
- SVN_ERR(svn_sqlite__step(&rb.have_base_node, stmt));
- if (rb.have_base_node)
- {
- rb.old_repos_id = svn_sqlite__column_int64(stmt, 0);
- rb.repos_relpath = svn_sqlite__column_text(stmt, 1, scratch_pool);
- SVN_ERR(svn_sqlite__reset(stmt));
+ SVN_ERR(svn_wc__db_read_info(&status,
+ NULL, NULL,
+ &rb.repos_relpath, &old_repos_root_url,
+ &rb.repos_uuid,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ db, local_dir_abspath,
+ scratch_pool, scratch_pool));
- SVN_ERR(fetch_repos_info(NULL, &rb.repos_uuid, pdh->wcroot->sdb,
- rb.old_repos_id, scratch_pool));
+ if (status == svn_wc__db_status_excluded)
+ {
+ /* The parent cannot be excluded, so look at the parent and then
+ adjust the relpath */
+ const char *parent_abspath = svn_dirent_dirname(local_dir_abspath,
+ scratch_pool);
+ SVN_ERR(svn_wc__db_read_info(&status,
+ NULL, NULL,
+ &rb.repos_relpath, &old_repos_root_url,
+ &rb.repos_uuid,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ db, parent_abspath,
+ scratch_pool, scratch_pool));
+ stored_local_dir_abspath = local_dir_abspath;
+ local_dir_abspath = parent_abspath;
}
else
+ stored_local_dir_abspath = NULL;
+
+ if (!rb.repos_relpath || !old_repos_root_url || !rb.repos_uuid)
{
- SVN_ERR(svn_sqlite__reset(stmt));
- SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, &rb.repos_uuid,
- NULL, NULL, NULL, NULL,
- db, local_dir_abspath, scratch_pool,
- scratch_pool));
+ /* Do we need to support relocating something that is
+ added/deleted/excluded without relocating the parent? If not
+ then perhaps relpath, root_url and uuid should be passed down
+ to the children so that they don't have to scan? */
+
+ if (status == svn_wc__db_status_deleted)
+ {
+ const char *work_del_abspath;
+ SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, NULL,
+ &work_del_abspath,
+ db, local_dir_abspath,
+ scratch_pool, scratch_pool));
+ if (work_del_abspath)
+ {
+ /* Deleted within a copy/move */
+ SVN_ERR_ASSERT(!stored_local_dir_abspath);
+ stored_local_dir_abspath = local_dir_abspath;
+
+ /* The parent of the delete is added. */
+ status = svn_wc__db_status_added;
+ local_dir_abspath = svn_dirent_dirname(work_del_abspath,
+ scratch_pool);
+ }
+ }
+
+ if (status == svn_wc__db_status_added
+ || status == svn_wc__db_status_obstructed_add)
+ {
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
+ &rb.repos_relpath,
+ &old_repos_root_url, &rb.repos_uuid,
+ NULL, NULL, NULL, NULL,
+ db, local_dir_abspath,
+ scratch_pool, scratch_pool));
+ }
+ else
+ SVN_ERR(svn_wc__db_scan_base_repos(&rb.repos_relpath,
+ &old_repos_root_url, &rb.repos_uuid,
+ db, local_dir_abspath,
+ scratch_pool, scratch_pool));
+ }
+
+ SVN_ERR_ASSERT(rb.repos_relpath && old_repos_root_url && rb.repos_uuid);
+
+ if (stored_local_dir_abspath)
+ {
+ /* Adjust to get value suitable for local_dir_abspath */
+ const char *part = svn_dirent_is_child(local_dir_abspath,
+ stored_local_dir_abspath,
+ scratch_pool);
+ rb.repos_relpath = svn_relpath_join(rb.repos_relpath, part,
+ scratch_pool);
+ local_dir_abspath = stored_local_dir_abspath;
}
+
+ SVN_ERR(create_repos_id(&rb.old_repos_id, old_repos_root_url, rb.repos_uuid,
+ pdh->wcroot->sdb, scratch_pool));
+
rb.wc_id = pdh->wcroot->wc_id;
rb.repos_root_url = repos_root_url;
@@ -5660,8 +5727,8 @@ svn_wc__db_scan_addition(svn_wc__db_stat
/* Record information from the starting node. */
if (current_abspath == local_abspath)
{
- if (presence != svn_wc__db_status_normal
- && presence != svn_wc__db_status_excluded)
+ /* The starting node should exist normally. */
+ if (presence != svn_wc__db_status_normal)
return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS,
svn_sqlite__reset(stmt),
_("Expected node '%s' to be added."),
Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=953101&r1=953100&r2=953101&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Wed Jun 9 18:02:41 2010
@@ -543,16 +543,26 @@ def relocate_deleted_missing_copied(sbox
# Remove A/B/F to create a missing entry
svntest.main.safe_rmtree(os.path.join(wc_dir, 'A', 'B', 'F'))
- # Copy A/D/H to A/D/H2
- H_path = os.path.join(wc_dir, 'A', 'D', 'H')
- H2_path = os.path.join(wc_dir, 'A', 'D', 'H2')
+ # Copy A/D to A/D2
+ D_path = os.path.join(wc_dir, 'A', 'D')
+ D2_path = os.path.join(wc_dir, 'A', 'D2')
svntest.actions.run_and_verify_svn(None, None, [], 'copy',
- H_path, H2_path)
+ D_path, D2_path)
+ # Delete within the copy
+ D2G_path = os.path.join(wc_dir, 'A', 'D2', 'G')
+ svntest.actions.run_and_verify_svn(None, None, [], 'rm', D2G_path)
+
expected_status.add({
- 'A/D/H2' : Item(status='A ', wc_rev='-', copied='+'),
- 'A/D/H2/chi' : Item(status=' ', wc_rev='-', copied='+'),
- 'A/D/H2/omega' : Item(status=' ', wc_rev='-', copied='+'),
- 'A/D/H2/psi' : Item(status=' ', wc_rev='-', copied='+'),
+ 'A/D2' : Item(status='A ', wc_rev='-', copied='+'),
+ 'A/D2/gamma' : Item(status=' ', wc_rev='-', copied='+'),
+ 'A/D2/G' : Item(status='D ', wc_rev='?'),
+ 'A/D2/G/pi' : Item(status='D ', wc_rev='?'),
+ 'A/D2/G/rho' : Item(status='D ', wc_rev='?'),
+ 'A/D2/G/tau' : Item(status='D ', wc_rev='?'),
+ 'A/D2/H' : Item(status=' ', wc_rev='-', copied='+'),
+ 'A/D2/H/chi' : Item(status=' ', wc_rev='-', copied='+'),
+ 'A/D2/H/omega' : Item(status=' ', wc_rev='-', copied='+'),
+ 'A/D2/H/psi' : Item(status=' ', wc_rev='-', copied='+'),
})
expected_status.tweak('A/B/F', status='! ', wc_rev='?')
svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -574,17 +584,23 @@ def relocate_deleted_missing_copied(sbox
expected_disk = svntest.main.greek_state.copy()
expected_disk.remove('A/mu')
expected_disk.add({
- 'A/D/H2' : Item(),
- 'A/D/H2/chi' : Item("This is the file 'chi'.\n"),
- 'A/D/H2/omega' : Item("This is the file 'omega'.\n"),
- 'A/D/H2/psi' : Item("This is the file 'psi'.\n"),
+ 'A/D2' : Item(),
+ 'A/D2/gamma' : Item("This is the file 'gamma'.\n"),
+ 'A/D2/G' : Item(),
+ 'A/D2/H' : Item(),
+ 'A/D2/H/chi' : Item("This is the file 'chi'.\n"),
+ 'A/D2/H/omega' : Item("This is the file 'omega'.\n"),
+ 'A/D2/H/psi' : Item("This is the file 'psi'.\n"),
})
expected_status.add({
'A/B/F' : Item(status=' ', wc_rev='2'),
})
expected_status.tweak(wc_rev=2)
- expected_status.tweak('A/D/H2', 'A/D/H2/chi', 'A/D/H2/omega', 'A/D/H2/psi',
+ expected_status.tweak('A/D2', 'A/D2/gamma',
+ 'A/D2/H', 'A/D2/H/chi', 'A/D2/H/omega', 'A/D2/H/psi',
wc_rev='-')
+ expected_status.tweak('A/D2/G', 'A/D2/G/pi', 'A/D2/G/rho', 'A/D2/G/tau',
+ wc_rev='?')
svntest.actions.run_and_verify_update(wc_dir,
expected_output,
expected_disk,
@@ -592,10 +608,13 @@ def relocate_deleted_missing_copied(sbox
# Commit to verify that copyfrom URLs have been relocated
expected_output = svntest.wc.State(wc_dir, {
- 'A/D/H2' : Item(verb='Adding'),
+ 'A/D2' : Item(verb='Adding'),
+ 'A/D2/G' : Item(verb='Deleting'),
})
- expected_status.tweak('A/D/H2', 'A/D/H2/chi', 'A/D/H2/omega', 'A/D/H2/psi',
+ expected_status.tweak('A/D2', 'A/D2/gamma',
+ 'A/D2/H', 'A/D2/H/chi', 'A/D2/H/omega', 'A/D2/H/psi',
status=' ', wc_rev='3', copied=None)
+ expected_status.remove('A/D2/G', 'A/D2/G/pi', 'A/D2/G/rho', 'A/D2/G/tau')
svntest.actions.run_and_verify_commit(wc_dir,
expected_output, expected_status,
None, wc_dir)