subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dan...@apache.org
Subject svn commit: r930648 [2/3] - in /subversion/branches/svn-patch-improvements: ./ build/generator/ build/generator/templates/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subvers...
Date Sun, 04 Apr 2010 09:09:35 GMT
Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.c Sun Apr  4 09:09:34 2010
@@ -37,7 +37,6 @@
 
 #include "wc.h"
 #include "adm_files.h"
-#include "adm_ops.h"
 #include "entries.h"
 #include "lock.h"
 #include "tree_conflicts.h"
@@ -47,7 +46,6 @@
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
 #include "private/svn_sqlite.h"
-#include "private/svn_skel.h"
 
 #define MAYBE_ALLOC(x,p) ((x) ? (x) : apr_pcalloc((p), sizeof(*(x))))
 
@@ -2565,10 +2563,6 @@ fold_entry(apr_hash_t *entries,
   if (modify_flags & SVN_WC__ENTRY_MODIFY_ABSENT)
     cur_entry->absent = entry->absent;
 
-  /* Incomplete state */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_INCOMPLETE)
-    cur_entry->incomplete = entry->incomplete;
-
   /* Text/prop modification times */
   if (modify_flags & SVN_WC__ENTRY_MODIFY_TEXT_TIME)
     cur_entry->text_time = entry->text_time;

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/entries.h Sun Apr  4 09:09:34 2010
@@ -109,7 +109,6 @@ svn_error_t *svn_wc__atts_to_entry(svn_w
 #define SVN_WC__ENTRY_MODIFY_CONFLICT_WRK       APR_INT64_C(0x0000000000004000)
 #define SVN_WC__ENTRY_MODIFY_PREJFILE           APR_INT64_C(0x0000000000008000)
 /* OPEN */
-#define SVN_WC__ENTRY_MODIFY_INCOMPLETE         APR_INT64_C(0x0000000000100000)
 #define SVN_WC__ENTRY_MODIFY_ABSENT             APR_INT64_C(0x0000000000200000)
 /* OPEN */
 #define SVN_WC__ENTRY_MODIFY_WORKING_SIZE       APR_INT64_C(0x0000000100000000)

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.c Sun Apr  4 09:09:34 2010
@@ -1062,44 +1062,46 @@ svn_wc__loggy_move(svn_stringbuf_t **log
 }
 
 svn_error_t *
-svn_wc__loggy_maybe_set_executable(svn_stringbuf_t **log_accum,
+svn_wc__loggy_maybe_set_executable(svn_wc__db_t *db,
                                    const char *adm_abspath,
                                    const char *path,
-                                   apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
 {
+  svn_stringbuf_t *log_accum = NULL;
   const char *loggy_path1;
 
   SVN_ERR(loggy_path(&loggy_path1, path, adm_abspath, scratch_pool));
-  svn_xml_make_open_tag(log_accum,
-                        result_pool,
+  svn_xml_make_open_tag(&log_accum,
+                        scratch_pool,
                         svn_xml_self_closing,
                         SVN_WC__LOG_MAYBE_EXECUTABLE,
                         SVN_WC__LOG_ATTR_NAME, loggy_path1,
                         NULL);
 
-  return SVN_NO_ERROR;
+  return svn_error_return(svn_wc__wq_add_loggy(db, adm_abspath, log_accum,
+                                               scratch_pool));
 }
 
 svn_error_t *
-svn_wc__loggy_maybe_set_readonly(svn_stringbuf_t **log_accum,
+svn_wc__loggy_maybe_set_readonly(svn_wc__db_t *db,
                                  const char *adm_abspath,
                                  const char *path,
-                                 apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
 {
+  svn_stringbuf_t *log_accum = NULL;
   const char *loggy_path1;
 
   SVN_ERR(loggy_path(&loggy_path1, path, adm_abspath, scratch_pool));
-  svn_xml_make_open_tag(log_accum,
-                        result_pool,
+  svn_xml_make_open_tag(&log_accum,
+                        scratch_pool,
                         svn_xml_self_closing,
                         SVN_WC__LOG_MAYBE_READONLY,
                         SVN_WC__LOG_ATTR_NAME,
                         loggy_path1,
                         NULL);
 
-  return SVN_NO_ERROR;
+  return svn_error_return(svn_wc__wq_add_loggy(db, adm_abspath, log_accum,
+                                               scratch_pool));
 }
 
 svn_error_t *
@@ -1195,19 +1197,22 @@ svn_wc__loggy_set_timestamp(svn_stringbu
 
 
 svn_error_t *
-svn_wc__loggy_add_tree_conflict(svn_stringbuf_t **log_accum,
+svn_wc__loggy_add_tree_conflict(svn_wc__db_t *db,
+                                const char *adm_abspath,
                                 const svn_wc_conflict_description2_t *conflict,
-                                apr_pool_t *pool)
+                                apr_pool_t *scratch_pool)
 {
+  svn_stringbuf_t *log_accum = NULL;
   const char *victim_basename;
   svn_skel_t *skel;
   const char *conflict_data;
 
-  victim_basename = svn_dirent_basename(conflict->local_abspath, pool);
-  SVN_ERR(svn_wc__serialize_conflict(&skel, conflict, pool, pool));
-  conflict_data = svn_skel__unparse(skel, pool)->data,
+  victim_basename = svn_dirent_basename(conflict->local_abspath, scratch_pool);
+  SVN_ERR(svn_wc__serialize_conflict(&skel, conflict,
+                                     scratch_pool, scratch_pool));
+  conflict_data = svn_skel__unparse(skel, scratch_pool)->data,
 
-  svn_xml_make_open_tag(log_accum, pool, svn_xml_self_closing,
+  svn_xml_make_open_tag(&log_accum, scratch_pool, svn_xml_self_closing,
                         SVN_WC__LOG_ADD_TREE_CONFLICT,
                         SVN_WC__LOG_ATTR_NAME,
                         victim_basename,
@@ -1215,7 +1220,8 @@ svn_wc__loggy_add_tree_conflict(svn_stri
                         conflict_data,
                         NULL);
 
-  return SVN_NO_ERROR;
+  return svn_error_return(svn_wc__wq_add_loggy(db, adm_abspath, log_accum,
+                                               scratch_pool));
 }
 
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.h?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/log.h Sun Apr  4 09:09:34 2010
@@ -192,37 +192,35 @@ svn_wc__loggy_move(svn_stringbuf_t **log
 
 
 
-/* Extend **LOG_ACCUM with log instructions to set permissions of PATH
-   to 'executable' if it has the 'executable' property set.
+/* Queue instructions to set permissions of PATH to 'executable' if it has
+   the 'executable' property set.
+
    ADM_ABSPATH is the absolute path for the admin directory for PATH.
 
    The property is tested at log run time, within this log instruction.
 
-   Allocate *LOG_ACCUM in RESULT_POOL if it is NULL. Use SCRATCH_POOL for
-   temporary allocations.
+   Use SCRATCH_POOL for temporary allocations.
 */
 svn_error_t *
-svn_wc__loggy_maybe_set_executable(svn_stringbuf_t **log_accum,
+svn_wc__loggy_maybe_set_executable(svn_wc__db_t *db,
                                    const char *adm_abspath,
                                    const char *path,
-                                   apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool);
 
-/* Extend **LOG_ACCUM with log instructions to set permissions of PATH
-   to 'readonly' if it has the 'needs-lock' property set and there is
-   no lock for the file in the working copy.
+/* Queue instructions to set permissions of PATH to 'readonly' if it has
+   the 'needs-lock' property set and there is no lock for the file in the
+   working copy.
+
    ADM_ABSPATH is the absolute path for the admin directory for PATH.
 
    The tests are made at log run time, within this log instruction.
 
-   Allocate *LOG_ACCUM in RESULT_POOL if it is NULL. Use SCRATCH_POOL for
-   temporary allocations.
+   Use SCRATCH_POOL for temporary allocations.
 */
 svn_error_t *
-svn_wc__loggy_maybe_set_readonly(svn_stringbuf_t **log_accum,
+svn_wc__loggy_maybe_set_readonly(svn_wc__db_t *db,
                                  const char *adm_abspath,
                                  const char *path,
-                                 apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool);
 
 
@@ -289,6 +287,34 @@ svn_wc__loggy_set_timestamp(svn_stringbu
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool);
 
+/* Like svn_wc__add_tree_conflict(), but append to the log accumulator
+ * LOG_ACCUM a command to rewrite the entry field, and do not flush the log.
+ * This function is meant to be used in the working copy library where
+ * log accumulators are usually readily available.
+ *
+ * If *LOG_ACCUM is NULL then set *LOG_ACCUM to a new stringbug allocated in
+ * POOL, else append to the existing stringbuf there.
+ */
+svn_error_t *
+svn_wc__loggy_add_tree_conflict(svn_wc__db_t *db,
+                                const char *adm_abspath,
+                                const svn_wc_conflict_description2_t *conflict,
+                                apr_pool_t *scratch_pool);
+
+
+/* Extend LOG_ACCUM with log entries to save the current baseprops of PATH
+   as revert props.
+
+   Makes sure the baseprops are destroyed if DESTROY_BASEPROPS is TRUE,
+   the baseprops are preserved otherwise.
+*/
+svn_error_t *
+svn_wc__loggy_revert_props_create(svn_stringbuf_t **log_accum,
+                                  svn_wc__db_t *db,
+                                  const char *local_abspath,
+                                  const char *adm_abspath,
+                                  apr_pool_t *pool);
+
 
 /* TODO ###
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/merge.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/merge.c Sun Apr  4 09:09:34 2010
@@ -1253,23 +1253,33 @@ svn_wc__internal_merge(svn_stringbuf_t *
                             cancel_baton,
                             pool));
 
+  SVN_ERR_ASSERT(!dry_run
+                 || *log_accum == NULL
+                 || svn_stringbuf_isempty(*log_accum));
+
+  /* Queue everything that has been accumulated.  */
+  if (*log_accum != NULL)
+    {
+      SVN_ERR(svn_wc__wq_add_loggy(db, dir_abspath, *log_accum, pool));
+      svn_stringbuf_setempty(*log_accum);
+    }
+
   /* Merging is complete.  Regardless of text or binariness, we might
      need to tweak the executable bit on the new working file, and
      possibly make it read-only. */
   if (! dry_run)
     {
-      SVN_ERR(svn_wc__loggy_maybe_set_executable(log_accum, dir_abspath,
+      SVN_ERR(svn_wc__loggy_maybe_set_executable(db, dir_abspath,
                                                  target_abspath,
-                                                 pool, pool));
-      SVN_ERR(svn_wc__loggy_maybe_set_readonly(log_accum, dir_abspath,
+                                                 pool));
+      SVN_ERR(svn_wc__loggy_maybe_set_readonly(db, dir_abspath,
                                                target_abspath,
-                                               pool, pool));
+                                               pool));
     }
 
   return SVN_NO_ERROR;
 }
 
-
 
 svn_error_t *
 svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
@@ -1292,8 +1302,14 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
               void *cancel_baton,
               apr_pool_t *scratch_pool)
 {
-  svn_stringbuf_t *log_accum = svn_stringbuf_create("", scratch_pool);
+  svn_stringbuf_t *log_accum = NULL;
+  const char *dir_abspath = svn_dirent_dirname(target_abspath, scratch_pool);
+
+  /* Before we do any work, make sure we hold a write lock.  */
+  if (!dry_run)
+    SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
 
+  /* Queue all the work.  */
   SVN_ERR(svn_wc__internal_merge(&log_accum, merge_outcome,
                                  wc_ctx->db,
                                  left_abspath, left_version,
@@ -1309,23 +1325,14 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
                                  cancel_func, cancel_baton,
                                  scratch_pool));
 
-  /* Write our accumulation of log entries into a log file */
-  if (!dry_run)
-    {
-      const char *dir_abspath = svn_dirent_dirname(target_abspath,
-                                                   scratch_pool);
-
-      /* Verify that we're holding this directory's write lock.  */
-      SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
+  /* svn_wc__internal_merge() should have queued all of its work.  */
+  SVN_ERR_ASSERT(log_accum == NULL || svn_stringbuf_isempty(log_accum));
 
-      /* Add all the work items to the queue, then run it.  */
-      /* ### add_loggy takes a DIR, but wq_run is a simple WRI_ABSPATH  */
-      SVN_ERR(svn_wc__wq_add_loggy(wc_ctx->db, dir_abspath,
-                                   log_accum, scratch_pool));
-      SVN_ERR(svn_wc__wq_run(wc_ctx->db, target_abspath,
-                             cancel_func, cancel_baton,
-                             scratch_pool));
-    }
+  /* If this isn't a dry run, then run the work!  */
+  if (!dry_run)
+    SVN_ERR(svn_wc__wq_run(wc_ctx->db, target_abspath,
+                           cancel_func, cancel_baton,
+                           scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.c Sun Apr  4 09:09:34 2010
@@ -2167,16 +2167,24 @@ svn_wc__internal_propset(svn_wc__db_t *d
       if (svn_subst_keywords_differ2(old_keywords, new_keywords, FALSE,
                                      scratch_pool))
         {
-          /* NOTE: this change is immediate. If the overall propset fails,
-             then we end up with an un-cached text_time. Big whoop.  */
-
-          /* If we changed the keywords or newlines, void the entry
-             timestamp for this file, so svn_wc_text_modified_p() does
-             a real (albeit slow) check later on. */
-          /* Setting the last mod time to zero will effectively invalidate
-             it's value. */
-          SVN_ERR(svn_wc__db_op_set_last_mod_time(db, local_abspath, 0,
-                                                  scratch_pool));
+          /* If the keywords have changed, then the translation of the file
+             may be different. We should invalidate the cached TRANSLATED_SIZE
+             and LAST_MOD_TIME on this node.
+
+             Note that we don't immediately re-translate the file. But a
+             "has it changed?" check in the future will do a translation
+             from the pristine, and it will want to compare the (new)
+             resulting TRANSLATED_SIZE against the working copy file.
+
+             Also, when this file is (de)translated with the new keywords,
+             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));
         }
     }
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.h?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/props.h Sun Apr  4 09:09:34 2010
@@ -164,18 +164,6 @@ svn_wc__install_props(svn_wc__db_t *db,
                       svn_boolean_t force_base_install,
                       apr_pool_t *scratch_pool);
 
-/* Extend LOG_ACCUM with log entries to save the current baseprops of PATH
-   as revert props.
-
-   Makes sure the baseprops are destroyed if DESTROY_BASEPROPS is TRUE,
-   the baseprops are preserved otherwise.
-*/
-svn_error_t *
-svn_wc__loggy_revert_props_create(svn_stringbuf_t **log_accum,
-                                  svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  const char *adm_abspath,
-                                  apr_pool_t *pool);
 
 /* Delete PROPS_KIND props for LOCAL_ABSPATH */
 svn_error_t *

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/questions.c Sun Apr  4 09:09:34 2010
@@ -35,19 +35,15 @@
 #include "svn_string.h"
 #include "svn_error.h"
 #include "svn_dirent_uri.h"
-#include "svn_path.h"
 #include "svn_time.h"
 #include "svn_io.h"
 #include "svn_props.h"
 
 #include "wc.h"
 #include "adm_files.h"
-#include "entries.h"
 #include "props.h"
 #include "translate.h"
 #include "wc_db.h"
-#include "lock.h"
-#include "tree_conflicts.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
@@ -89,6 +85,8 @@
  * if verify_checksum is TRUE. If checksum does not match, return the error
  * SVN_ERR_WC_CORRUPT_TEXT_BASE.
  *
+ * PRISTINE_STREAM will be closed before a successful return.
+ *
  * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
  */
 static svn_error_t *
@@ -125,7 +123,6 @@ compare_and_verify(svn_boolean_t *modifi
       /* Reading files is necessary. */
       svn_checksum_t *checksum;
       svn_stream_t *v_stream;  /* versioned_file */
-      svn_stream_t *p_stream = svn_stream_disown(pristine_stream, scratch_pool);
       const svn_checksum_t *node_checksum;
 
       if (verify_checksum)
@@ -142,9 +139,10 @@ compare_and_verify(svn_boolean_t *modifi
                                        scratch_pool, scratch_pool));
 
           if (node_checksum)
-            p_stream = svn_stream_checksummed2(p_stream, &checksum, NULL,
-                                               svn_checksum_md5, TRUE,
-                                               scratch_pool);
+            pristine_stream = svn_stream_checksummed2(pristine_stream,
+                                                      &checksum, NULL,
+                                                      svn_checksum_md5, TRUE,
+                                                      scratch_pool);
         }
 
       if (special)
@@ -176,17 +174,15 @@ compare_and_verify(svn_boolean_t *modifi
           else if (need_translation)
             {
               /* Wrap base stream to translate into working copy form. */
-              p_stream = svn_subst_stream_translated(p_stream, eol_str, FALSE,
-                                                     keywords, TRUE,
-                                                     scratch_pool);
+              pristine_stream = svn_subst_stream_translated(pristine_stream,
+                                                            eol_str, FALSE,
+                                                            keywords, TRUE,
+                                                            scratch_pool);
             }
         }
 
-      SVN_ERR(svn_stream_contents_same(&same, p_stream, v_stream,
-                                       scratch_pool));
-
-      SVN_ERR(svn_stream_close(v_stream));
-      SVN_ERR(svn_stream_close(p_stream));
+      SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream,
+                                        scratch_pool));
 
       if (verify_checksum && node_checksum)
         {
@@ -211,10 +207,8 @@ compare_and_verify(svn_boolean_t *modifi
       SVN_ERR(svn_stream_open_readonly(&v_stream, versioned_file_abspath,
                                        scratch_pool, scratch_pool));
 
-      SVN_ERR(svn_stream_contents_same(&same, pristine_stream, v_stream,
-                                       scratch_pool));
-
-      SVN_ERR(svn_stream_close(v_stream));
+      SVN_ERR(svn_stream_contents_same2(&same, pristine_stream, v_stream,
+                                        scratch_pool));
     }
 
   *modified_p = (! same);
@@ -236,11 +230,12 @@ svn_wc__internal_versioned_file_modcheck
   SVN_ERR(svn_stream_open_readonly(&pristine_stream, base_file_abspath,
                                    scratch_pool, scratch_pool));
 
-  SVN_ERR(compare_and_verify(modified_p, db, versioned_file_abspath,
-                             pristine_stream, compare_textbases, FALSE,
-                             scratch_pool));
-
-  return svn_error_return(svn_stream_close(pristine_stream));
+  return svn_error_return(compare_and_verify(modified_p, db,
+                                             versioned_file_abspath,
+                                             pristine_stream,
+                                             compare_textbases,
+                                             FALSE,
+                                             scratch_pool));
 }
 
 svn_error_t *
@@ -248,12 +243,12 @@ svn_wc__versioned_file_modcheck(svn_bool
                                 svn_wc_context_t *wc_ctx,
                                 const char *versioned_file_abspath,
                                 const char *base_file_abspath,
-                                svn_boolean_t compare_textbases,
                                 apr_pool_t *scratch_pool)
 {
   return svn_error_return(svn_wc__internal_versioned_file_modcheck(
                             modified_p, wc_ctx->db, versioned_file_abspath,
-                            base_file_abspath, compare_textbases,
+                            base_file_abspath,
+                            TRUE /* compare_textbases */,
                             scratch_pool));
 }
 
@@ -376,12 +371,11 @@ svn_wc__internal_text_modified_p(svn_boo
     }
 
   /* Check all bytes, and verify checksum if requested. */
-  err = compare_and_verify(modified_p, db, local_abspath, pristine_stream,
-                           compare_textbases, force_comparison,
-                           scratch_pool);
-
-  return svn_error_compose_create(err,
-                                  svn_stream_close(pristine_stream));
+  return svn_error_return(compare_and_verify(modified_p, db, local_abspath,
+                                             pristine_stream,
+                                             compare_textbases,
+                                             force_comparison,
+                                             scratch_pool));
 }
 
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/revision_status.c Sun Apr  4 09:09:34 2010
@@ -40,8 +40,13 @@ struct walk_baton
   svn_wc__db_t *db;
 };
 
-/* An svn_wc__node_found_func_t callback function for analyzing the status
- * of nodes */
+/* An svn_wc__node_found_func_t callback function for analyzing the wc
+ * status of LOCAL_ABSPATH. Since it can be invoked for a lot of paths in
+ * a wc but some data , i.e. if the wc is switched or has modifications, is
+ * expensive to calculate, we optimize by checking if those values are
+ * already set before runnning the db operations. The found status
+ * information is stored in BATON. Temporary allocations are made in
+ * SCRATCH_POOL. */
 static svn_error_t *
 analyze_status(const char *local_abspath,
                void *baton,
@@ -50,10 +55,9 @@ analyze_status(const char *local_abspath
   struct walk_baton *wb = baton;
   svn_revnum_t changed_rev;
   svn_revnum_t revision;
+  svn_revnum_t item_rev; 
   svn_depth_t depth;
   svn_wc__db_status_t status;
-  svn_boolean_t wc_root;
-  svn_boolean_t switched;
 
   SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, 
                                NULL, NULL, &changed_rev, 
@@ -71,24 +75,36 @@ analyze_status(const char *local_abspath
       wb->result->sparse_checkout = TRUE;
       return SVN_NO_ERROR;
     }
-
-  if (status == svn_wc__db_status_not_present)
-    return SVN_NO_ERROR;
+  else if (status == svn_wc__db_status_not_present)
+    {
+      return SVN_NO_ERROR;
+    }
+  else if (status == svn_wc__db_status_added
+           || status == svn_wc__db_status_obstructed_add
+           || status == svn_wc__db_status_deleted
+           || status == svn_wc__db_status_obstructed_delete)
+    {
+      wb->result->modified = TRUE; 
+    }
 
   if (! wb->result->switched)
     {
+      svn_boolean_t wc_root;
+      svn_boolean_t switched;
+
       SVN_ERR(svn_wc__check_wc_root(&wc_root, NULL, &switched, wb->db,
                                     local_abspath, scratch_pool));
 
       wb->result->switched |= switched;
     }
 
+  item_rev = (wb->committed
+              ? changed_rev
+              : revision);
+
   /* Added files have a revision of no interest */
-  if (revision != SVN_INVALID_REVNUM)
+  if (item_rev != SVN_INVALID_REVNUM)
     {
-      svn_revnum_t item_rev = (wb->committed
-                               ? changed_rev
-                               : revision);
 
       if (wb->result->min_rev == SVN_INVALID_REVNUM
           || item_rev < wb->result->min_rev)
@@ -101,22 +117,27 @@ analyze_status(const char *local_abspath
 
   if (! wb->result->modified)
     {
-      svn_boolean_t text_mod;
       svn_boolean_t props_mod;
 
       SVN_ERR(svn_wc__props_modified(&props_mod, wb->db, local_abspath,
                                      scratch_pool));
+      wb->result->modified |= props_mod;
+    }
+
+  if (! wb->result->modified)
+    {
+      svn_boolean_t text_mod;
 
       SVN_ERR(svn_wc__internal_text_modified_p(&text_mod, wb->db,
                                                local_abspath,
                                                FALSE,
                                                TRUE,
                                                scratch_pool));
-      wb->result->modified |= (text_mod || props_mod);
+      wb->result->modified |= text_mod; 
     }
 
-  wb->result->sparse_checkout |= ((depth != svn_depth_infinity 
-                                  && depth != svn_depth_unknown));
+  wb->result->sparse_checkout |= (depth != svn_depth_infinity 
+                                  && depth != svn_depth_unknown);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/tree_conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/tree_conflicts.h?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/tree_conflicts.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/tree_conflicts.h Sun Apr  4 09:09:34 2010
@@ -74,19 +74,6 @@ svn_wc__deserialize_conflict(const svn_w
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool);
 
-/* Like svn_wc__add_tree_conflict(), but append to the log accumulator
- * LOG_ACCUM a command to rewrite the entry field, and do not flush the log.
- * This function is meant to be used in the working copy library where
- * log accumulators are usually readily available.
- *
- * If *LOG_ACCUM is NULL then set *LOG_ACCUM to a new stringbug allocated in
- * POOL, else append to the existing stringbuf there.
- */
-svn_error_t *
-svn_wc__loggy_add_tree_conflict(svn_stringbuf_t **log_accum,
-                                const svn_wc_conflict_description2_t *conflict,
-                                apr_pool_t *pool);
-
 /*
  * Encode tree conflict descriptions into a single string.
  *

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/update_editor.c Sun Apr  4 09:09:34 2010
@@ -305,13 +305,9 @@ struct dir_baton
      These nodes should all be marked as deleted. */
   svn_boolean_t in_deleted_and_tree_conflicted_subtree;
 
-  /* Set iff this is a new directory that is not yet versioned and not
-     yet in the parent's list of entries */
-  svn_boolean_t added;
-
   /* Set if an unversioned dir of the same name already existed in
      this directory. */
-  svn_boolean_t existed;
+  svn_boolean_t obstruction_found;
 
   /* Set if a dir of the same name already exists and is
      scheduled for addition without history. */
@@ -324,13 +320,6 @@ struct dir_baton
   /* The bump information for this directory. */
   struct bump_dir_info *bump_info;
 
-  /* The current log buffer. The content of this accumulator may be
-     flushed and run at any time (in pool cleanup), so only append
-     complete sets of operations to it; you may need to build up a
-     buffer of operations and append it atomically with
-     svn_stringbuf_appendstr. */
-  svn_stringbuf_t *log_accum;
-
   /* The depth of the directory in the wc (or inferred if added).  Not
      used for filtering; we have a separate wrapping editor for that. */
   svn_depth_t ambient_depth;
@@ -504,17 +493,6 @@ node_get_relpath_ignore_errors(svn_wc__d
   return relpath;
 }
 
-/* Flush accumulated log entries to a log file on disk for DIR_BATON and
- * increase the log number of the dir baton.
- * Use POOL for temporary allocations. */
-static svn_error_t *
-flush_log(struct dir_baton *db, apr_pool_t *pool)
-{
-  SVN_WC__FLUSH_LOG_ACCUM(db->edit_baton->db, db->local_abspath,
-                          db->log_accum, pool);
-
-  return SVN_NO_ERROR;
-}
 
 /* An APR pool cleanup handler.  This runs the log file for a
    directory baton. */
@@ -526,11 +504,9 @@ cleanup_dir_baton(void *dir_baton)
   svn_error_t *err;
   apr_pool_t *pool = apr_pool_parent_get(db->pool);
 
-  err = flush_log(db, pool);
-  if (!err)
-    err = svn_wc__wq_run(eb->db, db->local_abspath,
-                         eb->cancel_func, eb->cancel_baton,
-                         pool);
+  err = svn_wc__wq_run(eb->db, db->local_abspath,
+                       eb->cancel_func, eb->cancel_baton,
+                       pool);
 
   /* If the editor aborts for some sort of error, the command line
      client relies on pool cleanup to run outstanding work queues and
@@ -573,7 +549,6 @@ make_dir_baton(struct dir_baton **d_p,
                const char *path,
                struct edit_baton *eb,
                struct dir_baton *pb,
-               svn_boolean_t added,
                apr_pool_t *scratch_pool)
 {
   apr_pool_t *dir_pool;
@@ -660,11 +635,9 @@ make_dir_baton(struct dir_baton **d_p,
   d->parent_baton = pb;
   d->pool         = dir_pool;
   d->propchanges  = apr_array_make(dir_pool, 1, sizeof(svn_prop_t));
-  d->added        = added;
-  d->existed      = FALSE;
+  d->obstruction_found = FALSE;
   d->add_existed  = FALSE;
   d->bump_info    = bdi;
-  d->log_accum    = svn_stringbuf_create("", dir_pool);
   d->old_revision = SVN_INVALID_REVNUM;
 
   /* The caller of this function needs to fill these in. */
@@ -947,14 +920,14 @@ struct file_baton
   svn_boolean_t already_notified;
 
   /* Set if this file is new. */
-  svn_boolean_t added;
+  svn_boolean_t adding_file;
 
   /* Set if this file is new with history. */
   svn_boolean_t added_with_history;
 
   /* Set if an unversioned file of the same name already existed in
      this directory. */
-  svn_boolean_t existed;
+  svn_boolean_t obstruction_found;
 
   /* Set if a file of the same name already exists and is
      scheduled for addition without history. */
@@ -1059,8 +1032,8 @@ make_file_baton(struct file_baton **f_p,
   f->edit_baton        = pb->edit_baton;
   f->propchanges       = apr_array_make(file_pool, 1, sizeof(svn_prop_t));
   f->bump_info         = pb->bump_info;
-  f->added             = adding;
-  f->existed           = FALSE;
+  f->adding_file       = adding;
+  f->obstruction_found = FALSE;
   f->add_existed       = FALSE;
   f->deleted           = FALSE;
   f->dir_baton         = pb;
@@ -1344,7 +1317,7 @@ open_root(void *edit_baton,
      edit run. */
   eb->root_opened = TRUE;
 
-  SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, FALSE, pool));
+  SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, pool));
   *dir_baton = db;
 
   SVN_ERR(svn_wc__db_read_kind(&kind, eb->db, db->local_abspath, TRUE, pool));
@@ -2040,6 +2013,7 @@ node_already_conflicted(svn_boolean_t *c
   return SVN_NO_ERROR;
 }
 
+
 /* Delete PATH from its immediate parent PARENT_PATH, in the edit
  * represented by EB. PATH is relative to EB->anchor.
  * PARENT_PATH is relative to the current working directory.
@@ -2110,13 +2084,8 @@ do_entry_deletion(struct edit_baton *eb,
       /* When we raise a tree conflict on a directory, we want to avoid
        * making any changes inside it. (Will an update ever try to make
        * further changes to or inside a directory it's just deleted?) */
-      {
-        svn_stringbuf_t *log_accum = NULL;
-
-        SVN_ERR(svn_wc__loggy_add_tree_conflict(&log_accum, tree_conflict,
-                                                pool));
-        SVN_ERR(svn_wc__wq_add_loggy(eb->db, dir_abspath, log_accum, pool));
-      }
+      SVN_ERR(svn_wc__loggy_add_tree_conflict(eb->db, dir_abspath,
+                                              tree_conflict, pool));
 
       SVN_ERR(remember_skipped_tree(eb, local_abspath));
 
@@ -2287,9 +2256,6 @@ delete_entry(const char *path,
 
   their_relpath = svn_relpath_join(pb->new_relpath, base, pool);
 
-  /* Flush parent log before potentially adding tree conflicts */
-  SVN_ERR(flush_log(pb, pool));
-
   return do_entry_deletion(pb->edit_baton, local_abspath,
                            their_relpath,
                            pb->in_deleted_and_tree_conflicted_subtree,
@@ -2321,7 +2287,7 @@ add_directory(const char *path,
                  || (!copyfrom_path &&
                      !SVN_IS_VALID_REVNUM(copyfrom_revision)));
 
-  SVN_ERR(make_dir_baton(&db, path, eb, pb, TRUE, pool));
+  SVN_ERR(make_dir_baton(&db, path, eb, pb, pool));
   *child_baton = db;
 
   if (pb->skip_descendants)
@@ -2357,9 +2323,6 @@ add_directory(const char *path,
       db->ambient_depth = svn_depth_infinity;
     }
 
-  /* Flush the log for the parent directory before going into this subtree. */
-  SVN_ERR(flush_log(pb, pool));
-
   /* Is this path a conflict victim? */
   SVN_ERR(node_already_conflicted(&already_conflicted, eb->db,
                                   db->local_abspath, pool));
@@ -2424,7 +2387,7 @@ add_directory(const char *path,
       (wc_kind == svn_wc__db_kind_unknown || !IS_NODE_PRESENT(status)))
     {
       /* Found an unversioned directory */
-      db->existed = TRUE;
+      db->obstruction_found = TRUE;
 
       if (!eb->allow_unver_obstructions)
         {
@@ -2542,9 +2505,10 @@ add_directory(const char *path,
 
               if (tree_conflict != NULL)
                 {
-                  /* Record this conflict so that its descendants are
-                     skipped silently. */
-                  SVN_ERR(svn_wc__loggy_add_tree_conflict(&pb->log_accum,
+                  /* Queue this conflict in the parent so that its descendants
+                     are skipped silently. */
+                  SVN_ERR(svn_wc__loggy_add_tree_conflict(eb->db,
+                                                          pb->local_abspath,
                                                           tree_conflict,
                                                           pool));
 
@@ -2680,7 +2644,7 @@ add_directory(const char *path,
 
       if (db->in_deleted_and_tree_conflicted_subtree)
         action = svn_wc_notify_update_add_deleted;
-      else if (db->existed)
+      else if (db->obstruction_found)
         action = svn_wc_notify_exists;
       else
         action = svn_wc_notify_update_add;
@@ -2708,7 +2672,7 @@ open_directory(const char *path,
   svn_wc_conflict_description2_t *tree_conflict = NULL;
   svn_wc__db_status_t status, base_status;
 
-  SVN_ERR(make_dir_baton(&db, path, eb, pb, FALSE, pool));
+  SVN_ERR(make_dir_baton(&db, path, eb, pb, pool));
   *child_baton = db;
 
   /* We should have a write lock on every directory touched.  */
@@ -2730,9 +2694,6 @@ open_directory(const char *path,
 
   SVN_ERR(check_path_under_root(pb->local_abspath, db->name, pool));
 
-  /* Flush the log for the parent directory before going into this subtree. */
-  SVN_ERR(flush_log(pb, pool));
-
   SVN_ERR(svn_wc__db_read_info(&status, NULL, &db->old_revision, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL,
                                &db->ambient_depth, NULL, NULL, NULL, NULL,
@@ -2781,8 +2742,9 @@ open_directory(const char *path,
   /* Remember the roots of any locally deleted trees. */
   if (tree_conflict != NULL)
     {
-      SVN_ERR(svn_wc__loggy_add_tree_conflict(&pb->log_accum, tree_conflict,
-                                              pool));
+      /* Place a tree conflict into the parent work queue.  */
+      SVN_ERR(svn_wc__loggy_add_tree_conflict(eb->db, pb->local_abspath,
+                                              tree_conflict, pool));
 
       do_notification(eb, db->local_abspath, svn_node_dir,
                       svn_wc_notify_tree_conflict, pool);
@@ -2914,9 +2876,8 @@ close_directory(void *dir_baton,
     {
       db->bump_info->skipped = TRUE;
 
-      /* The log accumulator better be empty because we aren't going to
-         be running any logs in this directory.  */
-      SVN_ERR_ASSERT(svn_stringbuf_isempty(db->log_accum));
+      /* ### hopefully this directory's queue is empty, cuz we're not
+         ### going to be running it!  */
 
       /* Allow the parent to complete its update. */
       SVN_ERR(maybe_bump_dir_info(eb, db->bump_info, db->pool));
@@ -3051,9 +3012,6 @@ close_directory(void *dir_baton,
                                   new_base_props, new_actual_props,
                                   TRUE /* write_base_props */, TRUE, pool));
 
-  /* Flush the log.  */
-  SVN_ERR(flush_log(db, pool));
-
   if (last_change)
     SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, db->local_abspath,
                                                     last_change->cmt_rev,
@@ -3083,7 +3041,7 @@ close_directory(void *dir_baton,
 
       if (db->in_deleted_and_tree_conflicted_subtree)
         action = svn_wc_notify_update_update_deleted;
-      else if (db->existed || db->add_existed)
+      else if (db->obstruction_found || db->add_existed)
         action = svn_wc_notify_exists;
       else
         action = svn_wc_notify_update_update;
@@ -3703,7 +3661,7 @@ add_file(const char *path,
   if (kind == svn_node_file &&
       (wc_kind == svn_wc__db_kind_unknown || !IS_NODE_PRESENT(status)))
     {
-      fb->existed = TRUE;
+      fb->obstruction_found = TRUE;
 
       if (!eb->allow_unver_obstructions)
         {
@@ -3821,15 +3779,12 @@ add_file(const char *path,
 
               if (tree_conflict != NULL)
                 {
-                  svn_stringbuf_t *log_accum = NULL;
-
                   /* Record the conflict so that the file is skipped silently
                      by the other callbacks. */
-                  SVN_ERR(svn_wc__loggy_add_tree_conflict(&log_accum,
+                  SVN_ERR(svn_wc__loggy_add_tree_conflict(eb->db,
+                                                          pb->local_abspath,
                                                           tree_conflict,
                                                           subpool));
-                  SVN_ERR(svn_wc__wq_add_loggy(eb->db, pb->local_abspath,
-                                               log_accum, subpool));
 
                   SVN_ERR(remember_skipped_tree(eb, fb->local_abspath));
                   fb->skip_this = TRUE;
@@ -3934,12 +3889,8 @@ open_file(const char *path,
   /* Is this path the victim of a newly-discovered tree conflict? */
   if (tree_conflict)
     {
-      svn_stringbuf_t *log_accum = NULL;
-
-      SVN_ERR(svn_wc__loggy_add_tree_conflict(&log_accum, tree_conflict,
-                                              pool));
-      SVN_ERR(svn_wc__wq_add_loggy(eb->db, pb->local_abspath, log_accum,
-                                   pool));
+      SVN_ERR(svn_wc__loggy_add_tree_conflict(eb->db, pb->local_abspath,
+                                              tree_conflict, pool));
 
       if (tree_conflict->reason == svn_wc_conflict_reason_deleted ||
           tree_conflict->reason == svn_wc_conflict_reason_replaced)
@@ -4074,7 +4025,7 @@ apply_textdelta(void *file_baton,
         finished inventing yet.)
   */
 
-  if (! fb->added)
+  if (! fb->adding_file)
     {
       if (replaced)
         SVN_ERR(svn_wc__get_revert_contents(&source, fb->edit_baton->db,
@@ -4283,7 +4234,7 @@ install_text_base(svn_stringbuf_t **log_
  * update all metadata so that the working copy believes it has a new
  * working revision of the file.  All of this work includes being
  * sensitive to eol translation, keyword substitution, and performing
- * all actions accumulated to FB->DIR_BATON->LOG_ACCUM.
+ * all actions accumulated the parent directory's work queue.
  *
  * If there's a new text base, NEW_TEXT_BASE_ABSPATH must be the full
  * pathname of the new text base, somewhere in the administrative area
@@ -4309,7 +4260,6 @@ merge_file(svn_stringbuf_t **log_accum,
            struct file_baton *fb,
            const char *new_text_base_abspath,
            const svn_checksum_t *actual_checksum,
-           svn_boolean_t lock_removed,
            apr_pool_t *pool)
 {
   struct edit_baton *eb = fb->edit_baton;
@@ -4318,10 +4268,6 @@ merge_file(svn_stringbuf_t **log_accum,
   svn_boolean_t is_replaced = FALSE;
   svn_boolean_t magic_props_changed;
   enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
-  svn_wc_conflict_version_t *left_version = NULL; /* ### Fill */
-  svn_wc_conflict_version_t *right_version = NULL; /* ### Fill */
-
-  /* Accumulated entry modifications. */
   svn_wc_entry_t tmp_entry;
   apr_uint64_t flags = 0;
 
@@ -4334,6 +4280,7 @@ merge_file(svn_stringbuf_t **log_accum,
 
          - The .svn/entries file still reflects the old version of F.
 
+         ### there is no fb->old_text_base_path
          - fb->old_text_base_path is the old pristine F.
            (This is only set if there's a new text base).
 
@@ -4373,16 +4320,34 @@ merge_file(svn_stringbuf_t **log_accum,
      call reads the entries from the database the returned entry is
      svn_wc_schedule_replace.  2 lines marked ### EBUG below. */
   if (fb->copied_working_text)
-    is_locally_modified = TRUE;
+    {
+      /* The file was copied here, and it came with both a (new) pristine
+         and a working file. Presumably, the working file is modified
+         relative to the new pristine.
+
+         The new pristine is in NEW_TEXT_BASE_ABSPATH, which should also
+         be FB->COPIED_TEXT_BASE.  */
+      is_locally_modified = TRUE;
+    }
   else if (entry && entry->file_external_path
            && entry->schedule == svn_wc_schedule_replace) /* ###EBUG */
-    is_locally_modified = FALSE;
-  else if (! fb->existed)
-    SVN_ERR(svn_wc__internal_text_modified_p(&is_locally_modified, eb->db,
-                                             fb->local_abspath, FALSE, FALSE,
-                                             pool));
+    {
+      is_locally_modified = FALSE;
+    }
+  else if (! fb->obstruction_found)
+    {
+      /* The working file is not an obstruction. So: is the file modified,
+         relative to its ORIGINAL pristine?  */
+      SVN_ERR(svn_wc__internal_text_modified_p(&is_locally_modified, eb->db,
+                                               fb->local_abspath,
+                                               FALSE /* force_comparison */,
+                                               FALSE /* compare_textbases */,
+                                               pool));
+    }
   else if (new_text_base_abspath)
     {
+      /* We have a new pristine to install. Is the file modified relative
+         to this new pristine?  */
       SVN_ERR(svn_wc__internal_versioned_file_modcheck(&is_locally_modified,
                                                        eb->db,
                                                        fb->local_abspath,
@@ -4390,7 +4355,10 @@ merge_file(svn_stringbuf_t **log_accum,
                                                        FALSE, pool));
     }
   else
-    is_locally_modified = FALSE;
+    {
+      /* No other potential changes, so the working file is NOT modified.  */
+      is_locally_modified = FALSE;
+    }
 
   if (entry && entry->schedule == svn_wc_schedule_replace
       && ! entry->file_external_path)  /* ### EBUG */
@@ -4407,26 +4375,24 @@ merge_file(svn_stringbuf_t **log_accum,
 
   /* For 'textual' merging, we implement this matrix.
 
-                          Text file                   Binary File
-                         -----------------------------------------------
-    "Local Mods" &&      | svn_wc_merge uses diff3, | svn_wc_merge     |
-    (!fb->existed ||     | possibly makes backups & | makes backups,   |
-     fb->add_existed)    | marks file as conflicted.| marks conflicted |
-                         -----------------------------------------------
-    "Local Mods" &&      |        Just leave obstructing file as-is.   |
-    fb->existed          |                                             |
-                         -----------------------------------------------
-    No Mods              |        Just overwrite working file.         |
-                         |                                             |
-                         -----------------------------------------------
-    File is Locally      |        Same as if 'No Mods' except we       |
-    Deleted              |        don't move the new text base to      |
-                         |        the working file location.           |
-                         -----------------------------------------------
-    File is Locally      |        Install the new text base.           |
-    Replaced             |        Leave working file alone.            |
-                         |                                             |
-                         -----------------------------------------------
+                                 Text file                  Binary File
+                               -----------------------------------------------
+    "Local Mods" &&            | svn_wc_merge uses diff3, | svn_wc_merge     |
+    (!fb->obstruction_found || | possibly makes backups & | makes backups,   |
+     fb->add_existed)          | marks file as conflicted.| marks conflicted |
+                               -----------------------------------------------
+    "Local Mods" &&            |        Just leave obstructing file as-is.   |
+    fb->obstruction_found      |                                             |
+                               -----------------------------------------------
+    No Mods                    |        Just overwrite working file.         |
+                               -----------------------------------------------
+    File is Locally            |        Same as if 'No Mods' except we       |
+    Deleted                    |        don't copy the new text base to      |
+                               |        the working file location.           |
+                               -----------------------------------------------
+    File is Locally            |        Install the new text base.           |
+    Replaced                   |        Leave working file alone.            |
+                               -----------------------------------------------
 
    So the first thing we do is figure out where we are in the
    matrix. */
@@ -4475,7 +4441,7 @@ merge_file(svn_stringbuf_t **log_accum,
               SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum,
                                       pool);
             }
-          else if (! fb->existed)
+          else if (! fb->obstruction_found)
             /* Working file exists and has local mods
                or is scheduled for addition but is not an obstruction. */
             {
@@ -4546,8 +4512,8 @@ merge_file(svn_stringbuf_t **log_accum,
               SVN_ERR(svn_wc__internal_merge(
                         log_accum, &merge_outcome,
                         eb->db,
-                        merge_left, left_version,
-                        new_text_base_abspath, right_version,
+                        merge_left, NULL,
+                        new_text_base_abspath, NULL,
                         fb->local_abspath,
                         fb->copied_working_text,
                         oldrev_str, newrev_str, mine_str,
@@ -4555,8 +4521,12 @@ merge_file(svn_stringbuf_t **log_accum,
                         eb->conflict_func, eb->conflict_baton,
                         eb->cancel_func, eb->cancel_baton,
                         pool));
-              SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum,
-                                      pool);
+
+              /* svn_wc__internal_merge() should have queued all of
+                 its work (including a bunch of stuff that we pre-loaded
+                 into the log accumulator).  */
+              SVN_ERR_ASSERT(*log_accum == NULL
+                             || svn_stringbuf_isempty(*log_accum));
 
               /* If we created a temporary left merge file, get rid of it. */
               if (delete_left)
@@ -4614,16 +4584,21 @@ merge_file(svn_stringbuf_t **log_accum,
           SVN_ERR(svn_wc__loggy_copy(log_accum, pb->local_abspath,
                                      tmptext, fb->local_abspath, pool, pool));
           SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
-        }
 
-      if (lock_removed)
-        {
-          /* If a lock was removed and we didn't update the text contents, we
-             might need to set the file read-only. */
-          SVN_ERR(svn_wc__loggy_maybe_set_readonly(log_accum, pb->local_abspath,
-                                                   fb->local_abspath, pool,
-                                                   pool));
-          SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
+          /* Done with the temporary file. Toss it.  */
+          /* ### stupid fucking function sometimes decides NOT to create a
+             ### temp file. but how are we supposed to know?  */
+          if (strcmp(tmptext, fb->local_abspath) != 0)
+          {
+            const svn_skel_t *work_item;
+
+            SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
+                                                 eb->db,
+                                                 tmptext,
+                                                 pool, pool));
+            SVN_ERR(svn_wc__db_wq_add(eb->db, pb->local_abspath,
+                                      work_item, pool));
+          }
         }
     }
 
@@ -4654,11 +4629,11 @@ merge_file(svn_stringbuf_t **log_accum,
   /* Log commands to handle text-timestamp and working-size,
      if the file is - or will be - unmodified and schedule-normal */
   if (!is_locally_modified &&
-      (fb->added || entry->schedule == svn_wc_schedule_normal))
+      (fb->adding_file || entry->schedule == svn_wc_schedule_normal))
     {
       /* Adjust working copy file unless this file is an allowed
          obstruction. */
-      if (fb->last_changed_date && !fb->existed)
+      if (fb->last_changed_date && !fb->obstruction_found)
         SVN_ERR(svn_wc__loggy_set_timestamp(
                   log_accum, pb->local_abspath,
                   fb->local_abspath, fb->last_changed_date,
@@ -4679,17 +4654,6 @@ merge_file(svn_stringbuf_t **log_accum,
       SVN_WC__FLUSH_LOG_ACCUM(eb->db, pb->local_abspath, *log_accum, pool);
     }
 
-  /* Clean up add-with-history temp file. */
-  if (fb->copied_text_base)
-    {
-      const svn_skel_t *work_item;
-
-      SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                           eb->db, fb->copied_text_base,
-                                           pool, pool));
-      SVN_ERR(svn_wc__db_wq_add(eb->db, pb->local_abspath, work_item, pool));
-    }
-
   /* Set the returned content state. */
 
   /* This is kind of interesting.  Even if no new text was
@@ -4875,14 +4839,14 @@ close_file(void *file_baton,
      tree. Behaviors are quite different based on the original state.  */
   SVN_ERR(svn_wc__get_entry(&entry, eb->db, fb->local_abspath, TRUE,
                             svn_node_file, FALSE, pool, pool));
-  if (! entry && ! fb->added)
+  if (! entry && ! fb->adding_file)
     return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                              _("'%s' is not under version control"),
                              svn_dirent_local_style(fb->local_abspath, pool));
 
   /* add_file() was called, or there was an added node here. Ensure that
      we have a BASE node to work with.  */
-  if (fb->added || fb->add_existed)
+  if (fb->adding_file || fb->add_existed)
     {
       SVN_ERR(construct_base_node(eb->db, fb->local_abspath,
                                   *eb->target_revision,
@@ -4983,13 +4947,37 @@ close_file(void *file_baton,
   SVN_ERR(merge_file(&delayed_log_accum,
                      &content_state, entry,
                      fb, new_base_abspath, md5_actual_checksum,
-                     lock_state == svn_wc_notify_lock_state_unlocked,
                      pool));
 
   /* Queue all operations.  */
   SVN_WC__FLUSH_LOG_ACCUM(eb->db, fb->dir_baton->local_abspath,
                           delayed_log_accum, pool);
 
+  /* Now that all the state has settled, should we update the readonly
+     status of the working file? The LOCK_STATE will signal what we should
+     do for this node.  */
+  if (new_base_abspath == NULL
+      && lock_state == svn_wc_notify_lock_state_unlocked)
+    {
+      /* If a lock was removed and we didn't update the text contents, we
+         might need to set the file read-only. */
+      SVN_ERR(svn_wc__loggy_maybe_set_readonly(eb->db,
+                                               fb->dir_baton->local_abspath,
+                                               fb->local_abspath, pool));
+    }
+
+  /* Clean up any temporary files.  */
+  if (fb->copied_text_base)
+    {
+      const svn_skel_t *work_item;
+
+      SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
+                                           eb->db, fb->copied_text_base,
+                                           pool, pool));
+      SVN_ERR(svn_wc__db_wq_add(eb->db, fb->dir_baton->local_abspath,
+                                work_item, pool));
+    }
+
   /* We have one less referrer to the directory's bump information. */
   SVN_ERR(maybe_bump_dir_info(eb, fb->bump_info, pool));
 
@@ -5003,12 +4991,12 @@ close_file(void *file_baton,
 
       if (fb->deleted)
         action = svn_wc_notify_update_add_deleted;
-      else if (fb->existed || fb->add_existed)
+      else if (fb->obstruction_found || fb->add_existed)
         {
           if (content_state != svn_wc_notify_state_conflicted)
             action = svn_wc_notify_exists;
         }
-      else if (fb->added)
+      else if (fb->adding_file)
         {
           action = svn_wc_notify_update_add;
         }
@@ -5712,6 +5700,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   svn_stringbuf_t *log_accum;
   struct last_change_info *last_change = NULL;
   svn_error_t *err;
+  const char *source_abspath = NULL;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   SVN_ERR_ASSERT(new_base_contents != NULL);
@@ -5866,7 +5855,6 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   /* Categorize the base properties. */
   {
     apr_array_header_t *regular_props;
-    apr_array_header_t *wc_props;
     apr_array_header_t *entry_props;
     apr_array_header_t *prop_array;
 
@@ -5875,7 +5863,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
     SVN_ERR(svn_prop_diffs(&prop_array, new_base_props,
                            apr_hash_make(pool), pool));
     SVN_ERR(svn_categorize_props(prop_array,
-                                 &entry_props, &wc_props, &regular_props,
+                                 &entry_props, NULL, &regular_props,
                                  pool));
 
     /* Put regular props back into a hash table. */
@@ -5907,40 +5895,18 @@ svn_wc_add_repos_file4(svn_wc_context_t 
   /* Install working file. */
   if (new_contents)
     {
-      /* If the caller gave us a new working file, copy it in place. */
       svn_stream_t *tmp_contents;
-      const char *tmp_text_path;
 
-      /* ### it may be nice to have an option to OP_FILE_INSTALL to allow
-         ### an installation from an alternate location (TMP_TEXT_PATH).  */
-
-      SVN_ERR(svn_stream_open_unique(&tmp_contents, &tmp_text_path,
+      /* If the caller gave us a new working file, copy it to a safe
+         (temporary) location. We'll then translate/copy that into place
+         after the node's state has been created.  */
+      SVN_ERR(svn_stream_open_unique(&tmp_contents, &source_abspath,
                                      temp_dir_abspath, svn_io_file_del_none,
                                      pool, pool));
       SVN_ERR(svn_stream_copy3(new_contents,
                                tmp_contents,
                                cancel_func, cancel_baton,
                                pool));
-
-      /* Translate new temporary text file to working text. */
-      SVN_ERR(svn_wc__loggy_copy(&log_accum, dir_abspath,
-                                 tmp_text_path, local_abspath,
-                                 pool, pool));
-      SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
-
-      /* After copying to the working directory, lose the temp file. */
-      {
-        const svn_skel_t *work_item;
-
-        SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                             db, tmp_text_path,
-                                             pool, pool));
-        /* ### we should pass WORK_ITEM to some wc_db api that constructs
-           ### this new node. but alas, we do so much of this in pieces,
-           ### and not using wc_db apis. so just manually add the work item
-           ### into the queue.  */
-        SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
-      }
     }
 
   /* Install new text base for copied files. Added files do NOT have a
@@ -5980,23 +5946,46 @@ svn_wc_add_repos_file4(svn_wc_context_t 
                 last_change->cmt_author,
                 pool));
     }
+  
+  /* ### /HACK */
 
   /* For added files without NEW_CONTENTS, then generate the working file
      from the provided "pristine" contents.  */
   if (new_contents == NULL && copyfrom_url == NULL)
-    {
-      /* Translate new temporary text file to working text. */
-      SVN_ERR(svn_wc__loggy_copy(&log_accum, dir_abspath,
-                                 tmp_text_base_abspath, local_abspath,
-                                 pool, pool));
-      SVN_WC__FLUSH_LOG_ACCUM(db, dir_abspath, log_accum, pool);
+    source_abspath = tmp_text_base_abspath;
 
-      /* After copying to the working directory, lose the temp file. */
-      {
-        const svn_skel_t *work_item;
+  {
+    const svn_skel_t *work_item;
+    svn_boolean_t record_fileinfo;
 
+    /* If new contents were provided, then we do NOT want to record the
+       file information. We assume the new contents do not match the
+       "proper" values for TRANSLATED_SIZE and LAST_MOD_TIME.  */
+    record_fileinfo = new_contents == NULL;
+
+    /* Install the working copy file (with appropriate translation) from
+       the appropriate source. SOURCE_ABSPATH will be NULL, indicating an
+       installation from the pristine (available for copied/moved files),
+       or it will specify a temporary file where we placed a "pristine"
+       (for an added file) or a detranslated local-mods file.  */
+    SVN_ERR(svn_wc__wq_build_file_install(&work_item,
+                                          db, local_abspath,
+                                          source_abspath,
+                                          FALSE /* use_commit_times */,
+                                          record_fileinfo,
+                                          pool, pool));
+    /* ### we should pass WORK_ITEM to some wc_db api that constructs
+       ### this new node. but alas, we do so much of this in pieces,
+       ### and not using wc_db apis. so just manually add the work item
+       ### into the queue.  */
+    SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
+
+    /* If we installed from somewhere besides the official pristine, then
+       it is a temporary file, which needs to be removed.  */
+    if (source_abspath != NULL)
+      {
         SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                             db, tmp_text_base_abspath,
+                                             db, source_abspath,
                                              pool, pool));
         /* ### we should pass WORK_ITEM to some wc_db api that constructs
            ### this new node. but alas, we do so much of this in pieces,
@@ -6004,28 +5993,7 @@ svn_wc_add_repos_file4(svn_wc_context_t 
            ### into the queue.  */
         SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
       }
-    }
-  
-  /* ### /HACK */
-
-  /* If a working file was not provided by the caller, then install one
-     from the text base (with appropriate translation). Note that the
-     text base is available only for copied files.  */
-  if (new_contents == NULL && copyfrom_url != NULL)
-    {
-      const svn_skel_t *work_item;
-
-      SVN_ERR(svn_wc__wq_build_file_install(&work_item,
-                                            db, local_abspath,
-                                            FALSE /* use_commit_times */,
-                                            TRUE /* record_fileinfo */,
-                                            pool, pool));
-      /* ### we should pass WORK_ITEM to some wc_db api that constructs
-         ### this new node. but alas, we do so much of this in pieces,
-         ### and not using wc_db apis. so just manually add the work item
-         ### into the queue.  */
-      SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, pool));
-    }
+  }
 
   return svn_error_return(svn_wc__wq_run(db, dir_abspath,
                                          cancel_func, cancel_baton,

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-metadata.sql?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-metadata.sql Sun Apr  4 09:09:34 2010
@@ -358,8 +358,10 @@ CREATE INDEX I_WORKING_PARENT ON WORKING
 
 /* The ACTUAL_NODE table describes text changes and property changes on each
    node in the WC, relative to the WORKING_NODE table row for the same path
-   (if present) or else to the BASE_NODE row for the same path (which must
-   exist in that case).
+   (if present) or else to the BASE_NODE row for the same path.  (Either a
+   WORKING_NODE row or a BASE_NODE row must exist if this node exists, but
+   an ACTUAL_NODE row can exist on its own if it is just recording info on
+   a non-present node - a tree conflict or a changelist, for example.)
 
    The ACTUAL_NODE table row for a given path exists if the node at that
    path is known to have text or property changes relative to its

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc-queries.sql Sun Apr  4 09:09:34 2010
@@ -186,10 +186,6 @@ where repos_id = ?1 and
   (repos_relpath = ?2 or
    repos_relpath like ?3 escape '#');
 
--- STMT_UPDATE_BASE_LAST_MOD_TIME
-update base_node set last_mod_time = ?3
-where wc_id = ?1 and local_relpath = ?2;
-
 -- STMT_UPDATE_BASE_FILEINFO
 UPDATE BASE_NODE SET translated_size = ?3, last_mod_time = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2;
@@ -359,10 +355,18 @@ SELECT wc_id, local_relpath, parent_relp
     repos_relpath, revnum FROM BASE_NODE
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
+-- ### the statement below should be setting copyfrom_revision!
 -- STMT_UPDATE_COPYFROM
 UPDATE WORKING_NODE set copyfrom_repos_id = ?3, copyfrom_repos_path = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2;
 
+-- STMT_UPDATE_COPYFROM_TO_INHERIT
+UPDATE WORKING_NODE SET
+  copyfrom_repos_id = null,
+  copyfrom_repos_path = null,
+  copyfrom_revnum = null
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
 -- STMT_DETERMINE_TREE_FOR_RECORDING
 SELECT 0 FROM BASE_NODE WHERE wc_id = ?1 AND local_relpath = ?2
 UNION

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.c Sun Apr  4 09:09:34 2010
@@ -3100,35 +3100,6 @@ svn_wc__db_op_revert(svn_wc__db_t *db,
   NOT_IMPLEMENTED();
 }
 
-svn_error_t *
-svn_wc__db_op_set_last_mod_time(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_time_t last_mod_time,
-                                apr_pool_t *scratch_pool)
-{
-  svn_wc__db_pdh_t *pdh;
-  const char *local_relpath;
-  svn_sqlite__stmt_t *stmt;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
-                              svn_sqlite__mode_readwrite,
-                              scratch_pool, scratch_pool));
-  VERIFY_USABLE_PDH(pdh);
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
-                                    STMT_UPDATE_BASE_LAST_MOD_TIME));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isi",
-                            pdh->wcroot->wc_id, local_relpath,
-                            last_mod_time));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-
-  flush_entries(pdh);
-
-  return SVN_NO_ERROR;
-}
-
 
 svn_error_t *
 svn_wc__db_op_read_tree_conflict(
@@ -6511,7 +6482,8 @@ svn_wc__db_temp_op_set_working_incomplet
                                db, local_dir_abspath,
                                scratch_pool, scratch_pool));
 
-  SVN_ERR_ASSERT(status == svn_wc__db_status_normal ||
+  /* Presence in WORKING_NODE must be normal or incomplete */
+  SVN_ERR_ASSERT(status == svn_wc__db_status_added ||
                  status == svn_wc__db_status_incomplete);
 
   SVN_ERR(get_statement_for_path(&stmt, db, local_dir_abspath,
@@ -6889,6 +6861,8 @@ make_copy_txn(void *baton,
       SVN_ERR(create_repos_id(&repos_id, repos_root_url, repos_uuid, sdb,
                               iterpool));
 
+      /* ### this is not setting the COPYFROM_REVISION column!!  */
+
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_COPYFROM));
       SVN_ERR(svn_sqlite__bindf(stmt, "isis",
                                 mcb->pdh->wcroot->wc_id,
@@ -7045,3 +7019,115 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
 
   return SVN_NO_ERROR;
 }
+
+
+svn_error_t *
+svn_wc__db_temp_elide_copyfrom(svn_wc__db_t *db,
+                               const char *local_abspath,
+                               apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  apr_int64_t original_repos_id;
+  const char *original_repos_relpath;
+  svn_revnum_t original_revision;
+  const char *parent_abspath;
+  const char *name;
+  svn_error_t *err;
+  const char *op_root_abspath;
+  const char *parent_repos_relpath;
+  const char *parent_uuid;
+  svn_revnum_t parent_revision;
+  const char *implied_relpath;
+  const char *original_uuid;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  SVN_ERR(parse_local_abspath(&pdh, &local_relpath, db, local_abspath,
+                              svn_sqlite__mode_readwrite,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
+
+  /* Examine the current WORKING_NODE row's copyfrom information. If there
+     is no WORKING node, then simply exit.  */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_SELECT_WORKING_NODE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  if (!have_row)
+    return svn_error_return(svn_sqlite__reset(stmt));
+
+  /* Already inheriting copyfrom information?  */
+  if (svn_sqlite__column_is_null(stmt, 9 /* copyfrom_repos_id */))
+    return svn_error_return(svn_sqlite__reset(stmt));
+
+  original_repos_id = svn_sqlite__column_int64(stmt, 9);
+  original_repos_relpath = svn_sqlite__column_text(stmt, 10, scratch_pool);
+  original_revision = svn_sqlite__column_revnum(stmt, 11);
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  /* If this node is copied/moved, then there MUST be a parent. The above
+     copyfrom values cannot be set on a wcroot.  */
+  svn_dirent_split(local_abspath, &parent_abspath, &name, scratch_pool);
+  err = svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL, NULL,
+                                 &parent_repos_relpath,
+                                 NULL,
+                                 &parent_uuid,
+                                 &parent_revision,
+                                 db, parent_abspath,
+                                 scratch_pool, scratch_pool);
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+        return svn_error_return(err);
+      svn_error_clear(err);
+
+      /* ### hunh? sometimes the parent is missing? stupid semi-stable
+         ### state crap, probably. don't bother trying to reset the
+         ### copyfrom data for this case.  */
+      return SVN_NO_ERROR;
+    }
+
+  /* Now we need to determine if the child's values are derivable from
+     the parent values.  */
+
+  /* If the revision numbers are not the same, then easy exit.  */
+  if (original_revision != parent_revision)
+    return SVN_NO_ERROR;
+
+  /* The child repos_relpath should be under the parent's.  */
+  if (svn_relpath_is_child(parent_repos_relpath,
+                           original_repos_relpath,
+                           NULL) == NULL)
+    return SVN_NO_ERROR;
+
+  /* Given the relpath from OP_ROOT_ABSPATH down to LOCAL_ABSPATH, compute
+     an implied REPOS_RELPATH. If that does not match the RELPATH we found,
+     then we can exit (the child is a new copy root).  */
+  implied_relpath = svn_relpath_join(parent_repos_relpath,
+                                     svn_dirent_skip_ancestor(op_root_abspath,
+                                                              local_abspath),
+                                     scratch_pool);
+  if (strcmp(implied_relpath, original_repos_relpath) != 0)
+    return SVN_NO_ERROR;
+
+  /* Everything matches up. Grab the details for ORIGINAL_REPOS_ID and
+     compare to the parent.  */
+  SVN_ERR(fetch_repos_info(NULL, &original_uuid,
+                           pdh->wcroot->sdb, original_repos_id,
+                           scratch_pool));
+  if (strcmp(original_uuid, parent_uuid) != 0)
+    return SVN_NO_ERROR;
+
+  /* The child's copyfrom information is derivable from the parent.
+     The data should be reset to null, indicating the derivation.  */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+                                    STMT_UPDATE_COPYFROM_TO_INHERIT));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", pdh->wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__update(NULL, stmt));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.h?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/wc_db.h Sun Apr  4 09:09:34 2010
@@ -1039,18 +1039,6 @@ svn_wc__db_op_revert(svn_wc__db_t *db,
                      apr_pool_t *scratch_pool);
 
 
-/* Set the last mod time cache to LAST_MOD_TIME for the appropriate BASE
-   node for LOCAL_ABSPATH in DB.
-
-   Use SCRATCH_POOL for any temporary allocations.
-*/
-svn_error_t *
-svn_wc__db_op_set_last_mod_time(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                apr_time_t last_mod_time,
-                                apr_pool_t *scratch_pool);
-
-
 /* Get any tree conflict associated with LOCAL_ABSPATH in DB, and put it
    in *TREE_CONFLICT, allocated in RESULT_POOL.
 
@@ -2126,6 +2114,14 @@ svn_wc__db_temp_op_make_copy(svn_wc__db_
                              apr_pool_t *scratch_pool);
 
 
+/* Elide the copyfrom information for LOCAL_ABSPATH if it can be derived
+   from the parent node.  */
+svn_error_t *
+svn_wc__db_temp_elide_copyfrom(svn_wc__db_t *db,
+                               const char *local_abspath,
+                               apr_pool_t *scratch_pool);
+
+
 /* @} */
 
 

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.c Sun Apr  4 09:09:34 2010
@@ -312,6 +312,8 @@ run_revert(svn_wc__db_t *db,
               reinstall_working = TRUE;
 #endif
 #if 0
+              /* ### try to avoid altering the timestamp if the intended
+                 ### contents are the same as current-contents.  */
               SVN_ERR(svn_wc__text_modified_internal_p(&reinstall_working,
                                                        db, local_abspath,
                                                        FALSE, FALSE,
@@ -325,6 +327,8 @@ run_revert(svn_wc__db_t *db,
           svn_boolean_t use_commit_times;
           apr_finfo_t finfo;
 
+          /* ### this should use OP_FILE_INSTALL.  */
+
           /* Copy from the text base to the working file. The working file
              specifies the params for translation.  */
           SVN_ERR(copy_and_translate(db, text_base_path, local_abspath,
@@ -933,7 +937,12 @@ svn_wc__wq_add_loggy(svn_wc__db_t *db,
                      const svn_stringbuf_t *log_content,
                      apr_pool_t *scratch_pool)
 {
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
+  svn_skel_t *work_item;
+
+  if (log_content == NULL || svn_stringbuf_isempty(log_content))
+    return SVN_NO_ERROR;
+
+  work_item = svn_skel__make_empty_list(scratch_pool);
 
   /* The skel still points at ADM_ABSPATH and LOG_CONTENT, but the skel will
      be serialized just below in the wq_add call.  */
@@ -1263,7 +1272,6 @@ log_do_committed(svn_wc__db_t *db,
   svn_boolean_t set_read_write = FALSE;
   const svn_wc_entry_t *orig_entry;
   svn_boolean_t prop_mods;
-  svn_wc_entry_t tmp_entry;
 
   /*** Perform sanity checking operations ***/
 
@@ -1389,6 +1397,8 @@ log_do_committed(svn_wc__db_t *db,
     {
       svn_boolean_t overwrote_working;
       apr_finfo_t finfo;
+      svn_filesize_t translated_size;
+      apr_time_t last_mod_time;
 
       SVN_ERR(svn_wc__db_global_commit(db, local_abspath,
                                        new_revision, new_date, new_author,
@@ -1425,12 +1435,12 @@ log_do_committed(svn_wc__db_t *db,
 
       /* We will compute and modify the size and timestamp */
 
-      tmp_entry.working_size = finfo.size;
-
-      /* ### svn_wc__db_op_set_last_mod_time()  */
+      translated_size = finfo.size;
 
       if (overwrote_working)
-        tmp_entry.text_time = finfo.mtime;
+        {
+          last_mod_time = finfo.mtime;
+        }
       else
         {
           /* The working copy file hasn't been overwritten, meaning
@@ -1477,15 +1487,12 @@ log_do_committed(svn_wc__db_t *db,
             }
           /* If they are the same, use the working file's timestamp,
              else use the base file's timestamp. */
-          tmp_entry.text_time = modified ? basef_finfo.mtime : finfo.mtime;
+          last_mod_time = modified ? basef_finfo.mtime : finfo.mtime;
         }
 
-      return svn_error_return(svn_wc__entry_modify2(
+      return svn_error_return(svn_wc__db_global_record_fileinfo(
                                 db, local_abspath,
-                                svn_node_unknown, FALSE,
-                                &tmp_entry,
-                                SVN_WC__ENTRY_MODIFY_WORKING_SIZE
-                                | SVN_WC__ENTRY_MODIFY_TEXT_TIME,
+                                translated_size, last_mod_time,
                                 pool));
     }
 
@@ -1516,6 +1523,7 @@ log_do_committed(svn_wc__db_t *db,
   /* Make sure our entry exists in the parent. */
   {
     const svn_wc_entry_t *dir_entry;
+    svn_wc_entry_t tmp_entry;
 
     /* Check if we have a valid record in our parent */
     SVN_ERR(svn_wc__get_entry(&dir_entry, db, local_abspath,
@@ -1917,6 +1925,7 @@ run_file_install(svn_wc__db_t *db,
                  apr_pool_t *scratch_pool)
 {
   const svn_skel_t *arg1 = work_item->children->next;
+  const svn_skel_t *arg4 = arg1->next->next->next;
   const char *local_abspath;
   svn_boolean_t use_commit_times;
   svn_boolean_t record_fileinfo;
@@ -1933,10 +1942,22 @@ run_file_install(svn_wc__db_t *db,
   use_commit_times = svn_skel__parse_int(arg1->next, scratch_pool) != 0;
   record_fileinfo = svn_skel__parse_int(arg1->next->next, scratch_pool) != 0;
 
-  /* Get the pristine contents (from WORKING or BASE, as appropriate).  */
-  SVN_ERR(svn_wc__get_pristine_contents(&src_stream, db, local_abspath,
-                                        scratch_pool, scratch_pool));
-  SVN_ERR_ASSERT(src_stream != NULL);
+  if (arg4 == NULL)
+    {
+      /* Get the pristine contents (from WORKING or BASE, as appropriate).  */
+      SVN_ERR(svn_wc__get_pristine_contents(&src_stream, db, local_abspath,
+                                            scratch_pool, scratch_pool));
+      SVN_ERR_ASSERT(src_stream != NULL);
+    }
+  else
+    {
+      const char *source_abspath;
+
+      /* Use the provided path for the source.  */
+      source_abspath = apr_pstrmemdup(scratch_pool, arg4->data, arg4->len);
+      SVN_ERR(svn_stream_open_readonly(&src_stream, source_abspath,
+                                       scratch_pool, scratch_pool));
+    }
 
   SVN_ERR(svn_wc__get_special(&special, db, local_abspath, scratch_pool));
   if (special)
@@ -2021,15 +2042,14 @@ run_file_install(svn_wc__db_t *db,
                                               scratch_pool));
     }
 
+  /* ### this should happen before we rename the file into place.  */
   if (record_fileinfo)
     {
-      /* ### ugh. switch this over to some new wc_db APIs.  */
-
-      svn_wc_entry_t tmp_entry;
+      apr_time_t last_mod_time;
       apr_finfo_t finfo;
 
       /* loggy_set_entry_timestamp_from_wc()  */
-      SVN_ERR(svn_io_file_affected_time(&tmp_entry.text_time,
+      SVN_ERR(svn_io_file_affected_time(&last_mod_time,
                                         local_abspath,
                                         scratch_pool));
 
@@ -2037,14 +2057,17 @@ run_file_install(svn_wc__db_t *db,
       SVN_ERR(svn_io_stat(&finfo, local_abspath,
                           APR_FINFO_MIN | APR_FINFO_LINK,
                           scratch_pool));
-      tmp_entry.working_size = finfo.size;
 
-      SVN_ERR(svn_wc__entry_modify2(db, local_abspath,
-                                    svn_node_unknown, FALSE,
-                                    &tmp_entry,
-                                    SVN_WC__ENTRY_MODIFY_TEXT_TIME
-                                      | SVN_WC__ENTRY_MODIFY_WORKING_SIZE,
-                                    scratch_pool));
+      SVN_ERR(svn_wc__db_global_record_fileinfo(db, local_abspath,
+                                                finfo.size, last_mod_time,
+                                                scratch_pool));
+
+      /* ### there used to be a call to entry_modify2() here, to set the
+         ### TRANSLATED_SIZE and LAST_MOD_TIME values. that function elided
+         ### copyfrom information that snuck into the database. it should
+         ### not be there in the first place, but we can manually get rid
+         ### of the erroneous, inheritable copyfrom data.  */
+      SVN_ERR(svn_wc__db_temp_elide_copyfrom(db, local_abspath, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -2055,6 +2078,7 @@ svn_error_t *
 svn_wc__wq_build_file_install(const svn_skel_t **work_item,
                               svn_wc__db_t *db,
                               const char *local_abspath,
+                              const char *source_abspath,
                               svn_boolean_t use_commit_times,
                               svn_boolean_t record_fileinfo,
                               apr_pool_t *result_pool,
@@ -2062,6 +2086,12 @@ svn_wc__wq_build_file_install(const svn_
 {
   svn_skel_t *build_item = svn_skel__make_empty_list(result_pool);
 
+  /* If a SOURCE_ABSPATH was provided, then put it into the skel. If this
+     value is not provided, then the file's pristine contents will be used.  */
+  if (source_abspath != NULL)
+    svn_skel__prepend_str(apr_pstrdup(result_pool, source_abspath),
+                          build_item, result_pool);
+
   svn_skel__prepend_int(record_fileinfo, build_item, result_pool);
   svn_skel__prepend_int(use_commit_times, build_item, result_pool);
   svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),

Modified: subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.h?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/svn-patch-improvements/subversion/libsvn_wc/workqueue.h Sun Apr  4 09:09:34 2010
@@ -66,11 +66,19 @@ svn_wc__wq_run(svn_wc__db_t *db,
    copy file at LOCAL_ABSPATH. If USE_COMMIT_TIMES is TRUE, then the newly
    installed file will use the nodes CHANGE_DATE for the file timestamp.
    If RECORD_FILEINFO is TRUE, then the resulting LAST_MOD_TIME and
-   TRANSLATED_SIZE will be recorded in the database.  */
+   TRANSLATED_SIZE will be recorded in the database.
+
+   If SOURCE_ABSPATH is NULL, then the pristine contents will be installed
+   (with appropriate translation). If SOURCE_ABSPATH is not NULL, then it
+   specifies a source file for the translation. The file must exist for as
+   long as *WORK_ITEM exists (and is queued). Typically, it will be a
+   temporary file, and an OP_FILE_REMOVE will be queued to later remove it.
+*/
 svn_error_t *
 svn_wc__wq_build_file_install(const svn_skel_t **work_item,
                               svn_wc__db_t *db,
                               const char *local_abspath,
+                              const char *source_abspath,
                               svn_boolean_t use_commit_times,
                               svn_boolean_t record_fileinfo,
                               apr_pool_t *result_pool,
@@ -121,7 +129,11 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
                       apr_pool_t *scratch_pool);
 
 
-/* ### temporary compat for mapping the old loggy into workqueue space.  */
+/* ### temporary compat for mapping the old loggy into workqueue space.
+
+   LOG_CONTENT may be NULL or reference an empty log. No work item will be
+   queued in this case.
+*/
 svn_error_t *
 svn_wc__wq_add_loggy(svn_wc__db_t *db,
                      const char *adm_abspath,

Modified: subversion/branches/svn-patch-improvements/subversion/mod_dav_svn/reports/get-locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-patch-improvements/subversion/mod_dav_svn/reports/get-locks.c?rev=930648&r1=930647&r2=930648&view=diff
==============================================================================
--- subversion/branches/svn-patch-improvements/subversion/mod_dav_svn/reports/get-locks.c (original)
+++ subversion/branches/svn-patch-improvements/subversion/mod_dav_svn/reports/get-locks.c Sun Apr  4 09:09:34 2010
@@ -41,7 +41,7 @@
 #include "../dav_svn.h"
 
 /* Respond to a get-locks-report request.  See description of this
-   report in libsvn_ra_dav/fetch.c.  */
+   report in libsvn_ra_neon/get_locks.c.  */
 
 
 #define SVN_APR_ERR(expr)                       \



Mime
View raw message