You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2014/05/21 18:54:17 UTC

svn commit: r1596616 - in /subversion/trunk/subversion: libsvn_wc/update_editor.c tests/cmdline/switch_tests.py

Author: stsp
Date: Wed May 21 16:54:16 2014
New Revision: 1596616

URL: http://svn.apache.org/r1596616
Log:
Re-apply a fixed version of the changes from r1596591 which were
reverted in r1596592. This version handles locally modified files
properly, rather than overwriting local changes as r1596591 did.
The regression test has also been expanded to cover local mods.

Fix issue #1975, "svn switch does not update keywords".

* subversion/libsvn_wc/update_editor.c
  (update_keywords_after_switch_cb): New helper function
   which checks for the presence of an svn:keywords property
   and queues an install_file work queue item if present.
   Thus, when the work queue is run to complete the switch
   operation, all files with keywords will go through the
   translation process.
  (close_edit): If this is a switch operation, run a recursive
   proplist with the specified depth (infinity by default),
   invocing update_keywords_after_switch_cb() for each node
   with properties.

* subversion/tests/cmdline/switch_tests.py
  (switch_keywords, test_list): New test. Fails without
   the above change and passes with it.

Modified:
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    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=1596616&r1=1596615&r2=1596616&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed May 21 16:54:16 2014
@@ -4691,6 +4691,78 @@ close_file(void *file_baton,
 }
 
 
