> Use SVN_ERR_ASSERT instead.

I fixed this in the attached patch.

> The apr_time_now call looks odd.  Do we need to change the file's
> timestamp in this case?

Do you think the file's fimestamp should be preserved afer removing the property?

> You also need to update the help text for 'svn ps' to describe the new
> property, see subversion/svn/svn.c.

I fixed this in the attached patch.

> and "if ("  not "if(".

I fixed this in the attached patch.

> svn diff -x-p
> , please?  That makes review easier.

I fixed this in the attached patch.

> Inheriting could be a later patch.  Another issue in the current patch
> is the use of apr_time_now when the property is removed; changing that
> affects the regression test.

I added a test in update_with_use_commit_times() at subversion/tests/cmdline/update_tests.py.

Regards.

--
Masaru Tsuchiyama<m.tma...@gmail.com>


Index: subversion/include/svn_props.h
===================================================================
--- subversion/include/svn_props.h      (revision 1509957)
+++ subversion/include/svn_props.h      (working copy)
@@ -412,6 +412,14 @@ svn_prop_name_is_valid(const char *prop_name);
  */
 #define SVN_PROP_SPECIAL_VALUE SVN_PROP_BOOLEAN_TRUE
 
+/** The value to force the executable property to when set.
+ *
+ * @deprecated Provided for backward compatibility with the 1.4 API.
+ * Use @c SVN_PROP_BOOLEAN_TRUE instead.
+ * @since New in 1.9.
+ */
+#define SVN_PROP_USE_COMMIT_TIMES_VALUE SVN_PROP_BOOLEAN_TRUE
+
 /** Describes external items to check out into this directory.
  *
  * The format is a series of lines, each in the following format:
@@ -449,6 +457,12 @@ svn_prop_name_is_valid(const char *prop_name);
 /** Property used to record inheritable configuration ignores. */
 #define SVN_PROP_INHERITABLE_IGNORES SVN_PROP_PREFIX "global-ignores"
 
+/**
+ * Property used to control whether timestamp of a file is modified to the 
commit time * @since New in 1.9.
+ * @since New in 1.9.
+ */
+#define SVN_PROP_USE_COMMIT_TIMES  SVN_PROP_PREFIX "use-commit-times"
+
 /** Meta-data properties.
  *
  * The following properties are used for storing meta-data about
@@ -509,7 +523,8 @@ svn_prop_name_is_valid(const char *prop_name);
                                 SVN_PROP_TEXT_TIME, \
                                 SVN_PROP_OWNER, \
                                 SVN_PROP_GROUP, \
-                                SVN_PROP_UNIX_MODE,
+                                SVN_PROP_UNIX_MODE, \
+                                SVN_PROP_USE_COMMIT_TIMES,
 
 /** @} */
 
Index: subversion/libsvn_subr/properties.c
===================================================================
--- subversion/libsvn_subr/properties.c (revision 1509957)
+++ subversion/libsvn_subr/properties.c (working copy)
@@ -446,7 +446,8 @@ svn_prop_is_boolean(const char *prop_name)
      make any speed difference.  */
   if (strcmp(prop_name, SVN_PROP_EXECUTABLE) == 0
       || strcmp(prop_name, SVN_PROP_NEEDS_LOCK) == 0
-      || strcmp(prop_name, SVN_PROP_SPECIAL) == 0)
+      || strcmp(prop_name, SVN_PROP_SPECIAL) == 0
+      || strcmp(prop_name, SVN_PROP_USE_COMMIT_TIMES) == 0)
     return TRUE;
   return FALSE;
 }
Index: subversion/libsvn_wc/props.c
===================================================================
--- subversion/libsvn_wc/props.c        (revision 1509957)
+++ subversion/libsvn_wc/props.c        (working copy)
@@ -2152,7 +2152,7 @@ svn_wc_canonicalize_svn_prop(const svn_string_t **
     }
   else if (svn_prop_is_boolean(propname))
     {
-      /* SVN_PROP_EXECUTABLE, SVN_PROP_NEEDS_LOCK, SVN_PROP_SPECIAL */
+      /* SVN_PROP_EXECUTABLE, SVN_PROP_NEEDS_LOCK, SVN_PROP_SPECIAL, 
SVN_PROP_USE_COMMIT_TIMES */
       propval = &boolean_value;
     }
   else if (strcmp(propname, SVN_PROP_MERGEINFO) == 0)
Index: subversion/libsvn_wc/update_editor.c
===================================================================
--- subversion/libsvn_wc/update_editor.c        (revision 1509957)
+++ subversion/libsvn_wc/update_editor.c        (working copy)
@@ -751,6 +751,12 @@ struct file_baton
 
   /* The tree conflict to install once the node is really edited */
   svn_skel_t *edit_conflict;
