I'd like to get the "is this WC mixed revision?" and "is this WC switched?"
bits without stat()-ing every single file in the worktree.

Patch enclosed.

It still prints 'M' when there's a tree mod or a prop mod.  In my use-case
I actually throw that out: I use it as «svnversion --no-stat | sed s/M//».

Cheers,

Daniel


[[[
svnversion: Grow a new option to not stat() the WORKING tree.

* subversion/include/svn_wc.h
  (svn_wc_revision_status2): Deprecate.
  (svn_wc_revision_status3): New.

* subversion/libsvn_wc/revision_status.c
  (svn_wc_revision_status2): Deprecate.
  (svn_wc_revision_status3): New.

* subversion/svnversion/svnversion.c
  (SVNVERSION_OPT_VERSION): Changed from macro to enumerator.
  (SVNVERSION_OPT_NO_STAT): New enumerator.
  (sub_main): Declare and parse a new option, --no-stat.

* subversion/tests/cmdline/svnversion_tests.py
  (no_stat): New test.
  (test_list): Run it.
]]]

[[[
Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h (revision 1870656)
+++ subversion/include/svn_wc.h (working copy)
@@ -8176,7 +8176,8 @@ typedef struct svn_wc_revision_status_t
  * status.
  *
  * Set @a (*result_p)->modified to indicate whether any item is locally
- * modified.
+ * modified. If @a may_stat is @c TRUE, do a full check; otherwise, check the
+ * working copy database only, but don't look for text modifications on-disk.
  *
  * If @a cancel_func is non-NULL, call it with @a cancel_baton to determine
  * if the client has canceled the operation.
@@ -8186,6 +8187,24 @@ typedef struct svn_wc_revision_status_t
  *
  * @a wc_ctx should be a valid working copy context.
  *
+ * @since New in 1.14
+ */
+svn_error_t *
+svn_wc_revision_status3(svn_wc_revision_status_t **result_p,
+                        svn_wc_context_t *wc_ctx,
+                        const char *local_abspath,
+                        const char *trail_url,
+                        svn_boolean_t committed,
+                        svn_boolean_t may_stat,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool);
+
+/** Similar to svn_wc_revision_status2(), but with @a may_stat
+ * set to @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.13 API.
  * @since New in 1.7
  */
 svn_error_t *
Index: subversion/libsvn_wc/revision_status.c
===================================================================
--- subversion/libsvn_wc/revision_status.c      (revision 1870656)
+++ subversion/libsvn_wc/revision_status.c      (working copy)
@@ -32,11 +32,12 @@
 #include "svn_private_config.h"
 
 svn_error_t *
-svn_wc_revision_status2(svn_wc_revision_status_t **result_p,
+svn_wc_revision_status3(svn_wc_revision_status_t **result_p,
                         svn_wc_context_t *wc_ctx,
                         const char *local_abspath,
                         const char *trail_url,
                         svn_boolean_t committed,
+                        svn_boolean_t may_stat,
                         svn_cancel_func_t cancel_func,
                         void *cancel_baton,
                         apr_pool_t *result_pool,
@@ -63,11 +64,28 @@ svn_error_t *
                                      committed,
                                      scratch_pool));
 
-  if (!result->modified)
+  if (!result->modified && may_stat)
     SVN_ERR(svn_wc__node_has_local_mods(&result->modified, NULL,
                                         wc_ctx->db, local_abspath, TRUE,
                                         cancel_func, cancel_baton,
                                         scratch_pool));
 
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc_revision_status2(svn_wc_revision_status_t **result_p,
+                        svn_wc_context_t *wc_ctx,
+                        const char *local_abspath,
+                        const char *trail_url,
+                        svn_boolean_t committed,
+                        svn_cancel_func_t cancel_func,
+                        void *cancel_baton,
+                        apr_pool_t *result_pool,
+                        apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc_revision_status3(result_p, wc_ctx, local_abspath, trail_url,
+                                  committed, TRUE, cancel_func, cancel_baton,
+                                  result_pool, scratch_pool));
   return SVN_NO_ERROR;
 }
Index: subversion/svnversion/svnversion.c
===================================================================
--- subversion/svnversion/svnversion.c  (revision 1870656)
+++ subversion/svnversion/svnversion.c  (working copy)
@@ -32,7 +32,10 @@
 
 #include "svn_private_config.h"
 
-#define SVNVERSION_OPT_VERSION SVN_OPT_FIRST_LONGOPT_ID
+enum {
+  SVNVERSION_OPT_VERSION = SVN_OPT_FIRST_LONGOPT_ID,
+  SVNVERSION_OPT_NO_STAT
+};
 
 
 static svn_error_t *
@@ -135,10 +138,13 @@ sub_main(int *exit_code, int argc, const char *arg
   svn_wc_context_t *wc_ctx;
   svn_boolean_t quiet = FALSE;
   svn_boolean_t is_version = FALSE;
+  svn_boolean_t may_stat = TRUE;
   const apr_getopt_option_t options[] =
     {
       {"no-newline", 'n', 0, N_("do not output the trailing newline")},
       {"committed",  'c', 0, N_("last changed rather than current revisions")},
+      {"no-stat", SVNVERSION_OPT_NO_STAT, 0,
+        N_("don't check the working files for modifications")},
       {"help", 'h', 0, N_("display this help")},
       {"version", SVNVERSION_OPT_VERSION, 0,
        N_("show program version information")},
@@ -192,6 +198,9 @@ sub_main(int *exit_code, int argc, const char *arg
         case SVNVERSION_OPT_VERSION:
           is_version = TRUE;
           break;
+        case SVNVERSION_OPT_NO_STAT:
+          may_stat = FALSE;
+          break;
         default:
           *exit_code = EXIT_FAILURE;
           usage(pool);
@@ -224,8 +233,8 @@ sub_main(int *exit_code, int argc, const char *arg
   else
     trail_url = NULL;
 
-  err = svn_wc_revision_status2(&res, wc_ctx, local_abspath, trail_url,
-                                committed, NULL, NULL, pool, pool);
+  err = svn_wc_revision_status3(&res, wc_ctx, local_abspath, trail_url,
+                                committed, may_stat, NULL, NULL, pool, pool);
 
   if (err && (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND
               || err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY))
Index: subversion/tests/cmdline/svnversion_tests.py
===================================================================
--- subversion/tests/cmdline/svnversion_tests.py        (revision 1870656)
+++ subversion/tests/cmdline/svnversion_tests.py        (working copy)
@@ -377,6 +377,33 @@ def child_switched(sbox):
   svntest.actions.run_and_verify_svnversion(os.path.join(wc_dir, 'D', 'H'),
                                             None, [ "2\n" ], [])
 
+def no_stat(sbox):
+  "test '--no-stat'"
+  sbox.build(read_only = True)
+  wc_dir = sbox.wc_dir
+
+  verify = lambda expected_output: \
+    svntest.actions.run_and_verify_svnversion(wc_dir, None, expected_output,
+                                              [], '--no-stat', '--no-newline')
+
+  # Baseline:
+  verify(['1'])
+
+  # Property change gets reported
+  sbox.simple_propset('k', 'v', 'iota')
+  verify(['1M'])
+  sbox.simple_revert('iota')
+
+  # Tree changes get reported
+  sbox.simple_rm('iota')
+  verify(['1M'])
+  sbox.simple_revert('iota')
+
+  # Text mods do NOT get reported: the output shall not include 'M'.
+  sbox.simple_append('iota', b'This file is locally modified.\n')
+  verify(['1'])
+  sbox.simple_revert('iota')
+
 ########################################################################
 # Run the tests
 
@@ -390,6 +417,7 @@ test_list = [ None,
               committed_revisions,
               non_reposroot_wc,
               child_switched,
+              no_stat,
              ]
 
 if __name__ == '__main__':
]]]

Reply via email to