+/* Implements svn_wc__proplist_receiver_t.
+ * Check for the presence of an svn:keywords property and queues an install_file
+ * work queue item if present. Thus, when the work queue is run to complete the
+ * switch operation, all files with keywords will go through the translation
+ * process so URLs etc are updated. */
+static svn_error_t *
+update_keywords_after_switch_cb(void *baton,
+                                const char *local_abspath,
+                                apr_hash_t *props,
+                                apr_pool_t *scratch_pool)
+{
+  struct edit_baton *eb = baton;
+  svn_string_t *propval;
+  svn_boolean_t modified;
+  svn_boolean_t record_fileinfo;
+  svn_skel_t *work_items;
+  const char *install_from;
+
+  propval = svn_hash_gets(props, SVN_PROP_KEYWORDS);
+  if (!propval)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(svn_wc__internal_file_modified_p(&modified, eb->db,
+                                           local_abspath, FALSE,
+                                           scratch_pool));
+  if (modified)
+    {
+      const char *temp_dir_abspath;
+      svn_stream_t *working_stream;
+      svn_stream_t *install_from_stream;
+
+      SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, eb->db,
+                                             local_abspath, scratch_pool,
+                                             scratch_pool));
+      SVN_ERR(svn_stream_open_readonly(&working_stream, local_abspath,
+                                       scratch_pool, scratch_pool));
+      SVN_ERR(svn_stream_open_unique(&install_from_stream, &install_from,
+                                     temp_dir_abspath, svn_io_file_del_none,
+                                     scratch_pool, scratch_pool));
+      SVN_ERR(svn_stream_copy3(working_stream, install_from_stream,
+                               eb->cancel_func, eb->cancel_baton,
+                               scratch_pool));
+      record_fileinfo = FALSE;
+    }
+  else
+    {
+      install_from = NULL;
+      record_fileinfo = TRUE;
+    }
+    
+  SVN_ERR(svn_wc__wq_build_file_install(&work_items, eb->db, local_abspath,
+                                        install_from,
+                                        eb->use_commit_times,
+                                        record_fileinfo,
+                                        scratch_pool, scratch_pool));
+  if (install_from)
+    {
+      svn_skel_t *work_item;
+
+      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
+                                           local_abspath, install_from,
+                                           scratch_pool, scratch_pool));
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+    }
+
+  SVN_ERR(svn_wc__db_wq_add(eb->db, local_abspath, work_items,
+                            scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
 /* An svn_delta_editor_t function. */
 static svn_error_t *
 close_edit(void *edit_baton,
@@ -4787,6 +4859,29 @@ close_edit(void *edit_baton,
         }
     }
 
+  /* Update keywords in switched files.
+     GOTO #1975 (the year of the Altair 8800). */
+  if (eb->switch_repos_relpath)
+    {
+      svn_depth_t depth;
+      
+      if (eb->requested_depth > svn_depth_empty)
+        depth = eb->requested_depth;
+      else
+        depth = svn_depth_infinity;
+
+      SVN_ERR(svn_wc__db_read_props_streamily(eb->db,
+                                              eb->target_abspath,
+                                              depth,
+                                              FALSE, /* pristine */
+                                              NULL, /* changelists */
+                                              update_keywords_after_switch_cb,
+                                              eb,
+                                              eb->cancel_func,
+                                              eb->cancel_baton,
+                                              scratch_pool));
+    }
+
   /* The edit is over: run the wq with proper cancel support,
      but first kill the handler that would run it on the pool
      cleanup at the end of this function. */

Modified: subversion/trunk/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/switch_tests.py?rev=1596616&r1=1596615&r2=1596616&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/switch_tests.py Wed May 21 16:54:16 2014
@@ -2766,6 +2766,94 @@ def switch_across_replacement(sbox):
                                         None, None, None, None, None, False,
                                         '-r1')
 
+@Issue(1975)
+def switch_keywords(sbox):
+  "switch and svn:keywords"
+  sbox.build()
+  gamma_path = sbox.ospath('A/D/gamma')
+  psi_path = sbox.ospath('A/D/H/psi')
+
+  sbox.simple_propset('svn:keywords', 'URL', 'A/D/gamma')
+  svntest.main.file_write(gamma_path, "$URL$\n")
+  sbox.simple_propset('svn:keywords', 'URL', 'A/D/H/psi')
+  svntest.main.file_write(psi_path, "$URL$\n")
+  sbox.simple_commit()
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('A/D/gamma',
+                      contents="$URL: %s/A/D/gamma $\n" % sbox.repo_url)
+  expected_disk.tweak('A/D/H/psi',
+                      contents="$URL: %s/A/D/H/psi $\n" % sbox.repo_url)
+
+  svntest.actions.run_and_verify_update(sbox.wc_dir,
+                                        None, expected_disk,
+                                        None, None, None, None, None, None)
+  sbox.simple_copy('A', 'A_copy')
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  # Next, we're going to switch A to A_copy, and expect keywords
+  # in the switched files gamma and psi to be updated accordingly.
+
+  expected_disk.add({
+    'A_copy/D/H/chi'    : Item(contents="This is the file 'chi'.\n"),
+    'A_copy/D/H/psi'    : Item(contents="$URL: %s/A_copy/D/H/psi $\n"
+                                        % sbox.repo_url),
+    'A_copy/D/H/omega'  : Item(contents="This is the file 'omega'.\n"),
+    'A_copy/D/G/pi'     : Item(contents="This is the file 'pi'.\n"),
+    'A_copy/D/G/tau'    : Item(contents="This is the file 'tau'.\n"),
+    'A_copy/D/G/rho'    : Item(contents="This is the file 'rho'.\n"),
+    'A_copy/D/gamma'    : Item(contents="$URL: %s/A_copy/D/gamma $\n"
+                                        % sbox.repo_url),
+    'A_copy/B/F'        : Item(),
+    'A_copy/B/E/alpha'  : Item(contents="This is the file 'alpha'.\n"),
+    'A_copy/B/E/beta'   : Item(contents="This is the file 'beta'.\n"),
+    'A_copy/B/lambda'   : Item(contents="This is the file 'lambda'.\n"),
+    'A_copy/mu'         : Item(contents="This is the file 'mu'.\n"),
+    'A_copy/C'          : Item(),
+    })
+
+  # update expected URL for switched gamma
+  expected_disk.tweak('A/D/gamma',
+                      contents="$URL: %s/A_copy/D/gamma $\n" % sbox.repo_url)
+
+  # leave gamma unmodified, locally modify psi
+  svntest.main.file_write(psi_path, "$URL$\nnew line\n")
+  # update expected URL for switched psi
+  expected_disk.tweak('A/D/H/psi',
+                      contents="$URL: %s/A_copy/D/H/psi $\nnew line\n"
+                               % sbox.repo_url)
+
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 3)
+  expected_status.add({
+    'A_copy'            : Item(status='  ', wc_rev='3'),
+    'A_copy/mu'         : Item(status='  ', wc_rev='3'),
+    'A_copy/D'          : Item(status='  ', wc_rev='3'),
+    'A_copy/D/H'        : Item(status='  ', wc_rev='3'),
+    'A_copy/D/H/psi'    : Item(status='  ', wc_rev='3'),
+    'A_copy/D/H/chi'    : Item(status='  ', wc_rev='3'),
+    'A_copy/D/H/omega'  : Item(status='  ', wc_rev='3'),
+    'A_copy/D/gamma'    : Item(status='  ', wc_rev='3'),
+    'A_copy/D/G'        : Item(status='  ', wc_rev='3'),
+    'A_copy/D/G/rho'    : Item(status='  ', wc_rev='3'),
+    'A_copy/D/G/tau'    : Item(status='  ', wc_rev='3'),
+    'A_copy/D/G/pi'     : Item(status='  ', wc_rev='3'),
+    'A_copy/B'          : Item(status='  ', wc_rev='3'),
+    'A_copy/B/E'        : Item(status='  ', wc_rev='3'),
+    'A_copy/B/E/alpha'  : Item(status='  ', wc_rev='3'),
+    'A_copy/B/E/beta'   : Item(status='  ', wc_rev='3'),
+    'A_copy/B/F'        : Item(status='  ', wc_rev='3'),
+    'A_copy/B/lambda'   : Item(status='  ', wc_rev='3'),
+    'A_copy/C'          : Item(status='  ', wc_rev='3'),
+  })
+  expected_status.tweak('A', switched='S')
+  expected_status.tweak('A/D/H/psi', status='M ')
+
+  # both gamma and psi should have update URLs after the switch
+  svntest.actions.run_and_verify_switch(sbox.wc_dir, sbox.ospath('A'), '^/A_copy',
+                                        None, expected_disk, expected_status,
+                                        None, None, None, None, None)
+
 ########################################################################
 # Run the tests
 
@@ -2808,6 +2896,7 @@ test_list = [ None,
               different_node_kind,
               switch_to_spaces,
               switch_across_replacement,
+              switch_keywords,
               ]
 
 if __name__ == '__main__':