+
+  /* use-commit-times */
+  svn_boolean_t use_commit_times;
+
+  /* remove use-commit-times */
+  svn_boolean_t remove_use_commit_times;
 };
 
 
@@ -3830,6 +3836,17 @@ change_file_prop(void *file_baton,
           fb->already_notified = TRUE;
       }
     }
+  if (strcmp(name, SVN_PROP_USE_COMMIT_TIMES) == 0)
+    {
+        if (propchange->value)
+          {
+            fb->use_commit_times = TRUE;
+          }
+        else
+          {
+            fb->remove_use_commit_times = TRUE;
+          }
+    }
 
   return SVN_NO_ERROR;
 }
@@ -4636,6 +4653,24 @@ close_file(void *file_baton,
       eb->notify_func(eb->notify_baton, notify, scratch_pool);
     }
 
+  /* use_commit_times and remove_use_commit_times are mutably exclusive */
+  SVN_ERR_ASSERT( (fb->use_commit_times & fb->remove_use_commit_times) == 0 );
+  if ( !fb->adding_file )
+    {
+      if ( fb->use_commit_times && fb->changed_date )
+        {
+          SVN_ERR(svn_io_set_file_affected_time(fb->changed_date,
+                                                fb->local_abspath,
+                                                scratch_pool));
+        }
+      else if ( fb->remove_use_commit_times  )
+        {
+          SVN_ERR(svn_io_set_file_affected_time(apr_time_now(),
+                                                fb->local_abspath,
+                                                scratch_pool));
+        }
+    }
+
   svn_pool_destroy(fb->pool); /* Destroy scratch_pool */
 
   /* We have one less referrer to the directory */
Index: subversion/libsvn_wc/workqueue.c
===================================================================
--- subversion/libsvn_wc/workqueue.c    (revision 1509957)
+++ subversion/libsvn_wc/workqueue.c    (working copy)
@@ -638,6 +638,9 @@ run_file_install(work_item_baton_t *wqb,
         SVN_ERR(svn_io_set_file_read_only(local_abspath, FALSE, scratch_pool));
     }
 
