Author: rhuijben
Date: Tue May 10 14:31:45 2011
New Revision: 1101473

URL: http://svn.apache.org/viewvc?rev=1101473&view=rev
Log:
In general svn_wc__internal_file_modified_p() should be called with
compare_text_bases TRUE, as that is what a normal user would call a
modified file.

In other words it should ignore keyword expansion differences and eol
differences, as we would do that on commit and status.

Then we have a property that indicates whether we should use recorded
information or not, which we only use to specialize svn:eol-style in
the commit processing to hide a few bugs.

But for svn:keywords we do a similar thing, but we do that when updating
the property value. (Which doesn't trigger on merges)

Summarized: This moves the recording fixes to the two places where we set
properties. And this makes us always use the recorded information from the
public api. Adds a simple to explain boolean to check if the file matches
what you would get if you restored the file.

* subversion/libsvn_client/commit_util.c
  (harvest_committables): Remove eol checks. (Handled by libsvn_wc now,
     just like svn:keywords).

* subversion/libsvn_wc/adm_ops.c
  (revert_restore): Do an exact match check.
  (svn_wc__internal_remove_from_version_control): This function is only used
    from svn_wc_crop and when removing working copies, so stop doing work that
    isn't relevant there. Use recursive delete when we find a deleted node.
    Only call svn_wc__adm_destroy when we really destroy the wc.

* subversion/libsvn_wc/cleanup.c
  (repair_timestamps): Convert to repository form for timestamp repair.

* subversion/libsvn_wc/copy.c
  (svn_wc__internal_file_modified_p): Convert to repository form for copy
     repair.

* subversion/libsvn_wc/diff_editor.c
  (file_diff): Update caller.

* subversion/libsvn_wc/diff_local.c
  (file_diff): Update caller.

* subversion/libsvn_wc/externals.c
  (close_file): Update caller. Do the right check.

* subversion/libsvn_wc/props.c
  (svn_wc__perform_props_merge): Just clear recorded information on magic
    property changes.
  (do_propset): Handle eol changes like we do keyword changes, but make
    wc_db do the hard work in one atomic step.

* subversion/libsvn_wc/questions.c
  (compare_and_verify): Remove unused checksum verfication. (Should be handled
    by a pristine verification).
  (svn_wc__internal_file_modified_p): Update arguments.
  (svn_wc_text_modified_p2): Update caller add note.
    (argument will be removed in a followup commit).

* subversion/libsvn_wc/status.c
  (assemble_status): Update caller.

* subversion/libsvn_wc/update_editor.c
  (merge_file): Update caller.
  (svn_wc_add_repos_file4): Update caller.

* subversion/libsvn_wc/wc.h
  (svn_wc__internal_file_modified_p): Update documentation.

* subversion/libsvn_wc/wc_db.c
  (record_baton_t): Moved up in the file, to allow reuse.
  (db_record_fileinfo): Added db_ prefix and moved up to allow reuse.
  (svn_wc__db_global_record_fileinfo): Moved.

  (set_props_baton_t): Add clear_recorded_info boolean.
  (set_props_txn): Clear recorded info if requested.
  (svn_wc__db_op_set_props): Add argument.
  (record_baton_t, record_fileinfo,
   svn_wc__db_global_record_fileinfo): Moved up.

  (has_local_mods): Update caller.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_op_set_props): Add argument and update documentation.

* subversion/libsvn_wc/workqueue.c
  (process_commit_file_install): Update caller. As the result is only used to
    update the cache it shouldn't use exact comparison.

* subversion/tests/libsvn_wc/db-test.c
  (validate_node): Update caller.

Modified:
    subversion/trunk/subversion/libsvn_client/commit_util.c
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/cleanup.c
    subversion/trunk/subversion/libsvn_wc/copy.c
    subversion/trunk/subversion/libsvn_wc/diff_editor.c
    subversion/trunk/subversion/libsvn_wc/diff_local.c
    subversion/trunk/subversion/libsvn_wc/externals.c
    subversion/trunk/subversion/libsvn_wc/props.c
    subversion/trunk/subversion/libsvn_wc/questions.c
    subversion/trunk/subversion/libsvn_wc/status.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc.h
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h
    subversion/trunk/subversion/libsvn_wc/workqueue.c
    subversion/trunk/subversion/tests/libsvn_wc/db-test.c

Modified: subversion/trunk/subversion/libsvn_client/commit_util.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit_util.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit_util.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit_util.c Tue May 10 14:31:45 
2011
@@ -142,35 +142,6 @@ add_committable(svn_client__committables
   return SVN_NO_ERROR;
 }
 
