You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2011/07/06 13:41:50 UTC
svn commit: r1143357 - in /subversion/trunk/subversion:
libsvn_wc/update_editor.c tests/cmdline/svntest/wc.py
tests/cmdline/switch_tests.py
Author: julianfoad
Date: Wed Jul 6 11:41:49 2011
New Revision: 1143357
URL: http://svn.apache.org/viewvc?rev=1143357&view=rev
Log:
Fix and test for a bug in switching a directory to a file. The repository
URL was not updated in the WC metadata, so 'svn status' did not show it as
switched and further operations involving the repository would not work.
This dir-to-file kind of switch was not checked by the test suite except in
switch_tests.py 9 which has always been XFAIL.
* subversion/libsvn_wc/update_editor.c
(make_file_baton): When calculating the new repository relpath, account
for switches in the same way as is done in make_dir_baton().
(set_target_revision): Remove a useless comment.
* subversion/tests/cmdline/svntest/wc.py
(State.remove): Tweak the doc string.
(State.remove_subtree): New function.
(State.subtree): Remove the limitation that the subtree path could only be
a single path element.
* subversion/tests/cmdline/switch_tests.py
(different_node_kind): New test function.
(test_list): Add it.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/tests/cmdline/svntest/wc.py
subversion/trunk/subversion/tests/cmdline/switch_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1143357&r1=1143356&r2=1143357&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed Jul 6 11:41:49 2011
@@ -773,6 +773,7 @@ make_file_baton(struct file_baton **f_p,
svn_boolean_t adding,
apr_pool_t *scratch_pool)
{
+ struct edit_baton *eb = pb->edit_baton;
apr_pool_t *file_pool = svn_pool_create(pb->pool);
struct file_baton *f = apr_pcalloc(file_pool, sizeof(*f));
@@ -785,17 +786,35 @@ make_file_baton(struct file_baton **f_p,
SVN_ERR(path_join_under_root(&f->local_abspath,
pb->local_abspath, f->name, file_pool));
- /* Figure out the new_URL for this file. */
- if (adding || pb->edit_baton->switch_relpath)
- f->new_relpath = svn_relpath_join(pb->new_relpath, f->name, file_pool);
- else
+ /* Figure out the new URL for this file. */
+ if (eb->switch_relpath)
{
- SVN_ERR(svn_wc__db_scan_base_repos(&f->new_relpath, NULL, NULL,
- pb->edit_baton->db,
- f->local_abspath,
- file_pool, scratch_pool));
+ /* Handle switches... */
- SVN_ERR_ASSERT(f->new_relpath);
+ /* This file has a parent directory. If there is
+ no grandparent, then we may have anchored at the parent,
+ and self is the target. If we match the target, then set
+ NEW_RELPATH to the SWITCH_RELPATH.
+
+ Otherwise, we simply extend NEW_RELPATH from the parent. */
+ if (pb->parent_baton == NULL
+ && strcmp(eb->target_basename, f->name) == 0)
+ f->new_relpath = eb->switch_relpath;
+ else
+ f->new_relpath = svn_relpath_join(pb->new_relpath, f->name,
+ file_pool);
+ }
+ else /* must be an update */
+ {
+ if (adding)
+ f->new_relpath = svn_relpath_join(pb->new_relpath, f->name, file_pool);
+ else
+ {
+ SVN_ERR(svn_wc__db_scan_base_repos(&f->new_relpath, NULL, NULL,
+ eb->db, f->local_abspath,
+ file_pool, scratch_pool));
+ SVN_ERR_ASSERT(f->new_relpath);
+ }
}
f->pool = file_pool;
@@ -1046,7 +1065,6 @@ set_target_revision(void *edit_baton,
{
struct edit_baton *eb = edit_baton;
- /* Stashing a target_revision in the baton */
*(eb->target_revision) = target_revision;
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/wc.py?rev=1143357&r1=1143356&r2=1143357&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/wc.py Wed Jul 6 11:41:49 2011
@@ -135,10 +135,18 @@ class State:
self.desc[path] = item
def remove(self, *paths):
- "Remove a path from the state (the path must exist)."
+ "Remove PATHS from the state (the paths must exist)."
for path in paths:
del self.desc[to_relpath(path)]
+ def remove_subtree(self, *paths):
+ "Remove PATHS recursively from the state (the paths must exist)."
+ for subtree_path in paths:
+ subtree_path = to_relpath(subtree_path)
+ for path, item in self.desc.items():
+ if path == subtree_path or path[:len(subtree_path) + 1] == subtree_path + '/':
+ del self.desc[path]
+
def copy(self, new_root=None):
"""Make a deep copy of self. If NEW_ROOT is not None, then set the
copy's wc_dir NEW_ROOT instead of to self's wc_dir."""
@@ -180,13 +188,12 @@ class State:
def subtree(self, subtree_path):
"""Return a State object which is a deep copy of the sub-tree
- identified by SUBTREE_PATH (which is assumed to contain only one
- element rooted at the tree of this State object's WC_DIR)."""
+ beneath SUBTREE_PATH (which is assumed to be rooted at the tree of
+ this State object's WC_DIR). Exclude SUBTREE_PATH itself."""
desc = { }
for path, item in self.desc.items():
- path_elements = path.split("/")
- if len(path_elements) > 1 and path_elements[0] == subtree_path:
- desc["/".join(path_elements[1:])] = item.copy()
+ if path[:len(subtree_path) + 1] == subtree_path + '/':
+ desc[path[len(subtree_path) + 1:]] = item.copy()
return State(self.wc_dir, desc)
def write_to_disk(self, target_dir):
Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=1143357&r1=1143356&r2=1143357&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Wed Jul 6 11:41:49 2011
@@ -2856,6 +2856,56 @@ def up_to_old_rev_with_subtree_switched_
# Now update the WC to r1.
svntest.actions.run_and_verify_svn(None, None, [], 'up', '-r1', wc_dir)
+def different_node_kind(sbox):
+ "switch to a different node kind"
+ sbox.build(read_only = True)
+ os.chdir(sbox.wc_dir)
+ sbox.wc_dir = ''
+
+ pristine_disk = svntest.main.greek_state
+ pristine_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+ expected_disk = pristine_disk.copy()
+ expected_status = pristine_status.copy()
+
+ def switch_to_dir(sbox, rel_url, rel_path):
+ full_url = sbox.repo_url + '/' + rel_url
+ full_path = sbox.ospath(rel_path)
+ expected_disk.remove(rel_path)
+ expected_disk.add({ rel_path : pristine_disk.desc[rel_url] })
+ expected_disk.add_state(rel_path, pristine_disk.subtree(rel_url))
+ expected_status.tweak(rel_path, switched='S')
+ expected_status.add_state(rel_path, pristine_status.subtree(rel_url))
+ svntest.actions.run_and_verify_switch(sbox.wc_dir, full_path, full_url,
+ None, expected_disk, expected_status,
+ None, None, None, None, None, False,
+ '--ignore-ancestry')
+ svntest.actions.run_and_verify_svn(None, None, [], 'info', full_path)
+ if not os.path.isdir(full_path):
+ raise svntest.Failure
+
+ def switch_to_file(sbox, rel_url, rel_path):
+ full_url = sbox.repo_url + '/' + rel_url
+ full_path = sbox.ospath(rel_path)
+ expected_disk.remove_subtree(rel_path)
+ expected_disk.add({ rel_path : pristine_disk.desc[rel_url] })
+ expected_status.remove_subtree(rel_path)
+ expected_status.add({ rel_path : pristine_status.desc[rel_url] })
+ expected_status.tweak(rel_path, switched='S')
+ svntest.actions.run_and_verify_switch(sbox.wc_dir, full_path, full_url,
+ None, expected_disk, expected_status,
+ None, None, None, None, None, False,
+ '--ignore-ancestry')
+ svntest.actions.run_and_verify_svn(None, None, [], 'info', full_path)
+ if not os.path.isfile(full_path):
+ raise svntest.Failure
+
+ # Switch two files to dirs and two dirs to files.
+ # 'A/C' is an empty dir; 'A/D/G' is a non-empty dir.
+ switch_to_dir(sbox, 'A/C', 'iota')
+ switch_to_dir(sbox, 'A/D/G', 'A/D/gamma')
+ switch_to_file(sbox, 'iota', 'A/C')
+ switch_to_file(sbox, 'A/D/gamma', 'A/D/G')
+
########################################################################
# Run the tests
@@ -2895,6 +2945,7 @@ test_list = [ None,
tree_conflicts_on_switch_3,
copy_with_switched_subdir,
up_to_old_rev_with_subtree_switched_to_root,
+ different_node_kind,
]
if __name__ == '__main__':