+  if (props && svn_hash_gets(props, SVN_PROP_USE_COMMIT_TIMES))
+    use_commit_times = TRUE;
+
   if (use_commit_times)
     {
       if (changed_date)
Index: subversion/svn/svn.c
===================================================================
--- subversion/svn/svn.c        (revision 1509957)
+++ subversion/svn/svn.c        (working copy)
@@ -1340,6 +1340,8 @@ const svn_opt_subcommand_desc2_t svn_cl__cmd_table
      "      before it is modified.  Makes the working copy file read-only\n"
      "      when it is not locked.  Use 'svn propdel svn:needs-lock PATH...'\n"
      "      to clear.\n"
+     "    svn:use-commit-times - If present, make the timestamp of the file\n"
+     "       to commit time. Use 'svn propdel svn:use-commit-times PATH...' to 
clear.\n"
      "\n"
      "  Subversion recognizes the following special versioned properties on 
a\n"
      "  directory:\n"
Index: subversion/tests/cmdline/checkout_tests.py
===================================================================
--- subversion/tests/cmdline/checkout_tests.py  (revision 1509957)
+++ subversion/tests/cmdline/checkout_tests.py  (working copy)
@@ -1102,7 +1102,61 @@ def checkout_wc_from_drive(sbox):
     subprocess.call(['subst', '/D', drive +':'])
 
 #----------------------------------------------------------------------
+# Test checking out with svn:use-commit-times
+def checkout_with_use_commit_times(sbox):
+  "checkout with svn:use-commit-times"
 
+  sbox.build()
+  
+  # Create the revprop-change hook for this test
+  svntest.actions.enable_revprop_changes(sbox.repo_dir)
+
+  wc_dir = sbox.wc_dir
+  iota_path = sbox.ospath('iota')
+
+  svntest.actions.set_prop('svn:use-commit-times', '*', iota_path)
+
+  # Create expected output tree.
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(verb='Sending'),
+    })
+
+  # Commit the one file.
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        None,
+                                        None,
+                                        iota_path)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'propset', '--revprop', '-r2',
+                                     'svn:date', '2001-01-01T00:00:00.000000Z',
+                                     sbox.wc_dir)
+
+  # now checkout the repo in another folder
+  checkout_target = sbox.add_wc_path('checkout')
+  os.mkdir(checkout_target)
+
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.wc_dir = checkout_target
+  expected_output.tweak(status='A ', contents=None)
+  expected_wc = svntest.main.greek_state.copy()
+
+  svntest.actions.run_and_verify_checkout(sbox.repo_url,
+                                          checkout_target,
+                                          expected_output,
+                                          expected_wc)
+  secs_svn_date = time.mktime( (2001, 1, 1, 0, 0, 0, 0, 0, 0) )
+  secs_svn_date -=  time.timezone
+  new_iota = os.path.join(checkout_target, 'iota')
+  mtime = os.path.getmtime(new_iota)
+  
+  # check whether the timestamp of the file is expected value
+  if secs_svn_date != mtime:
+    raise svntest.Failure
+
+#----------------------------------------------------------------------
+
 # list all tests here, starting with None:
 test_list = [ None,
               checkout_with_obstructions,
@@ -1118,7 +1172,8 @@ test_list = [ None,
               checkout_peg_rev,
               checkout_peg_rev_date,
               co_with_obstructing_local_adds,
-              checkout_wc_from_drive
+              checkout_wc_from_drive,
+              checkout_with_use_commit_times
             ]
 
 if __name__ == "__main__":
Index: subversion/tests/cmdline/export_tests.py
===================================================================
--- subversion/tests/cmdline/export_tests.py    (revision 1509957)
+++ subversion/tests/cmdline/export_tests.py    (working copy)
@@ -27,6 +27,7 @@
 # General modules
 import os
 import tempfile
+import time
 
 # Our testing module
 import svntest
@@ -964,6 +965,63 @@ def export_custom_keywords(sbox):
   if open(export_file).read() != ''.join(alpha_content):
     raise svntest.Failure("wrong keyword expansion")
 
+
+#----------------------------------------------------------------------
+# Test exporting out with svn:use-commit-times
+def export_with_use_commit_times(sbox):
+  "export with svn:use-commit-times"
+
+  sbox.build()
+  
+  # Create the revprop-change hook for this test
+  svntest.actions.enable_revprop_changes(sbox.repo_dir)
+
+  wc_dir = sbox.wc_dir
+  iota_path = sbox.ospath('iota')
+
+  svntest.actions.set_prop('svn:use-commit-times', '*', iota_path)
+
+  # Create expected output tree.
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(verb='Sending'),
+    })
+
+  # Commit the one file.
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        None,
+                                        None,
+                                        iota_path)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'propset', '--revprop', '-r2',
+                                     'svn:date', '2001-01-01T00:00:00.000000Z',
+                                     sbox.wc_dir)
+
+  # now export the repo in another folder
+  export_target = sbox.add_wc_path('export')
+  expected_disk = svntest.main.greek_state.copy()
+  export_target = sbox.add_wc_path('export')
+
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.wc_dir = export_target
+  expected_output.desc[''] = Item()
+  expected_output.tweak(contents=None, status='A ')
+
+  svntest.actions.run_and_verify_export(sbox.repo_url,
+                                        export_target,
+                                        expected_output,
+                                        expected_disk)
+                                          
+  secs_svn_date = time.mktime( (2001, 1, 1, 0, 0, 0, 0, 0, 0) )
+  secs_svn_date -=  time.timezone
+  new_iota = os.path.join(export_target, 'iota')
+  mtime = os.path.getmtime(new_iota)
+  
+  # check whether the timestamp of the file is expected value
+  if secs_svn_date != mtime:
+    raise svntest.Failure
+
 ########################################################################
 # Run the tests
 
@@ -998,6 +1056,7 @@ test_list = [ None,
               export_to_current_dir,
               export_file_overwrite_with_force,
               export_custom_keywords,
+              export_with_use_commit_times,
              ]
 
 if __name__ == '__main__':
Index: subversion/tests/cmdline/prop_tests.py
===================================================================
--- subversion/tests/cmdline/prop_tests.py      (revision 1509957)
+++ subversion/tests/cmdline/prop_tests.py      (working copy)
@@ -901,6 +901,13 @@ def prop_value_conversions(sbox):
     svntest.actions.set_prop('svn:executable', pval, mu_path,
                              "svn: warning: W125005.*use 'svn propdel'")
 
+  # svn:use-commit-times value should be forced to a '*'
+  svntest.actions.set_prop('svn:use-commit-times', 'foo', iota_path)
+  svntest.actions.set_prop('svn:use-commit-times', '*', lambda_path)
+  for pval in ('      ', '', 'no', 'off', 'false'):
+    svntest.actions.set_prop('svn:use-commit-times', pval, mu_path,
+                             "svn: warning: W125005.*use 'svn propdel'")
+
   # Anything else should be untouched
   svntest.actions.set_prop('svn:some-prop', 'bar', lambda_path, force=True)
   svntest.actions.set_prop('svn:some-prop', ' bar baz', mu_path, force=True)