-
-static svn_error_t *
-check_prop_mods(svn_boolean_t *props_changed,
-                svn_boolean_t *eol_prop_changed,
-                const char *local_abspath,
-                svn_wc_context_t *wc_ctx,
-                apr_pool_t *pool)
-{
-  apr_array_header_t *prop_mods;
-  int i;
-
-  *eol_prop_changed = *props_changed = FALSE;
-  SVN_ERR(svn_wc_get_prop_diffs2(&prop_mods, NULL, wc_ctx, local_abspath,
-                                 pool, pool));
-  if (prop_mods->nelts == 0)
-    return SVN_NO_ERROR;
-
-  *props_changed = TRUE;
-  for (i = 0; i < prop_mods->nelts; i++)
-    {
-      svn_prop_t *prop_mod = &APR_ARRAY_IDX(prop_mods, i, svn_prop_t);
-      if (strcmp(prop_mod->name, SVN_PROP_EOL_STYLE) == 0)
-        *eol_prop_changed = TRUE;
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
 /* If there is a commit item for PATH in COMMITTABLES, return it, else
    return NULL.  Use POOL for temporary allocation only. */
 static svn_client_commit_item3_t *
@@ -568,8 +539,6 @@ harvest_committables(svn_wc_context_t *w
      information about it. */
   if (state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
     {
-      svn_boolean_t eol_prop_changed = FALSE;
-
       /* First of all, the working file or directory must exist.
          See issue #3198. */
       if (working_kind == svn_node_none)
@@ -580,25 +549,14 @@ harvest_committables(svn_wc_context_t *w
              svn_dirent_local_style(local_abspath, scratch_pool));
         }
 
-      /* If there are property modifications, check if eol-style changed. */
-      if (prop_mod)
-        SVN_ERR(check_prop_mods(&prop_mod, &eol_prop_changed, local_abspath,
-                                wc_ctx, scratch_pool));
-
       /* Regular adds of files have text mods, but for copies we have
          to test for textual mods.  Directories simply don't have text! */
       if (db_kind == svn_node_file)
         {
-          /* Check for text mods.  If EOL_PROP_CHANGED is TRUE, then
-             we need to force a translated byte-for-byte comparison
-             against the text-base so that a timestamp comparison
-             won't bail out early.  Depending on how the svn:eol-style
-             prop was changed, we might have to send new text to the
-             server to match the new newline style.  */
+          /* Check for text mods.  */
           if (state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
-            SVN_ERR(svn_wc_text_modified_p2(&text_mod, wc_ctx,
-                                            local_abspath, eol_prop_changed,
-                                            scratch_pool));
+            SVN_ERR(svn_wc_text_modified_p2(&text_mod, wc_ctx, local_abspath,
+                                            FALSE, scratch_pool));
           else
             text_mod = TRUE;
         }
@@ -609,15 +567,6 @@ harvest_committables(svn_wc_context_t *w
      committable. */
   else if (! (state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))
     {
-      svn_boolean_t eol_prop_changed;
-
-      /* See if there are property modifications to send. */
-      if (prop_mod)
-        SVN_ERR(check_prop_mods(&prop_mod, &eol_prop_changed, local_abspath,
-                                wc_ctx, scratch_pool));
-      else
-        eol_prop_changed = FALSE;
-
       /* Check for text mods on files.  If EOL_PROP_CHANGED is TRUE,
          then we need to force a translated byte-for-byte comparison
          against the text-base so that a timestamp comparison won't
@@ -626,7 +575,7 @@ harvest_committables(svn_wc_context_t *w
          match the new newline style.  */
       if (db_kind == svn_node_file)
         SVN_ERR(svn_wc_text_modified_p2(&text_mod, wc_ctx, local_abspath,
-                                        eol_prop_changed, scratch_pool));
+                                        FALSE, scratch_pool));
     }
 
   /* Set text/prop modification flags accordingly. */

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue May 10 14:31:45 2011
@@ -1401,11 +1401,13 @@ revert_restore(svn_wc__db_t *db,
             }
           else
             {
+              /* This compares the file against a pristine version of the
+                 translated file. So it will return modified in all cases
+                 where delete+restore would install a different file */
               SVN_ERR(svn_wc__internal_file_modified_p(&modified, &executable,
                                                        &read_only,
                                                        db, local_abspath,
-                                                       FALSE, FALSE,
-                                                       scratch_pool));
+                                                       TRUE, scratch_pool));
               if (modified)
                 {
                   SVN_ERR(svn_io_remove_file2(local_abspath, FALSE,
@@ -1903,93 +1905,32 @@ svn_wc__internal_remove_from_revision_co
 
   if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
     {
-      svn_node_kind_t on_disk;
-      svn_boolean_t text_modified_p;
-      const svn_checksum_t *base_sha1_checksum, *working_sha1_checksum;
+      svn_boolean_t text_modified_p = FALSE;
 
       if (instant_error || destroy_wf)
         {
-          svn_boolean_t wc_special, local_special;
-          /* Only check if the file was modified when it wasn't overwritten
-             with a special file */
-
-          SVN_ERR(svn_wc__get_translate_info(NULL, NULL, NULL,
-                                             &wc_special,
-                                             db, local_abspath, NULL, TRUE,
-                                             scratch_pool, scratch_pool));
-          SVN_ERR(svn_io_check_special_path(local_abspath, &on_disk,
-                                            &local_special, scratch_pool));
-          if (wc_special || ! local_special)
+          svn_node_kind_t on_disk;
+          SVN_ERR(svn_io_check_path(local_abspath, &on_disk, scratch_pool));
+          if (on_disk == svn_node_file)
             {
               /* Check for local mods. before removing entry */
               SVN_ERR(svn_wc__internal_file_modified_p(&text_modified_p, NULL,
                                                        NULL, db,
                                                        local_abspath, FALSE,
-                                                       TRUE, scratch_pool));
+                                                       scratch_pool));
               if (text_modified_p && instant_error)
                 return svn_error_createf(SVN_ERR_WC_LEFT_LOCAL_MOD, NULL,
                        _("File '%s' has local modifications"),
                        svn_dirent_local_style(local_abspath, scratch_pool));
             }
-
-          if (! wc_special && local_special)
-            text_modified_p = TRUE;
-        }
-
-      /* Find the checksum(s) of the node's one or two pristine texts.  Note
-         that read_info() may give us the one from BASE_NODE again. */
-      err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, NULL, NULL,
-                                     &base_sha1_checksum, NULL,
-                                     NULL, NULL, NULL, NULL,
-                                     db, local_abspath,
-                                     scratch_pool, scratch_pool);
-      if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-        {
-          svn_error_clear(err);
-          base_sha1_checksum = NULL;
-        }
-      else
-        SVN_ERR(err);
-      err = svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL,
-                                 &working_sha1_checksum, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL,
-                                 db, local_abspath,
-                                 scratch_pool, scratch_pool);
-      if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-        {
-          svn_error_clear(err);
-          working_sha1_checksum = NULL;
         }
-      else
-        SVN_ERR(err);
 
-      /* Remove NAME from PATH's entries file: */
+      /* Remove NAME from DB */
       SVN_ERR(svn_wc__db_op_remove_node(db, local_abspath,
                                         SVN_INVALID_REVNUM,
                                         svn_wc__db_kind_unknown,
                                         scratch_pool));
 
-      /* Having removed the checksums that reference the pristine texts,
-         remove the pristine texts (if now totally unreferenced) from the
-         pristine store.  Don't try to remove the same pristine text twice.
-         The two checksums might be the same, either because the copied base
-         was exactly the same as the replaced base, or just because the
-         ..._read_info() code above sets WORKING_SHA1_CHECKSUM to the base
-         checksum if there is no WORKING_NODE row. */
-      if (base_sha1_checksum)
-        SVN_ERR(svn_wc__db_pristine_remove(db, local_abspath,
-                                           base_sha1_checksum,
-                                           scratch_pool));
-      if (working_sha1_checksum
-          && ! svn_checksum_match(base_sha1_checksum, working_sha1_checksum))
-        SVN_ERR(svn_wc__db_pristine_remove(db, local_abspath,
-                                           working_sha1_checksum,
-                                           scratch_pool));
-
       /* If we were asked to destroy the working file, do so unless
          it has local mods. */
       if (destroy_wf)
@@ -2016,35 +1957,54 @@ svn_wc__internal_remove_from_revision_co
 
       for (i = 0; i < children->nelts; i++)
         {
-          const char *entry_name = APR_ARRAY_IDX(children, i, const char*);
-          const char *entry_abspath;
-          svn_boolean_t hidden;
+          const char *node_name = APR_ARRAY_IDX(children, i, const char*);
+          const char *node_abspath;
+          svn_wc__db_status_t status;
+          svn_wc__db_kind_t kind;
 
           svn_pool_clear(iterpool);
 
-          entry_abspath = svn_dirent_join(local_abspath, entry_name, iterpool);
+          node_abspath = svn_dirent_join(local_abspath, node_name, iterpool);
+
+          SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL,
+                                       db, node_abspath,
+                                       iterpool, iterpool));
 
-          /* ### where did the adm_missing and depth_exclude test go?!?
+          if (status == svn_wc__db_status_normal
+              && kind == svn_wc__db_kind_dir)
+            {
+              svn_boolean_t is_root;
 
-             ### BH: depth exclude is handled by hidden and missing is ok
-                     for this temp_op. */
+              SVN_ERR(svn_wc__check_wc_root(&is_root, NULL, NULL,
+                                            db, node_abspath, iterpool));
+
+              if (is_root)
+                continue; /* Just skip working copies as obstruction */
+            }
 
-          SVN_ERR(svn_wc__db_node_hidden(&hidden, db, entry_abspath,
-                                         iterpool));
-          if (hidden)
+          if (status != svn_wc__db_status_normal
+              && status != svn_wc__db_status_added
+              && status != svn_wc__db_status_incomplete)
             {
-              SVN_ERR(svn_wc__db_op_remove_node(db, entry_abspath,
+              /* The node is already 'deleted', so nothing to do on
+                 versioned nodes */
+              SVN_ERR(svn_wc__db_op_remove_node(db, node_abspath,
                                                 SVN_INVALID_REVNUM,
                                                 svn_wc__db_kind_unknown,
                                                 iterpool));
+
               continue;
             }
 
           err = svn_wc__internal_remove_from_revision_control(
-            db, entry_abspath,
-            destroy_wf, instant_error,
-            cancel_func, cancel_baton,
-            iterpool);
+                            db, node_abspath,
+                            destroy_wf, instant_error,
+                            cancel_func, cancel_baton,
+                            iterpool);
 
           if (err && (err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
             {
@@ -2081,13 +2041,15 @@ svn_wc__internal_remove_from_revision_co
                                               svn_wc__db_kind_unknown,
                                               iterpool));
           }
+        else
+          {
+            /* Remove the entire administrative .svn area, thereby removing
+               _this_ dir from revision control too.  */
+            SVN_ERR(svn_wc__adm_destroy(db, local_abspath,
+                                        cancel_func, cancel_baton, iterpool));
+          }
       }
 
-      /* Remove the entire administrative .svn area, thereby removing
-         _this_ dir from revision control too.  */
-      SVN_ERR(svn_wc__adm_destroy(db, local_abspath,
-                                  cancel_func, cancel_baton, iterpool));
-
       /* If caller wants us to recursively nuke everything on disk, go
          ahead, provided that there are no dangling local-mod files
          below */

Modified: subversion/trunk/subversion/libsvn_wc/cleanup.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/cleanup.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/cleanup.c (original)
+++ subversion/trunk/subversion/libsvn_wc/cleanup.c Tue May 10 14:31:45 2011
@@ -99,7 +99,7 @@ repair_timestamps(svn_wc__db_t *db,
     {
       svn_boolean_t modified;
       SVN_ERR(svn_wc__internal_file_modified_p(&modified, NULL, NULL,
-                                               db, local_abspath, FALSE, FALSE,
+                                               db, local_abspath, FALSE,
                                                scratch_pool));
     }
   else if (kind == svn_wc__db_kind_dir)

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Tue May 10 14:31:45 2011
@@ -289,8 +289,7 @@ copy_versioned_file(svn_wc__db_t *db,
                  never match. */
               SVN_ERR(svn_wc__internal_file_modified_p(&modified, NULL, NULL,
                                                        db, src_abspath,
-                                                       FALSE, FALSE,
-                                                       scratch_pool));
+                                                       FALSE, scratch_pool));
               if (!modified)
                 {
                   SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,

Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Tue May 10 14:31:45 2011
@@ -701,7 +701,7 @@ file_diff(struct edit_baton *eb,
 
       /* Here we deal with showing pure modifications. */
       SVN_ERR(svn_wc__internal_file_modified_p(&modified, NULL, NULL, db,
-                                               local_abspath, FALSE, TRUE,
+                                               local_abspath, FALSE,
                                                scratch_pool));
       if (modified)
         {
@@ -1737,7 +1737,7 @@ close_file(void *file_baton,
   if (!modified && !eb->use_text_base)
     SVN_ERR(svn_wc__internal_file_modified_p(&modified, NULL, NULL, eb->db,
                                              fb->local_abspath,
-                                             FALSE, TRUE, scratch_pool));
+                                             FALSE, scratch_pool));
 
   if (modified)
     {

Modified: subversion/trunk/subversion/libsvn_wc/diff_local.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_local.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_local.c Tue May 10 14:31:45 2011
@@ -355,7 +355,7 @@ file_diff(struct diff_baton *eb,
 
       /* Here we deal with showing pure modifications. */
       SVN_ERR(svn_wc__internal_file_modified_p(&modified, NULL, NULL, db,
-                                               local_abspath, FALSE, TRUE,
+                                               local_abspath, FALSE,
                                                scratch_pool));
       if (modified)
         {

Modified: subversion/trunk/subversion/libsvn_wc/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/externals.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/externals.c (original)
+++ subversion/trunk/subversion/libsvn_wc/externals.c Tue May 10 14:31:45 2011
@@ -741,7 +741,7 @@ close_file(void *file_baton,
             svn_boolean_t is_mod;
             SVN_ERR(svn_wc__internal_file_modified_p(&is_mod, NULL, NULL,
                                                      eb->db, eb->local_abspath,
-                                                     FALSE, FALSE, pool));
+                                                     FALSE, pool));
 
             if (!is_mod)
               {

Modified: subversion/trunk/subversion/libsvn_wc/props.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/props.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/props.c (original)
+++ subversion/trunk/subversion/libsvn_wc/props.c Tue May 10 14:31:45 2011
@@ -340,6 +340,7 @@ svn_wc__perform_props_merge(svn_wc_notif
                               U_("base_merge=TRUE is no longer supported"));
 #endif
     SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
+                                    svn_wc__has_magic_property(propchanges),
                                     NULL /* conflict */,
                                     work_items,
                                     scratch_pool));
@@ -2014,6 +2015,7 @@ do_propset(svn_wc__db_t *db,
   svn_wc_notify_action_t notify_action;
   svn_wc__db_status_t status;
   svn_skel_t *work_item = NULL;
+  svn_boolean_t clear_recorded_info = FALSE;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -2116,11 +2118,18 @@ do_propset(svn_wc__db_t *db,
              then it could be different, relative to the pristine. We want
              to ensure the LAST_MOD_TIME is different, to indicate that
              a full detranslate/compare is performed.  */
-          /* ### we should be performing similar logic for changes to the
-             ### svn:eol-style property.  */
-          SVN_ERR(svn_wc__db_global_record_fileinfo(db, local_abspath,
-                                                    SVN_INVALID_FILESIZE, 0,
-                                                    scratch_pool));
+          clear_recorded_info = TRUE;
+        }
+    }
+  else if (kind == svn_node_file && strcmp(name, SVN_PROP_EOL_STYLE) == 0)
+    {
+      svn_string_t *old_value = apr_hash_get(prophash, SVN_PROP_KEYWORDS,
+                                             APR_HASH_KEY_STRING);
+
+      if (((value == NULL) != (old_value == NULL))
+          || (value && ! svn_string_compare(value, old_value)))
+        {
+          clear_recorded_info = TRUE;
         }
     }
 
@@ -2150,7 +2159,8 @@ do_propset(svn_wc__db_t *db,
   apr_hash_set(prophash, name, APR_HASH_KEY_STRING, value);
 
   /* Drop it right into the db..  */
-  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, prophash, NULL, work_item,
+  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, prophash,
+                                  clear_recorded_info, NULL, work_item,
                                   scratch_pool));
 
   /* Run our workqueue item for sync'ing flags with props. */

Modified: subversion/trunk/subversion/libsvn_wc/questions.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/questions.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/questions.c (original)
+++ subversion/trunk/subversion/libsvn_wc/questions.c Tue May 10 14:31:45 2011
@@ -84,15 +84,10 @@
  * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of
  * PRISTINE_SIZE bytes), else to FALSE if not.
  *
- * If VERIFY_CHECKSUM is not NULL, also verify that PRISTINE_STREAM matches
- * this checksum (which should be the stored checksum for 
- * VERSIONED_FILE_ABSPATH). If the checksum does not match, return the error
- * SVN_ERR_WC_CORRUPT_TEXT_BASE.
- *
- * If COMPARE_TEXTBASES is true, translate VERSIONED_FILE_ABSPATH's EOL
+ * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL
  * style and keywords to repository-normal form according to its properties,
- * and compare the result with PRISTINE_STREAM.  If COMPARE_TEXTBASES is
- * false, translate PRISTINE_STREAM's EOL style and keywords to working-copy
+ * and compare the result with PRISTINE_STREAM.  If EXACT_COMPARISON is
+ * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy
  * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
  * result with VERSIONED_FILE_ABSPATH.
  *
@@ -115,8 +110,7 @@ compare_and_verify(svn_boolean_t *modifi
                    svn_filesize_t pristine_size,
                    svn_boolean_t has_props,
                    svn_boolean_t props_mod,
-                   svn_boolean_t compare_textbases,
-                   const svn_checksum_t *verify_checksum,
+                   svn_boolean_t exact_comparison,
                    apr_pool_t *scratch_pool)
 {
   svn_boolean_t same;
@@ -137,7 +131,7 @@ compare_and_verify(svn_boolean_t *modifi
                                          &keywords,
                                          &special,
                                          db, versioned_file_abspath, NULL,
-                                         compare_textbases,
+                                         exact_comparison,
                                          scratch_pool, scratch_pool));
 
       need_translation = svn_subst_translation_required(eol_style, eol_str,
@@ -148,7 +142,6 @@ compare_and_verify(svn_boolean_t *modifi
     need_translation = FALSE;
 
   if (! need_translation
-      && ! verify_checksum
       && (versioned_file_size != pristine_size))
     {
       *modified_p = TRUE;
@@ -179,21 +172,11 @@ compare_and_verify(svn_boolean_t *modifi
 
   /* ### Other checks possible? */
 
-  if (verify_checksum || need_translation)
+  if (need_translation)
     {
       /* Reading files is necessary. */
-      svn_checksum_t *checksum;
       svn_stream_t *v_stream;  /* versioned_file */
 
-      if (verify_checksum)
-        {
-          pristine_stream = svn_stream_checksummed2(pristine_stream,
-                                                    &checksum, NULL,
-                                                    verify_checksum->kind,
-                                                    TRUE,
-                                                    scratch_pool);
-        }
-
       if (special)
         {
           SVN_ERR(svn_subst_read_specialfile(&v_stream, versioned_file_abspath,
@@ -204,7 +187,7 @@ compare_and_verify(svn_boolean_t *modifi
           SVN_ERR(svn_stream_open_readonly(&v_stream, versioned_file_abspath,
                                            scratch_pool, scratch_pool));
 
-          if (compare_textbases && need_translation)
+          if (!exact_comparison && need_translation)
             {
               if (eol_style == svn_subst_eol_style_native)
                 eol_str = SVN_SUBST_NATIVE_EOL_STR;
@@ -234,19 +217,6 @@ compare_and_verify(svn_boolean_t *modifi
 
       SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream,
                                         scratch_pool));
-
-      if (verify_checksum)
-        {
-          if (checksum && !svn_checksum_match(checksum, verify_checksum))
-            return svn_error_create(SVN_ERR_WC_CORRUPT_TEXT_BASE,
-                    svn_checksum_mismatch_err(verify_checksum, checksum,
-                                              scratch_pool,
-                                _("Checksum mismatch indicates corrupt "
-                                  "text base for file: '%s'"),
-                                svn_dirent_local_style(versioned_file_abspath,
-                                                       scratch_pool)),
-                    NULL);
-        }
     }
   else
     {
@@ -271,8 +241,7 @@ svn_wc__internal_file_modified_p(svn_boo
                                  svn_boolean_t *read_only_p,
                                  svn_wc__db_t *db,
                                  const char *local_abspath,
-                                 svn_boolean_t force_comparison,
-                                 svn_boolean_t compare_textbases,
+                                 svn_boolean_t exact_comparison,
                                  apr_pool_t *scratch_pool)
 {
   svn_stream_t *pristine_stream;
@@ -340,7 +309,7 @@ svn_wc__internal_file_modified_p(svn_boo
       return SVN_NO_ERROR;
     }
 
-  if (! force_comparison)
+  if (! exact_comparison)
     {
       /* We're allowed to use a heuristic to determine whether files may
          have changed.  The heuristic has these steps:
@@ -396,8 +365,7 @@ svn_wc__internal_file_modified_p(svn_boo
                              local_abspath, finfo.size,
                              pristine_stream, pristine_size,
                              has_props, props_mod,
-                             compare_textbases,
-                             force_comparison ? checksum : NULL,
+                             exact_comparison,
                              scratch_pool));
 
   if (!*modified_p)
@@ -424,9 +392,10 @@ svn_wc_text_modified_p2(svn_boolean_t *m
                         svn_boolean_t force_comparison,
                         apr_pool_t *scratch_pool)
 {
+  /* ### We ignore FORCE_COMPARISON, but we also fixed its only
+         remaining use-case */
   return svn_wc__internal_file_modified_p(modified_p, NULL, NULL, wc_ctx->db,
-                                          local_abspath, force_comparison,
-                                          TRUE, scratch_pool);
+                                          local_abspath, FALSE, scratch_pool);
 }
 
 

Modified: subversion/trunk/subversion/libsvn_wc/status.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/status.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/status.c (original)
+++ subversion/trunk/subversion/libsvn_wc/status.c Tue May 10 14:31:45 2011
@@ -518,8 +518,7 @@ assemble_status(svn_wc_status3_t **statu
             {
               err = svn_wc__internal_file_modified_p(&text_modified_p, NULL,
                                                      NULL, db, local_abspath,
-                                                     FALSE, TRUE,
-                                                     scratch_pool);
+                                                     FALSE, scratch_pool);
 
               if (err)
                 {

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Tue May 10 14:31:45 
2011
@@ -3400,8 +3400,7 @@ merge_file(svn_skel_t **work_items,
 
       SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified, NULL,
                                                NULL, eb->db, fb->local_abspath,
-                                               FALSE /* force_comparison */,
-                                               FALSE /* compare_textbases */,
+                                               FALSE /* exact_comparison */,
                                                scratch_pool));
     }
 
@@ -4960,7 +4959,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   /* ### if below fails, then the above db change would remain :-(  */
 
   SVN_ERR(svn_wc__db_op_set_props(db, local_abspath,
-                                  new_props,
+                                  new_props, FALSE,
                                   NULL /* conflict */,
                                   all_work_items,
                                   pool));

Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Tue May 10 14:31:45 2011
@@ -372,16 +372,16 @@ void svn_wc__compat_call_notify_func(voi
  * the text base is much longer than the working file, every byte of
  * the text base will still be examined.)
  *
- * If COMPARE_TEXTBASES is true, translate LOCAL_ABSPATH's EOL
+ * If EXACT_COMPARISON is FALSE, translate LOCAL_ABSPATH's EOL
  * style and keywords to repository-normal form according to its properties,
  * and compare the result with the text base.  If COMPARE_TEXTBASES is
- * false, translate the text base's EOL style and keywords to working-copy
+ * TRUE, translate the text base's EOL style and keywords to working-copy
  * form according to LOCAL_ABSPATH's properties, and compare the
- * result with LOCAL_ABSPATH.
+ * result with LOCAL_ABSPATH.  Usually, EXACT_COMPARISON should be FALSE.
  *
  * If LOCAL_ABSPATH does not exist, consider it unmodified.  If it exists
  * but is not under revision control (not even scheduled for
- * addition), return the error SVN_ERR_ENTRY_NOT_FOUND.
+ * addition), return the error SVN_WC_PATH_NOT_FOUND.
  *
  * If the text is unmodified and a write-lock is held this function
  * will ensure that the last-known-unmodified timestamp and
@@ -396,8 +396,7 @@ svn_wc__internal_file_modified_p(svn_boo
                                  svn_boolean_t *read_only_p,
                                  svn_wc__db_t *db,
                                  const char *local_abspath,
-                                 svn_boolean_t force_comparison,
-                                 svn_boolean_t compare_textbases,
+                                 svn_boolean_t exact_comparison,
                                  apr_pool_t *scratch_pool);
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue May 10 14:31:45 2011
@@ -4630,10 +4630,69 @@ svn_wc__db_op_add_symlink(svn_wc__db_t *
   return SVN_NO_ERROR;
 }
 
+struct record_baton_t {
+  svn_filesize_t translated_size;
+  apr_time_t last_mod_time;
+};
+
+
+/* Record TRANSLATED_SIZE and LAST_MOD_TIME into top layer in NODES */
+static svn_error_t *
+db_record_fileinfo(void *baton,
+                   svn_wc__db_wcroot_t *wcroot,
+                   const char *local_relpath,
+                   apr_pool_t *scratch_pool)
+{
+  struct record_baton_t *rb = baton;
+  svn_sqlite__stmt_t *stmt;
+  int affected_rows;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_UPDATE_NODE_FILEINFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isii", wcroot->wc_id, local_relpath,
+                            rb->translated_size, rb->last_mod_time));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+
+  SVN_ERR_ASSERT(affected_rows == 1);
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__db_global_record_fileinfo(svn_wc__db_t *db,
+                                  const char *local_abspath,
+                                  svn_filesize_t translated_size,
+                                  apr_time_t last_mod_time,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+  struct record_baton_t rb;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              local_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  rb.translated_size = translated_size;
+  rb.last_mod_time = last_mod_time;
+
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_record_fileinfo, &rb,
+                              scratch_pool));
+
+  /* We *totally* monkeyed the entries. Toss 'em.  */
+  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 struct set_props_baton_t
 {
   apr_hash_t *props;
+  svn_boolean_t clear_recorded_info;
 
   const svn_skel_t *conflict;
   const svn_skel_t *work_items;
@@ -4711,6 +4770,14 @@ set_props_txn(void *baton,
   SVN_ERR(set_actual_props(wcroot->wc_id, local_relpath,
                            spb->props, wcroot->sdb, scratch_pool));
 
+  if (spb->clear_recorded_info)
+    {
+      struct record_baton_t rb;
+      rb.translated_size = SVN_INVALID_FILESIZE;
+      rb.last_mod_time = 0;
+      SVN_ERR(db_record_fileinfo(&rb, wcroot, local_relpath, scratch_pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -4719,6 +4786,7 @@ svn_error_t *
 svn_wc__db_op_set_props(svn_wc__db_t *db,
                         const char *local_abspath,
                         apr_hash_t *props,
+                        svn_boolean_t clear_recorded_info,
                         const svn_skel_t *conflict,
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool)
@@ -4734,6 +4802,7 @@ svn_wc__db_op_set_props(svn_wc__db_t *db
   VERIFY_USABLE_WCROOT(wcroot);
 
   spb.props = props;
+  spb.clear_recorded_info = clear_recorded_info;
   spb.conflict = conflict;
   spb.work_items = work_items;
 
@@ -8757,66 +8826,6 @@ svn_wc__db_op_bump_revisions_post_update
   return SVN_NO_ERROR;
 }
 
-
-struct record_baton_t {
-  svn_filesize_t translated_size;
-  apr_time_t last_mod_time;
-};
-
-
-/* Record TRANSLATED_SIZE and LAST_MOD_TIME into top layer in NODES */
-static svn_error_t *
-record_fileinfo(void *baton,
-                svn_wc__db_wcroot_t *wcroot,
-                const char *local_relpath,
-                apr_pool_t *scratch_pool)
-{
-  struct record_baton_t *rb = baton;
-  svn_sqlite__stmt_t *stmt;
-  int affected_rows;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_UPDATE_NODE_FILEINFO));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isii", wcroot->wc_id, local_relpath,
-                            rb->translated_size, rb->last_mod_time));
-  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
-
-  SVN_ERR_ASSERT(affected_rows == 1);
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__db_global_record_fileinfo(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  svn_filesize_t translated_size,
-                                  apr_time_t last_mod_time,
-                                  apr_pool_t *scratch_pool)
-{
-  svn_wc__db_wcroot_t *wcroot;
-  const char *local_relpath;
-  struct record_baton_t rb;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
-                              local_abspath, scratch_pool, scratch_pool));
-  VERIFY_USABLE_WCROOT(wcroot);
-
-  rb.translated_size = translated_size;
-  rb.last_mod_time = last_mod_time;
-
-  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, record_fileinfo, &rb,
-                              scratch_pool));
-
-  /* We *totally* monkeyed the entries. Toss 'em.  */
-  SVN_ERR(flush_entries(wcroot, local_abspath, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
 static svn_error_t *
 lock_add_txn(void *baton,
              svn_wc__db_wcroot_t *wcroot,
@@ -11842,8 +11851,7 @@ has_local_mods(svn_boolean_t *is_modifie
             {
               SVN_ERR(svn_wc__internal_file_modified_p(is_modified, NULL,
                                                        NULL, db, node_abspath,
-                                                       FALSE, TRUE,
-                                                       iterpool));
+                                                       FALSE, iterpool));
               if (*is_modified)
                 break;
             }

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue May 10 14:31:45 2011
@@ -1361,11 +1361,16 @@ svn_wc__db_op_add_symlink(svn_wc__db_t *
    WORK_ITEMS are inserted into the work queue, as additional things that
    need to be completed before the working copy is stable.
 
+
+   If CLEAR_RECORDED_INFO is true, the recorded information for the node
+   is cleared. (commonly used when updating svn:* magic properties).
+
    NOTE: This will overwrite ALL working properties the node currently
    has. There is no db_op_set_prop() function. Callers must read all the
    properties, change one, and write all the properties.
    ### ugh. this has poor transaction semantics...
 
+
    NOTE: This will create an entry in the ACTUAL table for the node if it
    does not yet have one.
 */
@@ -1373,6 +1378,7 @@ svn_error_t *
 svn_wc__db_op_set_props(svn_wc__db_t *db,
                         const char *local_abspath,
                         apr_hash_t *props,
+                        svn_boolean_t clear_recorded_info,
                         const svn_skel_t *conflict,
                         const svn_skel_t *work_items,
                         apr_pool_t *scratch_pool);

Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Tue May 10 14:31:45 2011
@@ -496,8 +496,8 @@ process_commit_file_install(svn_wc__db_t
          right kind of lock (and we ignore the result)
        */
       SVN_ERR(svn_wc__internal_file_modified_p(&modified, NULL, NULL,
-                                               db, local_abspath,
-                                               FALSE, FALSE, scratch_pool));
+                                               db, local_abspath, FALSE,
+                                               scratch_pool));
     }
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/tests/libsvn_wc/db-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/db-test.c?rev=1101473&r1=1101472&r2=1101473&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/db-test.c Tue May 10 14:31:45 
2011
@@ -643,7 +643,7 @@ validate_node(svn_wc__db_t *db,
   {
     apr_hash_t *actual_props = apr_hash_copy(scratch_pool, props);
     apr_hash_set(actual_props, "p999", APR_HASH_KEY_STRING, value);
-    SVN_ERR(svn_wc__db_op_set_props(db, path, actual_props,
+    SVN_ERR(svn_wc__db_op_set_props(db, path, actual_props, FALSE,
                                     NULL, NULL, scratch_pool));
     SVN_ERR(svn_wc__db_read_props(&props, db, path,
                                   scratch_pool, scratch_pool));


Reply via email to