You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/01/16 18:21:48 UTC
svn commit: r1434054 - in /subversion/trunk/subversion: libsvn_wc/status.c
tests/cmdline/stat_tests.py
Author: rhuijben
Date: Wed Jan 16 17:21:47 2013
New Revision: 1434054
URL: http://svn.apache.org/viewvc?rev=1434054&view=rev
Log:
Resolve a regression since 1.7.X where calling 'svn status' on a missing file
on a case-insensitive filesystem doesn't return the same information as
on its parent directory.
In <= 1.7 we always handled the root as a single target within its parent,
hiding all its siblings. This reverts us to this behavior on the only
point where we really need this for consistent output.
* subversion/libsvn_wc/status.c
(stat_wc_dirent_case_sensitive): New function.
(svn_wc__internal_walk_status,
internal_status): Use stat_wc_dirent_case_sensitive when checking the
target inside a working copy.
* subversion/tests/cmdline/stat_tests.py
(status_case_changed): New test.
(test_list): Add test.
Modified:
subversion/trunk/subversion/libsvn_wc/status.c
subversion/trunk/subversion/tests/cmdline/stat_tests.py
Modified: subversion/trunk/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=1434054&r1=1434053&r2=1434054&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/status.c (original)
+++ subversion/trunk/subversion/libsvn_wc/status.c Wed Jan 16 17:21:47 2013
@@ -2673,6 +2673,65 @@ svn_wc__get_status_editor(const svn_delt
return SVN_NO_ERROR;
}
+/* Like svn_io_stat_dirent, but works case sensitive inside working
+ copies. Before 1.8 we handled this with a selection filter inside
+ a directory */
+static svn_error_t *
+stat_wc_dirent_case_sensitive(const svn_io_dirent2_t **dirent,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+#if defined(WIN32) || defined(DARWIN)
+ svn_boolean_t is_wcroot;
+ /* We only need this code on systems with case insensitive filesystem
+ support. Enabling it unconditionally hurts performance */
+
+ /* The wcroot is "" inside the wc; handle it as not in the wc, as
+ the case of the root is indifferent to us. */
+ SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
+ scratch_pool));
+
+ if (! is_wcroot)
+ {
+ apr_hash_t *dirents;
+ svn_error_t *err;
+ const char *parent_abspath;
+ const char *name;
+
+ svn_dirent_split(&parent_abspath, &name, local_abspath, scratch_pool);
+
+ /* Obtain the name of the node, as stored in the directory.
+ Do this to avoid case insensitivity differences */
+
+ err = svn_io_get_dirents3(&dirents, parent_abspath, FALSE,
+ scratch_pool, scratch_pool);
+
+ if (err
+ && (APR_STATUS_IS_ENOENT(err->apr_err)
+ || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
+ {
+ svn_error_clear(err);
+ dirents = NULL;
+ }
+ else
+ SVN_ERR(err);
+
+ *dirent = dirents ? apr_hash_get(dirents, name, APR_HASH_KEY_STRING)
+ : NULL;
+
+ if (!*dirent)
+ *dirent = svn_io_dirent2_create(scratch_pool);
+
+ return SVN_NO_ERROR;
+ }
+#endif
+
+ return svn_error_trace(svn_io_stat_dirent(dirent, local_abspath, TRUE,
+ result_pool, scratch_pool));
+}
+
svn_error_t *
svn_wc__internal_walk_status(svn_wc__db_t *db,
const char *local_abspath,
@@ -2721,13 +2780,19 @@ svn_wc__internal_walk_status(svn_wc__db_
return svn_error_trace(err);
wb.externals = apr_hash_make(scratch_pool);
+
+ SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE, scratch_pool,
+ scratch_pool));
}
else
- SVN_ERR(svn_wc__db_externals_defined_below(&wb.externals, db, local_abspath,
- scratch_pool, scratch_pool));
+ {
+ SVN_ERR(svn_wc__db_externals_defined_below(&wb.externals,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
- SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
- scratch_pool, scratch_pool));
+ SVN_ERR(stat_wc_dirent_case_sensitive(&dirent, db, local_abspath,
+ scratch_pool, scratch_pool));
+ }
if (info
&& info->kind == svn_kind_dir
@@ -2868,9 +2933,6 @@ internal_status(svn_wc_status3_t **statu
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
- scratch_pool, scratch_pool));
-
err = svn_wc__db_read_info(&node_status, &node_kind, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
@@ -2878,19 +2940,25 @@ internal_status(svn_wc_status3_t **statu
db, local_abspath,
scratch_pool, scratch_pool);
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ if (err)
{
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_trace(err);
+
svn_error_clear(err);
node_kind = svn_kind_unknown;
/* Ensure conflicted is always set, but don't hide tree conflicts
on 'hidden' nodes. */
conflicted = FALSE;
+
+ SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
+ scratch_pool, scratch_pool));
}
- else if (err)
- {
- return svn_error_trace(err);
- }
- else if (node_status == svn_wc__db_status_not_present
+ else
+ SVN_ERR(stat_wc_dirent_case_sensitive(&dirent, db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (node_status == svn_wc__db_status_not_present
|| node_status == svn_wc__db_status_server_excluded
|| node_status == svn_wc__db_status_excluded)
{
Modified: subversion/trunk/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/stat_tests.py?rev=1434054&r1=1434053&r2=1434054&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/stat_tests.py Wed Jan 16 17:21:47 2013
@@ -1988,6 +1988,40 @@ def status_unversioned_dir(sbox):
svntest.actions.run_and_verify_svn2(None, [], expected_err, 0,
"status", "/")
+def status_case_changed(sbox):
+ "status reporting on case changed nodes directly"
+
+ sbox.build(read_only = True)
+ wc_dir = sbox.wc_dir
+
+ os.rename(sbox.ospath('iota'), sbox.ospath('iOTA'))
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.add({
+ 'iOTA' : Item(status='? '),
+ })
+ expected_status.tweak('iota', status='! ')
+
+ # First run status on the directory
+ svntest.actions.run_and_verify_unquiet_status(wc_dir,
+ expected_status)
+
+ # Now on the missing iota directly, which should give the same
+ # result, even on case insenstive filesystems
+ expected_status = svntest.wc.State(wc_dir, {
+ 'iota' : Item(status='! ', wc_rev=1),
+ })
+ svntest.actions.run_and_verify_unquiet_status(sbox.ospath('iota'),
+ expected_status)
+
+ # And on the unversioned iOTA
+ expected_status = svntest.wc.State(wc_dir, {
+ 'iOTA' : Item(status='? '),
+ })
+ svntest.actions.run_and_verify_unquiet_status(sbox.ospath('iOTA'),
+ expected_status)
+
+
########################################################################
# Run the tests
@@ -2033,6 +2067,7 @@ test_list = [ None,
modified_modulo_translation,
status_not_present,
status_unversioned_dir,
+ status_case_changed,
]
if __name__ == '__main__':