@@ -945,6 +952,11 @@ def prop_value_conversions(sbox):
   svntest.actions.check_prop('svn:executable', lambda_path, ['*'])
   svntest.actions.check_prop('svn:executable', mu_path, ['*'])
 
+  # Check svn:use-commit-times
+  svntest.actions.check_prop('svn:use-commit-times', iota_path, ['*'])
+  svntest.actions.check_prop('svn:use-commit-times', lambda_path, ['*'])
+  svntest.actions.check_prop('svn:use-commit-times', mu_path, ['*'])
+
   # Check other props
   svntest.actions.check_prop('svn:some-prop', lambda_path, ['bar'])
   svntest.actions.check_prop('svn:some-prop', mu_path, [' bar baz'])
Index: subversion/tests/cmdline/update_tests.py
===================================================================
--- subversion/tests/cmdline/update_tests.py    (revision 1509957)
+++ subversion/tests/cmdline/update_tests.py    (working copy)
@@ -6779,6 +6779,111 @@ def update_child_below_add(sbox):
                                         sbox.ospath('A/B/E'))
 
 
+#----------------------------------------------------------------------
+# Test updating out with svn:use-commit-times
+def update_with_use_commit_times(sbox):
+  "update with svn:use-commit-times"
+
+  sbox.build()
+  
+  # Create the revprop-change hook for this test
+  svntest.actions.enable_revprop_changes(sbox.repo_dir)
+
+  wc_dir = sbox.wc_dir
+  iota_path = sbox.ospath('iota')
+
+  # checkout the repo before setting 'svn:use-commit-times'
+  checkout_target = sbox.add_wc_path('checkout')
+  os.mkdir(checkout_target)
+
+  expected_output = svntest.main.greek_state.copy()
+  expected_output.wc_dir = checkout_target
+  expected_output.tweak(status='A ', contents=None)
+  expected_wc = svntest.main.greek_state.copy()
+
+  # checkout for updating before setting 'svn:use-commit-times'
+  svntest.actions.run_and_verify_checkout(sbox.repo_url,
+                                          checkout_target,
+                                          expected_output,
+                                          expected_wc)
+
+  # set 'svn:use-commit-times' to wc
+  svntest.actions.set_prop('svn:use-commit-times', '*', iota_path)
+
+  # Create expected output tree.
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota' : Item(verb='Sending'),
+    })
+
+  # Commit the one file.
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        None,
+                                        None,
+                                        iota_path)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'propset', '--revprop', '-r1',
+                                     'svn:date', '2001-01-01T00:00:00.000000Z',
+                                     sbox.wc_dir)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'propset', '--revprop', '-r2',
+                                     'svn:date', '2001-01-01T00:00:00.000000Z',
+                                     sbox.wc_dir)
+
+  # Update
+  expected_output = svntest.wc.State(checkout_target, {
+    'iota' : Item(status=' U'),
+    })
+  expected_output.wc_dir = checkout_target
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.wc_dir = checkout_target
+
+  expected_status = svntest.actions.get_virginal_state(checkout_target, 1)
+  expected_status.tweak('iota', wc_rev=2)
+
+  svntest.actions.run_and_verify_update(checkout_target,
+                                        None,
+                                        None,
+                                        None,
+                                        None, None, None, None, None, 0 )
+
+  secs_svn_date = time.mktime( (2001, 1, 1, 0, 0, 0, 0, 0, 0) )
+  secs_svn_date -=  time.timezone
+  new_iota = os.path.join(checkout_target, 'iota')
+  mtime = os.path.getmtime(new_iota)
+  
+  # check whether the timestamp of the file is expected value
+  if secs_svn_date != mtime:
+    raise svntest.Failure
+
+  # remove 'svn:use-commit-times' property test
+  svntest.main.run_svn(None, 'propdel', 'svn:use-commit-times', iota_path)
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        None,
+                                        None,
+                                        None,
+                                        iota_path)
+  # get current time before update
+  time_before_update = time.time()
+
+  # update
+  svntest.actions.run_and_verify_update(checkout_target,
+                                        None,
+                                        None,
+                                        None,
+                                        None, None, None, None, None, 0 )
+  # get current time after update
+  time_before_after = time.time()
+
+  mtime = os.path.getmtime(new_iota)
+
+  # check whether the timestamp of the file is between 'before update' and 
'after update'
+  if time_before_update > mtime or mtime > time_before_after:
+    raise svntest.Failure
+
 #######################################################################
 # Run the tests
 
@@ -6865,6 +6970,7 @@ test_list = [ None,
               update_moved_away,
               bump_below_tree_conflict,
               update_child_below_add,
+              update_with_use_commit_times,
              ]
 
 if __name__ == '__main__':

Reply via email to