You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2010/03/03 17:15:28 UTC

svn commit: r918542 - in /subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c old-and-busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h

Author: rhuijben
Date: Wed Mar  3 16:15:27 2010
New Revision: 918542

URL: http://svn.apache.org/viewvc?rev=918542&view=rev
Log:
Update the last change information (before WC-NG known as entry properties)
directly in WC-DB instead of via entry updates. This allows keeping track of
these values a bit longer than before, as the next entry_write() might remove
some details.

Like many similar updates this moves some loggy operations to using the database
directly, which might introduce some issues if you happen to press ^C in the
wrong place. The only solution that completely resolve this will be to update
BASE_NODE in one step, which is planned before 1.7.

This fixes one specific merge scenario that now properly detects that the
sub-replacement is done via the parent instead of directly. (The commit of
merge_tests#34 doesn't record a separate replacement now.)

* subversion/libsvn_wc/entries.c
  (fold_entry): Stop updating last_change information.

* subversion/libsvn_wc/entries.h
  (SVN_WC__ENTRY_MODIFY_CMT_REV,
   SVN_WC__ENTRY_MODIFY_CMT_DATE,
   SVN_WC__ENTRY_MODIFY_CMT_AUTHOR): Remove now unused values.

* subversion/libsvn_wc/log.c
  (log_do_modify_entry): Remove early WC-NG hack, which unset .deleted on
    updating last change information.

* subversion/libsvn_wc/old-and-busted.c
  (svn_wc__atts_to_entry): Remove uses of SVN_WC__ENTRY_MODIFY_CMT_AUTHOR.

* subversion/libsvn_wc/update_editor.c
  (last_change_info): New struct.
  (accumulate_entry_props): Rename to ...
  (accumulate_last_change): ... this and collect the information in
    a last_change_info struct instead of writing a loggy operations.
    Reorder arguments to match new standard.

  (close_directory): Collect last_change_info and if available write
    it to BASE_NODE in the final update step.

  (merge_props,
   merge_file): Collect last_change_info and pass to caller.
  (close_file): Collect last_chanhe_info and write it to BASE_NODE
    if available. Unset entry.deleted when we are adding a new node.

  (install_added_props): Collect last_change_info and pass it to caller.
  (svn_wc_add_repos_file4): If last_change info is provided write it to
    WORKING_NODE.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_UPDATE_BASE_LAST_CHANGE,
   STMT_UPDATE_WORKING_LAST_CHANGE): New query.

* subversion/libsvn_wc/wc_db.c
  (svn_wc__db_temp_op_set_base_last_change,
   svn_wc__db_temp_op_set_working_last_change): New function.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_temp_op_set_base_last_change,
   svn_wc__db_temp_op_set_working_last_change): New function.

Modified:
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/libsvn_wc/entries.h
    subversion/trunk/subversion/libsvn_wc/log.c
    subversion/trunk/subversion/libsvn_wc/old-and-busted.c
    subversion/trunk/subversion/libsvn_wc/update_editor.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Mar  3 16:15:27 2010
@@ -2587,17 +2587,7 @@
       ? apr_pstrdup(pool, entry->prejfile)
                           : NULL;
 
-  /* Last-commit stuff */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_REV)
-    cur_entry->cmt_rev = entry->cmt_rev;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_DATE)
-    cur_entry->cmt_date = entry->cmt_date;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_AUTHOR)
-    cur_entry->cmt_author = entry->cmt_author
-      ? apr_pstrdup(pool, entry->cmt_author)
-                            : NULL;
+  /* Last-commit flags are no longer passed to entry_modify() */
 
   /* LOCK flags are no longer passed to entry_modify().  */
 

Modified: subversion/trunk/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.h?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.h (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.h Wed Mar  3 16:15:27 2010
@@ -108,9 +108,6 @@
 #define SVN_WC__ENTRY_MODIFY_CONFLICT_NEW       APR_INT64_C(0x0000000000002000)
 #define SVN_WC__ENTRY_MODIFY_CONFLICT_WRK       APR_INT64_C(0x0000000000004000)
 #define SVN_WC__ENTRY_MODIFY_PREJFILE           APR_INT64_C(0x0000000000008000)
-#define SVN_WC__ENTRY_MODIFY_CMT_REV            APR_INT64_C(0x0000000000010000)
-#define SVN_WC__ENTRY_MODIFY_CMT_DATE           APR_INT64_C(0x0000000000020000)
-#define SVN_WC__ENTRY_MODIFY_CMT_AUTHOR         APR_INT64_C(0x0000000000040000)
 /* OPEN */
 #define SVN_WC__ENTRY_MODIFY_INCOMPLETE         APR_INT64_C(0x0000000000100000)
 #define SVN_WC__ENTRY_MODIFY_ABSENT             APR_INT64_C(0x0000000000200000)

Modified: subversion/trunk/subversion/libsvn_wc/log.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/log.c?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/log.c (original)
+++ subversion/trunk/subversion/libsvn_wc/log.c Wed Mar  3 16:15:27 2010
@@ -475,40 +475,6 @@
   if (valuestr && strcmp(valuestr, "true") == 0)
     modify_flags |= SVN_WC__ENTRY_MODIFY_FORCE;
 
-  /* It is possible that we will find a log that has a misordered sequence
-     of entry modifications and wcprop modifications. The entry must be
-     "not hidden" before wcprops can be installed. The sequence of actions
-     will look like:
-
-       1. modify_entry
-       2. modify_wcprops
-       3. modify_entry(DELETED=FALSE)
-
-     Step 2 will fail if the current node is marked DELETED. r36697 fixes
-     the ordering, moving step 3 to the beginning of the sequence. However,
-     old logs may still contain the above sequence. To compensate, we will
-     attempt to detect the pattern used by step 1, and preemptively clear
-     the DELETED flag.
-
-     The misordered entry is written by accumulate_entry_props() in
-     update_editor.c. That may modify the CMT_* values and/or the UUID.
-     If we see any of those, then we've detected a modify_entry constructed
-     by that function. And that means we *just* ran a step 3 (new code)
-     or we *will* run a step 3 (too late; old code). In both situations,
-     we can safely clear the DELETED flag.
-
-     The UUID modification is *only* performed by that function. The CMT_*
-     changes are also performed by process_committed_leaf() in adm_ops.c.
-     A just-committed node setting these values will NEVER be DELETED,
-     so it is safe to clear the value.  */
-  if (modify_flags & (SVN_WC__ENTRY_MODIFY_CMT_REV
-                      | SVN_WC__ENTRY_MODIFY_CMT_DATE
-                      | SVN_WC__ENTRY_MODIFY_CMT_AUTHOR))
-    {
-      entry->deleted = FALSE;
-      modify_flags |= SVN_WC__ENTRY_MODIFY_DELETED;
-    }
-
   /* Now write the new entry out. Note that we want to always operate
      on the stub if name is not THIS_DIR. This loggy function is intended
      to operate on the data in ADM_ABSPATH, so we do NOT want to reach
@@ -1086,17 +1052,7 @@
                  SVN_WC__ENTRY_ATTR_CHECKSUM,
                  entry->checksum);
 
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_REV,
-                 SVN_WC__ENTRY_ATTR_CMT_REV,
-                 apr_psprintf(scratch_pool, "%ld", entry->cmt_rev));
-
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_DATE,
-                 SVN_WC__ENTRY_ATTR_CMT_DATE,
-                 svn_time_to_cstring(entry->cmt_date, scratch_pool));
-
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_AUTHOR,
-                 SVN_WC__ENTRY_ATTR_CMT_AUTHOR,
-                 entry->cmt_author);
+  /* Note: Last-commit flags are no longer passed to this function. */
 
   /* Note: LOCK flags are no longer passed to this function.  */
 

Modified: subversion/trunk/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/old-and-busted.c?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/trunk/subversion/libsvn_wc/old-and-busted.c Wed Mar  3 16:15:27 2010
@@ -946,7 +946,6 @@
     if (cmt_datestr)
       {
         SVN_ERR(svn_time_from_cstring(&entry->cmt_date, cmt_datestr, pool));
-        *modify_flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;
       }
     else
       entry->cmt_date = 0;
@@ -956,15 +955,13 @@
     if (cmt_revstr)
       {
         entry->cmt_rev = SVN_STR_TO_REV(cmt_revstr);
-        *modify_flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;
       }
     else
       entry->cmt_rev = SVN_INVALID_REVNUM;
 
     entry->cmt_author = extract_string(modify_flags, atts,
                                        SVN_WC__ENTRY_ATTR_CMT_AUTHOR,
-                                       SVN_WC__ENTRY_MODIFY_CMT_AUTHOR,
-                                       FALSE, pool);
+                                       0, FALSE, pool);
   }
 
   /* NOTE: we do not set modify_flags values since the lock attributes only

Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed Mar  3 16:15:27 2010
@@ -1188,25 +1188,35 @@
 }
 
 
-/* Accumulate tags in LOG_ACCUM (associated with ADM_ABSPATH) to set
-   ENTRY_PROPS for PATH.
+/* Container for the common "Entry props" */
+struct last_change_info
+{
+  /** last revision this was changed */
+  svn_revnum_t cmt_rev;
+
+  /** last date this was changed */
+  apr_time_t cmt_date;
+
+  /** last commit author of this item */
+  const char *cmt_author;
+};
+
+/* Accumulate last change info in LAST_CHANGE to set on LOCAL_ABSPATH.
    ENTRY_PROPS is an array of svn_prop_t* entry props.
-   If ENTRY_PROPS contains the removal of a lock token, all entryprops
-   related to a lock will be removed and LOCK_STATE, if non-NULL, will be
-   set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL
+   If ENTRY_PROPS contains the removal of a lock token, the lock info is
+   directly removed from LOCAL_ABSPATH in DB and LOCK_STATE, if non-NULL, will
+   be set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL
    will be set to svn_wc_lock_state_unchanged. */
 static svn_error_t *
-accumulate_entry_props(svn_stringbuf_t *log_accum,
-                       svn_wc__db_t *db,
-                       const char *adm_abspath,
+accumulate_last_change(struct last_change_info **last_change,
                        svn_wc_notify_lock_state_t *lock_state,
-                       const char *path,
+                       svn_wc__db_t *db,
+                       const char *local_abspath,
                        apr_array_header_t *entry_props,
-                       apr_pool_t *pool)
+                       apr_pool_t *scratch_pool,
+                       apr_pool_t *result_pool)
 {
   int i;
-  svn_wc_entry_t tmp_entry;
-  apr_uint64_t flags = 0;
 
   if (lock_state)
     *lock_state = svn_wc_notify_lock_state_unchanged;
@@ -1217,11 +1227,10 @@
       const char *val;
 
       /* The removal of the lock-token entryprop means that the lock was
-         defunct. */
+         defunct, so remove it directly. */
       if (! strcmp(prop->name, SVN_PROP_ENTRY_LOCK_TOKEN))
         {
-          SVN_WC__FLUSH_LOG_ACCUM(db, adm_abspath, log_accum, pool);
-          SVN_ERR(svn_wc__loggy_delete_lock(db, adm_abspath, path, pool));
+          SVN_ERR(svn_wc__db_lock_remove(db, local_abspath, scratch_pool));
 
           if (lock_state)
             *lock_state = svn_wc_notify_lock_state_unlocked;
@@ -1236,29 +1245,23 @@
 
       val = prop->value->data;
 
-      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
+      if (*last_change == NULL)
         {
-          flags |= SVN_WC__ENTRY_MODIFY_CMT_AUTHOR;
-          tmp_entry.cmt_author = val;
+          *last_change = apr_pcalloc(result_pool, sizeof(**last_change));
+          (*last_change)->cmt_rev = SVN_INVALID_REVNUM;
         }
+
+      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
+        (*last_change)->cmt_author = apr_pstrdup(result_pool, val);
       else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_REV))
-        {
-          flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;
-          tmp_entry.cmt_rev = SVN_STR_TO_REV(val);
-        }
+        (*last_change)->cmt_rev = SVN_STR_TO_REV(val);
       else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_DATE))
-        {
-          flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;
-          SVN_ERR(svn_time_from_cstring(&tmp_entry.cmt_date, val, pool));
-        }
+        SVN_ERR(svn_time_from_cstring(&((*last_change)->cmt_date), val,
+                                      scratch_pool));
       /* Starting with Subversion 1.7 we ignore the SVN_PROP_ENTRY_UUID
          property here. */
     }
 
-  if (flags)
-    SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, adm_abspath,
-                                       path, &tmp_entry, flags, pool, pool));
-
   return SVN_NO_ERROR;
 }
 
@@ -3173,6 +3176,7 @@
 {
   struct dir_baton *db = dir_baton;
   struct edit_baton *eb = db->edit_baton;
+  struct last_change_info *last_change = NULL;
   svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
   apr_array_header_t *entry_props, *wc_props, *regular_props;
   apr_hash_t *base_props = NULL, *working_props = NULL;
@@ -3303,10 +3307,9 @@
                     _("Couldn't do property merge"));
         }
 
-      SVN_ERR(accumulate_entry_props(dirprop_log, eb->db,
-                                     db->local_abspath,
-                                     NULL, db->local_abspath, entry_props,
-                                     pool));
+      SVN_ERR(accumulate_last_change(&last_change, NULL, eb->db,
+                                     db->local_abspath, entry_props,
+                                     pool, pool));
 
       /* Handle the wcprops. */
       if (wc_props && wc_props->nelts > 0)
@@ -3329,6 +3332,14 @@
 
   /* Flush and run 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,
+                                                    last_change->cmt_date,
+                                                    last_change->cmt_author,
+                                                    pool));
+
   SVN_ERR(svn_wc__run_log2(eb->db, db->local_abspath, pool));
 
   /* We're done with this directory, so remove one reference from the
@@ -4493,6 +4504,7 @@
             svn_wc_notify_lock_state_t *lock_state,
             apr_hash_t **new_base_props,
             apr_hash_t **new_actual_props,
+            struct last_change_info **last_change,
             svn_wc__db_t *db,
             const char *file_abspath,
             const char *dir_abspath,
@@ -4547,9 +4559,9 @@
      Note that no merging needs to happen; these kinds of props aren't
      versioned, so if the property is present, we overwrite the value. */
   if (entry_props)
-    SVN_ERR(accumulate_entry_props(log_accum, db, dir_abspath,
-                                   lock_state, file_abspath, entry_props,
-                                   pool));
+    SVN_ERR(accumulate_last_change(last_change, lock_state,
+                                   db, file_abspath, entry_props,
+                                   pool, pool));
   else
     *lock_state = svn_wc_notify_lock_state_unchanged;
 
@@ -4653,6 +4665,7 @@
            svn_wc_notify_lock_state_t *lock_state,
            apr_hash_t **new_base_props,
            apr_hash_t **new_actual_props,
+           struct last_change_info **last_change,
            struct file_baton *fb,
            const char *new_text_base_path,
            const svn_checksum_t *actual_checksum,
@@ -4722,7 +4735,7 @@
      any file content merging, since that process might expand keywords, in
      which case we want the new entryprops to be in place. */
   SVN_ERR(merge_props(log_accum, prop_state, lock_state,
-                      new_base_props, new_actual_props,
+                      new_base_props, new_actual_props, last_change,
                       eb->db, fb->local_abspath, pb->local_abspath,
                       left_version, right_version,
                       fb->propchanges,
@@ -5065,6 +5078,7 @@
 {
   struct file_baton *fb = file_baton;
   struct edit_baton *eb = fb->edit_baton;
+  struct last_change_info *last_change = NULL;
   svn_wc_notify_state_t content_state, prop_state;
   svn_wc_notify_lock_state_t lock_state;
   svn_checksum_t *expected_checksum = NULL;
@@ -5132,8 +5146,8 @@
 
   /* It's a small world, after all. */
   SVN_ERR(merge_file(&content_state, &prop_state, &lock_state,
-                     &new_base_props, &new_actual_props, fb,
-                     new_base_path, md5_actual_checksum, pool));
+                     &new_base_props, &new_actual_props, &last_change,
+                     fb, new_base_path, md5_actual_checksum, pool));
 
 
   if (fb->added || fb->add_existed)
@@ -5144,11 +5158,15 @@
                    be removed soon anyway.
 
          ### HACK: The loggy stuff checked the preconditions for us,
-                   we just make the property code happy here. */
+                   we just make the property code happy here. 
+
+         We can also clear entry.deleted here, as we are adding a new
+         BASE_NODE anyway */
       svn_wc_entry_t tmp_entry;
       svn_stringbuf_t *create_log = NULL;
       apr_uint64_t flags = SVN_WC__ENTRY_MODIFY_KIND
-                           | SVN_WC__ENTRY_MODIFY_REVISION;
+                           | SVN_WC__ENTRY_MODIFY_REVISION
+                           | SVN_WC__ENTRY_MODIFY_DELETED;
 
       if (fb->add_existed)
         {
@@ -5163,6 +5181,7 @@
 
       tmp_entry.kind = svn_node_file;
       tmp_entry.revision = *eb->target_revision;
+      tmp_entry.deleted = FALSE;
 
       SVN_ERR(svn_wc__loggy_entry_modify(&create_log,
                                          fb->dir_baton->local_abspath,
@@ -5175,8 +5194,23 @@
                                    fb->dir_baton->local_abspath,
                                    create_log,
                                    pool));
+
+      SVN_ERR(svn_wc__wq_run(eb->db,
+                             fb->dir_baton->local_abspath,
+                             NULL, NULL, pool));
     }
 
+  /* ### Hack: The following block should be an atomic operation (including the install
+               loggy install portions of some functions called above */
+  SVN_ERR_ASSERT(last_change != NULL); /* Should always be not NULL for files */
+
+  if (last_change)
+    SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, fb->local_abspath,
+                                                    last_change->cmt_rev,
+                                                    last_change->cmt_date,
+                                                    last_change->cmt_author,
+                                                    pool));
+
   if (new_base_props || new_actual_props)
       SVN_ERR(svn_wc__install_props(eb->db, fb->local_abspath,
                                     new_base_props, new_actual_props,
@@ -5866,7 +5900,7 @@
    be an access baton for DST_PATH.
    Use @a POOL for temporary allocations. */
 static svn_error_t *
-install_added_props(svn_stringbuf_t *log_accum,
+install_added_props(struct last_change_info **last_change,
                     svn_wc__db_t *db,
                     const char *dir_abspath,
                     const char *local_abspath,
@@ -5894,8 +5928,8 @@
   }
 
   /* Install the entry props. */
-  SVN_ERR(accumulate_entry_props(log_accum, db, dir_abspath,
-                                 NULL, local_abspath, entry_props, pool));
+  SVN_ERR(accumulate_last_change(last_change, NULL, db, local_abspath,
+                                 entry_props, pool, pool));
 
   return svn_error_return(svn_wc__db_base_set_dav_cache(db, local_abspath,
                                         prop_hash_from_array(wc_props, pool),
@@ -5928,6 +5962,7 @@
   const char *temp_dir_abspath;
   svn_stringbuf_t *pre_props_accum;
   svn_stringbuf_t *post_props_accum;
+  struct last_change_info *last_change = NULL;
 
   SVN_ERR(svn_wc__text_base_path(&text_base_path, wc_ctx->db, local_abspath,
                                  FALSE, pool));
@@ -6020,7 +6055,7 @@
 
   /* Install the props before the loggy translation, so that it has access to
      the properties for this file. */
-  SVN_ERR(install_added_props(post_props_accum, wc_ctx->db, dir_abspath,
+  SVN_ERR(install_added_props(&last_change, wc_ctx->db, dir_abspath,
                               local_abspath, &new_base_props, new_props, pool));
 
   /* Copy the text base contents into a temporary file so our log
@@ -6096,6 +6131,17 @@
   SVN_ERR(svn_wc__install_props(wc_ctx->db, local_abspath, new_base_props,
                                 new_props ? new_props : new_base_props,
                                 TRUE, FALSE, pool));
+
+  SVN_ERR(svn_wc__run_log2(wc_ctx->db, dir_abspath, pool));
+
+  /* ### HACK: The following code should be performed in the same transaction as the install */
+  if (last_change)
+    SVN_ERR(svn_wc__db_temp_op_set_working_last_change(wc_ctx->db, local_abspath,
+                                                       last_change->cmt_rev,
+                                                       last_change->cmt_date,
+                                                       last_change->cmt_author,
+                                                       pool));
+  /* ### /HACK */
   SVN_ERR(svn_wc__wq_add_loggy(wc_ctx->db, dir_abspath, post_props_accum, pool));
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Mar  3 16:15:27 2010
@@ -372,6 +372,14 @@
 update base_node set file_external = ?3
 where wc_id = ?1 and local_relpath = ?2;
 
+-- STMT_UPDATE_BASE_LAST_CHANGE
+update base_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
+where wc_id = ?1 and local_relpath = ?2;
+
+-- STMT_UPDATE_WORKING_LAST_CHANGE
+update working_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
+where wc_id = ?1 and local_relpath = ?2;
+
 /* ------------------------------------------------------------------------- */
 
 /* these are used in upgrade.c  */

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Mar  3 16:15:27 2010
@@ -6232,4 +6232,93 @@
    }
 
   return SVN_NO_ERROR;
-}
\ No newline at end of file
+}
+
+svn_error_t *
+svn_wc__db_temp_op_set_base_last_change(svn_wc__db_t *db,
+                                        const char *local_abspath,
+                                        svn_revnum_t changed_rev,
+                                        apr_time_t changed_date,
+                                        const char *changed_author,
+                                        apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  svn_sqlite__stmt_t *stmt;
+  const char *local_relpath;
+  int affected;
+
+  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_CHANGE));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "isiis",
+                            pdh->wcroot->wc_id, local_relpath,
+                            (apr_int64_t)changed_rev,
+                            (apr_int64_t)changed_date,
+                            changed_author));
+
+  SVN_ERR(svn_sqlite__update(&affected, stmt));
+
+  /* ### Theoretically this check can fail if all the values match
+         the values in the database. But we only call this function
+         if the revision changes */
+  if (affected != 1)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("'%s' has no BASE_NODE"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  flush_entries(pdh);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_temp_op_set_working_last_change(svn_wc__db_t *db,
+                                           const char *local_abspath,
+                                           svn_revnum_t changed_rev,
+                                           apr_time_t changed_date,
+                                           const char *changed_author,
+                                           apr_pool_t *scratch_pool)
+{
+  svn_wc__db_pdh_t *pdh;
+  svn_sqlite__stmt_t *stmt;
+  const char *local_relpath;
+  int affected;
+
+  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_WORKING_LAST_CHANGE));
+
+  SVN_ERR(svn_sqlite__bindf(stmt, "isiis",
+                            pdh->wcroot->wc_id, local_relpath,
+                            (apr_int64_t)changed_rev,
+                            (apr_int64_t)changed_date,
+                            changed_author));
+
+  SVN_ERR(svn_sqlite__update(&affected, stmt));
+
+  /* The following check might fail if none of the values changes.
+     But currently this function is never called in such cases */
+  if (affected != 1)
+    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                             _("'%s' has no WORKING_NODE"),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
+
+  flush_entries(pdh);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=918542&r1=918541&r2=918542&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Mar  3 16:15:27 2010
@@ -2034,6 +2034,24 @@
                                           apr_pool_t *scratch_pool);
 
 
+/* Update changed information in BASE_NODE with the supplied values */
+svn_error_t *
+svn_wc__db_temp_op_set_base_last_change(svn_wc__db_t *db,
+                                        const char *local_abspath,
+                                        svn_revnum_t changed_rev,
+                                        apr_time_t changed_date,
+                                        const char *changed_author,
+                                        apr_pool_t *scratch_pool);
+
+/* Update changed information in WORKING_NODE with the supplied values */
+svn_error_t *
+svn_wc__db_temp_op_set_working_last_change(svn_wc__db_t *db,
+                                           const char *local_abspath,
+                                           svn_revnum_t changed_rev,
+                                           apr_time_t changed_date,
+                                           const char *changed_author,
+                                           apr_pool_t *scratch_pool);
+
 /** @} */
 
 



RE: RE: svn commit: r918542 - in /subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c old-and-busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h

Posted by Bert Huijben <be...@qqmail.nl>.
Thanks,

 

(I think I add some very very old working copy later tonight to
automatically check what you were afraid of :))

 

Have a good flight!

 

                Bert

 

From: Greg Stein [mailto:gstein@gmail.com] 
Sent: woensdag 3 maart 2010 18:40
To: Bert Huijben
Cc: dev@subversion.apache.org
Subject: Re: RE: svn commit: r918542 - in
/subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c
old-and-busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h

 

Hrm. Okee... sorry then; I'll review in solid detail after plane flight,
when I'm back to my laptop. 

On Mar 3, 2010 9:35 AM, "Bert Huijben" <be...@qqmail.nl> wrote:



> -----Original Message-----
> From: Greg Stein [mailto:gstein@gmail.com]
> Sent: woensdag 3 maart...

Yes, the ones in old-and-busted.c, but I didn't remove those; see the diff.
(That flag which keeps track of what is modified there, is ignored for about
a year there).

I just set the update flag to 0 there, like we did for similar changes. I
just removed the write ones in svn_wc__loggy_entry_modify, as we are no
longer writing them in the log.

When we are reading the entire entry (like on upgrades) the code still works
as before.

       Bert


Re: RE: svn commit: r918542 - in /subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c old-and-busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h

Posted by Greg Stein <gs...@gmail.com>.
Hrm. Okee... sorry then; I'll review in solid detail after plane flight,
when I'm back to my laptop.

On Mar 3, 2010 9:35 AM, "Bert Huijben" <be...@qqmail.nl> wrote:



> -----Original Message-----
> From: Greg Stein [mailto:gstein@gmail.com]
> Sent: woensdag 3 maart...
Yes, the ones in old-and-busted.c, but I didn't remove those; see the diff.
(That flag which keeps track of what is modified there, is ignored for about
a year there).

I just set the update flag to 0 there, like we did for similar changes. I
just removed the write ones in svn_wc__loggy_entry_modify, as we are no
longer writing them in the log.

When we are reading the entire entry (like on upgrades) the code still works
as before.

       Bert

RE: svn commit: r918542 - in /subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c old-and-busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h

Posted by Bert Huijben <be...@qqmail.nl>.

> -----Original Message-----
> From: Greg Stein [mailto:gstein@gmail.com]
> Sent: woensdag 3 maart 2010 17:22
> To: dev@subversion.apache.org
> Subject: Re: svn commit: r918542 - in
> /subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c old-and-
> busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h
> 
> Please revert.
> 
> The atts_to_entry stuff for the CMT_AUTHOR and friends needs to
> remain. That is how we load old entries files.

Yes, the ones in old-and-busted.c, but I didn't remove those; see the diff. 
(That flag which keeps track of what is modified there, is ignored for about
a year there).

I just set the update flag to 0 there, like we did for similar changes. I
just removed the write ones in svn_wc__loggy_entry_modify, as we are no
longer writing them in the log.

When we are reading the entire entry (like on upgrades) the code still works
as before.

	Bert

Re: svn commit: r918542 - in /subversion/trunk/subversion/libsvn_wc: entries.c entries.h log.c old-and-busted.c update_editor.c wc-queries.sql wc_db.c wc_db.h

Posted by Greg Stein <gs...@gmail.com>.
Please revert.

The atts_to_entry stuff for the CMT_AUTHOR and friends needs to
remain. That is how we load old entries files.

-g

On Wed, Mar 3, 2010 at 11:15,  <rh...@apache.org> wrote:
> Author: rhuijben
> Date: Wed Mar  3 16:15:27 2010
> New Revision: 918542
>
> URL: http://svn.apache.org/viewvc?rev=918542&view=rev
> Log:
> Update the last change information (before WC-NG known as entry properties)
> directly in WC-DB instead of via entry updates. This allows keeping track of
> these values a bit longer than before, as the next entry_write() might remove
> some details.
>
> Like many similar updates this moves some loggy operations to using the database
> directly, which might introduce some issues if you happen to press ^C in the
> wrong place. The only solution that completely resolve this will be to update
> BASE_NODE in one step, which is planned before 1.7.
>
> This fixes one specific merge scenario that now properly detects that the
> sub-replacement is done via the parent instead of directly. (The commit of
> merge_tests#34 doesn't record a separate replacement now.)
>
> * subversion/libsvn_wc/entries.c
>  (fold_entry): Stop updating last_change information.
>
> * subversion/libsvn_wc/entries.h
>  (SVN_WC__ENTRY_MODIFY_CMT_REV,
>   SVN_WC__ENTRY_MODIFY_CMT_DATE,
>   SVN_WC__ENTRY_MODIFY_CMT_AUTHOR): Remove now unused values.
>
> * subversion/libsvn_wc/log.c
>  (log_do_modify_entry): Remove early WC-NG hack, which unset .deleted on
>    updating last change information.
>
> * subversion/libsvn_wc/old-and-busted.c
>  (svn_wc__atts_to_entry): Remove uses of SVN_WC__ENTRY_MODIFY_CMT_AUTHOR.
>
> * subversion/libsvn_wc/update_editor.c
>  (last_change_info): New struct.
>  (accumulate_entry_props): Rename to ...
>  (accumulate_last_change): ... this and collect the information in
>    a last_change_info struct instead of writing a loggy operations.
>    Reorder arguments to match new standard.
>
>  (close_directory): Collect last_change_info and if available write
>    it to BASE_NODE in the final update step.
>
>  (merge_props,
>   merge_file): Collect last_change_info and pass to caller.
>  (close_file): Collect last_chanhe_info and write it to BASE_NODE
>    if available. Unset entry.deleted when we are adding a new node.
>
>  (install_added_props): Collect last_change_info and pass it to caller.
>  (svn_wc_add_repos_file4): If last_change info is provided write it to
>    WORKING_NODE.
>
> * subversion/libsvn_wc/wc-queries.sql
>  (STMT_UPDATE_BASE_LAST_CHANGE,
>   STMT_UPDATE_WORKING_LAST_CHANGE): New query.
>
> * subversion/libsvn_wc/wc_db.c
>  (svn_wc__db_temp_op_set_base_last_change,
>   svn_wc__db_temp_op_set_working_last_change): New function.
>
> * subversion/libsvn_wc/wc_db.h
>  (svn_wc__db_temp_op_set_base_last_change,
>   svn_wc__db_temp_op_set_working_last_change): New function.
>
> Modified:
>    subversion/trunk/subversion/libsvn_wc/entries.c
>    subversion/trunk/subversion/libsvn_wc/entries.h
>    subversion/trunk/subversion/libsvn_wc/log.c
>    subversion/trunk/subversion/libsvn_wc/old-and-busted.c
>    subversion/trunk/subversion/libsvn_wc/update_editor.c
>    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
>    subversion/trunk/subversion/libsvn_wc/wc_db.c
>    subversion/trunk/subversion/libsvn_wc/wc_db.h
>
> Modified: subversion/trunk/subversion/libsvn_wc/entries.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/entries.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/entries.c Wed Mar  3 16:15:27 2010
> @@ -2587,17 +2587,7 @@
>       ? apr_pstrdup(pool, entry->prejfile)
>                           : NULL;
>
> -  /* Last-commit stuff */
> -  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_REV)
> -    cur_entry->cmt_rev = entry->cmt_rev;
> -
> -  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_DATE)
> -    cur_entry->cmt_date = entry->cmt_date;
> -
> -  if (modify_flags & SVN_WC__ENTRY_MODIFY_CMT_AUTHOR)
> -    cur_entry->cmt_author = entry->cmt_author
> -      ? apr_pstrdup(pool, entry->cmt_author)
> -                            : NULL;
> +  /* Last-commit flags are no longer passed to entry_modify() */
>
>   /* LOCK flags are no longer passed to entry_modify().  */
>
>
> Modified: subversion/trunk/subversion/libsvn_wc/entries.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.h?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/entries.h (original)
> +++ subversion/trunk/subversion/libsvn_wc/entries.h Wed Mar  3 16:15:27 2010
> @@ -108,9 +108,6 @@
>  #define SVN_WC__ENTRY_MODIFY_CONFLICT_NEW       APR_INT64_C(0x0000000000002000)
>  #define SVN_WC__ENTRY_MODIFY_CONFLICT_WRK       APR_INT64_C(0x0000000000004000)
>  #define SVN_WC__ENTRY_MODIFY_PREJFILE           APR_INT64_C(0x0000000000008000)
> -#define SVN_WC__ENTRY_MODIFY_CMT_REV            APR_INT64_C(0x0000000000010000)
> -#define SVN_WC__ENTRY_MODIFY_CMT_DATE           APR_INT64_C(0x0000000000020000)
> -#define SVN_WC__ENTRY_MODIFY_CMT_AUTHOR         APR_INT64_C(0x0000000000040000)
>  /* OPEN */
>  #define SVN_WC__ENTRY_MODIFY_INCOMPLETE         APR_INT64_C(0x0000000000100000)
>  #define SVN_WC__ENTRY_MODIFY_ABSENT             APR_INT64_C(0x0000000000200000)
>
> Modified: subversion/trunk/subversion/libsvn_wc/log.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/log.c?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/log.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/log.c Wed Mar  3 16:15:27 2010
> @@ -475,40 +475,6 @@
>   if (valuestr && strcmp(valuestr, "true") == 0)
>     modify_flags |= SVN_WC__ENTRY_MODIFY_FORCE;
>
> -  /* It is possible that we will find a log that has a misordered sequence
> -     of entry modifications and wcprop modifications. The entry must be
> -     "not hidden" before wcprops can be installed. The sequence of actions
> -     will look like:
> -
> -       1. modify_entry
> -       2. modify_wcprops
> -       3. modify_entry(DELETED=FALSE)
> -
> -     Step 2 will fail if the current node is marked DELETED. r36697 fixes
> -     the ordering, moving step 3 to the beginning of the sequence. However,
> -     old logs may still contain the above sequence. To compensate, we will
> -     attempt to detect the pattern used by step 1, and preemptively clear
> -     the DELETED flag.
> -
> -     The misordered entry is written by accumulate_entry_props() in
> -     update_editor.c. That may modify the CMT_* values and/or the UUID.
> -     If we see any of those, then we've detected a modify_entry constructed
> -     by that function. And that means we *just* ran a step 3 (new code)
> -     or we *will* run a step 3 (too late; old code). In both situations,
> -     we can safely clear the DELETED flag.
> -
> -     The UUID modification is *only* performed by that function. The CMT_*
> -     changes are also performed by process_committed_leaf() in adm_ops.c.
> -     A just-committed node setting these values will NEVER be DELETED,
> -     so it is safe to clear the value.  */
> -  if (modify_flags & (SVN_WC__ENTRY_MODIFY_CMT_REV
> -                      | SVN_WC__ENTRY_MODIFY_CMT_DATE
> -                      | SVN_WC__ENTRY_MODIFY_CMT_AUTHOR))
> -    {
> -      entry->deleted = FALSE;
> -      modify_flags |= SVN_WC__ENTRY_MODIFY_DELETED;
> -    }
> -
>   /* Now write the new entry out. Note that we want to always operate
>      on the stub if name is not THIS_DIR. This loggy function is intended
>      to operate on the data in ADM_ABSPATH, so we do NOT want to reach
> @@ -1086,17 +1052,7 @@
>                  SVN_WC__ENTRY_ATTR_CHECKSUM,
>                  entry->checksum);
>
> -  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_REV,
> -                 SVN_WC__ENTRY_ATTR_CMT_REV,
> -                 apr_psprintf(scratch_pool, "%ld", entry->cmt_rev));
> -
> -  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_DATE,
> -                 SVN_WC__ENTRY_ATTR_CMT_DATE,
> -                 svn_time_to_cstring(entry->cmt_date, scratch_pool));
> -
> -  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CMT_AUTHOR,
> -                 SVN_WC__ENTRY_ATTR_CMT_AUTHOR,
> -                 entry->cmt_author);
> +  /* Note: Last-commit flags are no longer passed to this function. */
>
>   /* Note: LOCK flags are no longer passed to this function.  */
>
>
> Modified: subversion/trunk/subversion/libsvn_wc/old-and-busted.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/old-and-busted.c?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/old-and-busted.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/old-and-busted.c Wed Mar  3 16:15:27 2010
> @@ -946,7 +946,6 @@
>     if (cmt_datestr)
>       {
>         SVN_ERR(svn_time_from_cstring(&entry->cmt_date, cmt_datestr, pool));
> -        *modify_flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;
>       }
>     else
>       entry->cmt_date = 0;
> @@ -956,15 +955,13 @@
>     if (cmt_revstr)
>       {
>         entry->cmt_rev = SVN_STR_TO_REV(cmt_revstr);
> -        *modify_flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;
>       }
>     else
>       entry->cmt_rev = SVN_INVALID_REVNUM;
>
>     entry->cmt_author = extract_string(modify_flags, atts,
>                                        SVN_WC__ENTRY_ATTR_CMT_AUTHOR,
> -                                       SVN_WC__ENTRY_MODIFY_CMT_AUTHOR,
> -                                       FALSE, pool);
> +                                       0, FALSE, pool);
>   }
>
>   /* NOTE: we do not set modify_flags values since the lock attributes only
>
> Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/update_editor.c Wed Mar  3 16:15:27 2010
> @@ -1188,25 +1188,35 @@
>  }
>
>
> -/* Accumulate tags in LOG_ACCUM (associated with ADM_ABSPATH) to set
> -   ENTRY_PROPS for PATH.
> +/* Container for the common "Entry props" */
> +struct last_change_info
> +{
> +  /** last revision this was changed */
> +  svn_revnum_t cmt_rev;
> +
> +  /** last date this was changed */
> +  apr_time_t cmt_date;
> +
> +  /** last commit author of this item */
> +  const char *cmt_author;
> +};
> +
> +/* Accumulate last change info in LAST_CHANGE to set on LOCAL_ABSPATH.
>    ENTRY_PROPS is an array of svn_prop_t* entry props.
> -   If ENTRY_PROPS contains the removal of a lock token, all entryprops
> -   related to a lock will be removed and LOCK_STATE, if non-NULL, will be
> -   set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL
> +   If ENTRY_PROPS contains the removal of a lock token, the lock info is
> +   directly removed from LOCAL_ABSPATH in DB and LOCK_STATE, if non-NULL, will
> +   be set to svn_wc_notify_lock_state_unlocked.  Else, LOCK_STATE, if non-NULL
>    will be set to svn_wc_lock_state_unchanged. */
>  static svn_error_t *
> -accumulate_entry_props(svn_stringbuf_t *log_accum,
> -                       svn_wc__db_t *db,
> -                       const char *adm_abspath,
> +accumulate_last_change(struct last_change_info **last_change,
>                        svn_wc_notify_lock_state_t *lock_state,
> -                       const char *path,
> +                       svn_wc__db_t *db,
> +                       const char *local_abspath,
>                        apr_array_header_t *entry_props,
> -                       apr_pool_t *pool)
> +                       apr_pool_t *scratch_pool,
> +                       apr_pool_t *result_pool)
>  {
>   int i;
> -  svn_wc_entry_t tmp_entry;
> -  apr_uint64_t flags = 0;
>
>   if (lock_state)
>     *lock_state = svn_wc_notify_lock_state_unchanged;
> @@ -1217,11 +1227,10 @@
>       const char *val;
>
>       /* The removal of the lock-token entryprop means that the lock was
> -         defunct. */
> +         defunct, so remove it directly. */
>       if (! strcmp(prop->name, SVN_PROP_ENTRY_LOCK_TOKEN))
>         {
> -          SVN_WC__FLUSH_LOG_ACCUM(db, adm_abspath, log_accum, pool);
> -          SVN_ERR(svn_wc__loggy_delete_lock(db, adm_abspath, path, pool));
> +          SVN_ERR(svn_wc__db_lock_remove(db, local_abspath, scratch_pool));
>
>           if (lock_state)
>             *lock_state = svn_wc_notify_lock_state_unlocked;
> @@ -1236,29 +1245,23 @@
>
>       val = prop->value->data;
>
> -      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
> +      if (*last_change == NULL)
>         {
> -          flags |= SVN_WC__ENTRY_MODIFY_CMT_AUTHOR;
> -          tmp_entry.cmt_author = val;
> +          *last_change = apr_pcalloc(result_pool, sizeof(**last_change));
> +          (*last_change)->cmt_rev = SVN_INVALID_REVNUM;
>         }
> +
> +      if (! strcmp(prop->name, SVN_PROP_ENTRY_LAST_AUTHOR))
> +        (*last_change)->cmt_author = apr_pstrdup(result_pool, val);
>       else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_REV))
> -        {
> -          flags |= SVN_WC__ENTRY_MODIFY_CMT_REV;
> -          tmp_entry.cmt_rev = SVN_STR_TO_REV(val);
> -        }
> +        (*last_change)->cmt_rev = SVN_STR_TO_REV(val);
>       else if (! strcmp(prop->name, SVN_PROP_ENTRY_COMMITTED_DATE))
> -        {
> -          flags |= SVN_WC__ENTRY_MODIFY_CMT_DATE;
> -          SVN_ERR(svn_time_from_cstring(&tmp_entry.cmt_date, val, pool));
> -        }
> +        SVN_ERR(svn_time_from_cstring(&((*last_change)->cmt_date), val,
> +                                      scratch_pool));
>       /* Starting with Subversion 1.7 we ignore the SVN_PROP_ENTRY_UUID
>          property here. */
>     }
>
> -  if (flags)
> -    SVN_ERR(svn_wc__loggy_entry_modify(&log_accum, adm_abspath,
> -                                       path, &tmp_entry, flags, pool, pool));
> -
>   return SVN_NO_ERROR;
>  }
>
> @@ -3173,6 +3176,7 @@
>  {
>   struct dir_baton *db = dir_baton;
>   struct edit_baton *eb = db->edit_baton;
> +  struct last_change_info *last_change = NULL;
>   svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
>   apr_array_header_t *entry_props, *wc_props, *regular_props;
>   apr_hash_t *base_props = NULL, *working_props = NULL;
> @@ -3303,10 +3307,9 @@
>                     _("Couldn't do property merge"));
>         }
>
> -      SVN_ERR(accumulate_entry_props(dirprop_log, eb->db,
> -                                     db->local_abspath,
> -                                     NULL, db->local_abspath, entry_props,
> -                                     pool));
> +      SVN_ERR(accumulate_last_change(&last_change, NULL, eb->db,
> +                                     db->local_abspath, entry_props,
> +                                     pool, pool));
>
>       /* Handle the wcprops. */
>       if (wc_props && wc_props->nelts > 0)
> @@ -3329,6 +3332,14 @@
>
>   /* Flush and run 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,
> +                                                    last_change->cmt_date,
> +                                                    last_change->cmt_author,
> +                                                    pool));
> +
>   SVN_ERR(svn_wc__run_log2(eb->db, db->local_abspath, pool));
>
>   /* We're done with this directory, so remove one reference from the
> @@ -4493,6 +4504,7 @@
>             svn_wc_notify_lock_state_t *lock_state,
>             apr_hash_t **new_base_props,
>             apr_hash_t **new_actual_props,
> +            struct last_change_info **last_change,
>             svn_wc__db_t *db,
>             const char *file_abspath,
>             const char *dir_abspath,
> @@ -4547,9 +4559,9 @@
>      Note that no merging needs to happen; these kinds of props aren't
>      versioned, so if the property is present, we overwrite the value. */
>   if (entry_props)
> -    SVN_ERR(accumulate_entry_props(log_accum, db, dir_abspath,
> -                                   lock_state, file_abspath, entry_props,
> -                                   pool));
> +    SVN_ERR(accumulate_last_change(last_change, lock_state,
> +                                   db, file_abspath, entry_props,
> +                                   pool, pool));
>   else
>     *lock_state = svn_wc_notify_lock_state_unchanged;
>
> @@ -4653,6 +4665,7 @@
>            svn_wc_notify_lock_state_t *lock_state,
>            apr_hash_t **new_base_props,
>            apr_hash_t **new_actual_props,
> +           struct last_change_info **last_change,
>            struct file_baton *fb,
>            const char *new_text_base_path,
>            const svn_checksum_t *actual_checksum,
> @@ -4722,7 +4735,7 @@
>      any file content merging, since that process might expand keywords, in
>      which case we want the new entryprops to be in place. */
>   SVN_ERR(merge_props(log_accum, prop_state, lock_state,
> -                      new_base_props, new_actual_props,
> +                      new_base_props, new_actual_props, last_change,
>                       eb->db, fb->local_abspath, pb->local_abspath,
>                       left_version, right_version,
>                       fb->propchanges,
> @@ -5065,6 +5078,7 @@
>  {
>   struct file_baton *fb = file_baton;
>   struct edit_baton *eb = fb->edit_baton;
> +  struct last_change_info *last_change = NULL;
>   svn_wc_notify_state_t content_state, prop_state;
>   svn_wc_notify_lock_state_t lock_state;
>   svn_checksum_t *expected_checksum = NULL;
> @@ -5132,8 +5146,8 @@
>
>   /* It's a small world, after all. */
>   SVN_ERR(merge_file(&content_state, &prop_state, &lock_state,
> -                     &new_base_props, &new_actual_props, fb,
> -                     new_base_path, md5_actual_checksum, pool));
> +                     &new_base_props, &new_actual_props, &last_change,
> +                     fb, new_base_path, md5_actual_checksum, pool));
>
>
>   if (fb->added || fb->add_existed)
> @@ -5144,11 +5158,15 @@
>                    be removed soon anyway.
>
>          ### HACK: The loggy stuff checked the preconditions for us,
> -                   we just make the property code happy here. */
> +                   we just make the property code happy here.
> +
> +         We can also clear entry.deleted here, as we are adding a new
> +         BASE_NODE anyway */
>       svn_wc_entry_t tmp_entry;
>       svn_stringbuf_t *create_log = NULL;
>       apr_uint64_t flags = SVN_WC__ENTRY_MODIFY_KIND
> -                           | SVN_WC__ENTRY_MODIFY_REVISION;
> +                           | SVN_WC__ENTRY_MODIFY_REVISION
> +                           | SVN_WC__ENTRY_MODIFY_DELETED;
>
>       if (fb->add_existed)
>         {
> @@ -5163,6 +5181,7 @@
>
>       tmp_entry.kind = svn_node_file;
>       tmp_entry.revision = *eb->target_revision;
> +      tmp_entry.deleted = FALSE;
>
>       SVN_ERR(svn_wc__loggy_entry_modify(&create_log,
>                                          fb->dir_baton->local_abspath,
> @@ -5175,8 +5194,23 @@
>                                    fb->dir_baton->local_abspath,
>                                    create_log,
>                                    pool));
> +
> +      SVN_ERR(svn_wc__wq_run(eb->db,
> +                             fb->dir_baton->local_abspath,
> +                             NULL, NULL, pool));
>     }
>
> +  /* ### Hack: The following block should be an atomic operation (including the install
> +               loggy install portions of some functions called above */
> +  SVN_ERR_ASSERT(last_change != NULL); /* Should always be not NULL for files */
> +
> +  if (last_change)
> +    SVN_ERR(svn_wc__db_temp_op_set_base_last_change(eb->db, fb->local_abspath,
> +                                                    last_change->cmt_rev,
> +                                                    last_change->cmt_date,
> +                                                    last_change->cmt_author,
> +                                                    pool));
> +
>   if (new_base_props || new_actual_props)
>       SVN_ERR(svn_wc__install_props(eb->db, fb->local_abspath,
>                                     new_base_props, new_actual_props,
> @@ -5866,7 +5900,7 @@
>    be an access baton for DST_PATH.
>    Use @a POOL for temporary allocations. */
>  static svn_error_t *
> -install_added_props(svn_stringbuf_t *log_accum,
> +install_added_props(struct last_change_info **last_change,
>                     svn_wc__db_t *db,
>                     const char *dir_abspath,
>                     const char *local_abspath,
> @@ -5894,8 +5928,8 @@
>   }
>
>   /* Install the entry props. */
> -  SVN_ERR(accumulate_entry_props(log_accum, db, dir_abspath,
> -                                 NULL, local_abspath, entry_props, pool));
> +  SVN_ERR(accumulate_last_change(last_change, NULL, db, local_abspath,
> +                                 entry_props, pool, pool));
>
>   return svn_error_return(svn_wc__db_base_set_dav_cache(db, local_abspath,
>                                         prop_hash_from_array(wc_props, pool),
> @@ -5928,6 +5962,7 @@
>   const char *temp_dir_abspath;
>   svn_stringbuf_t *pre_props_accum;
>   svn_stringbuf_t *post_props_accum;
> +  struct last_change_info *last_change = NULL;
>
>   SVN_ERR(svn_wc__text_base_path(&text_base_path, wc_ctx->db, local_abspath,
>                                  FALSE, pool));
> @@ -6020,7 +6055,7 @@
>
>   /* Install the props before the loggy translation, so that it has access to
>      the properties for this file. */
> -  SVN_ERR(install_added_props(post_props_accum, wc_ctx->db, dir_abspath,
> +  SVN_ERR(install_added_props(&last_change, wc_ctx->db, dir_abspath,
>                               local_abspath, &new_base_props, new_props, pool));
>
>   /* Copy the text base contents into a temporary file so our log
> @@ -6096,6 +6131,17 @@
>   SVN_ERR(svn_wc__install_props(wc_ctx->db, local_abspath, new_base_props,
>                                 new_props ? new_props : new_base_props,
>                                 TRUE, FALSE, pool));
> +
> +  SVN_ERR(svn_wc__run_log2(wc_ctx->db, dir_abspath, pool));
> +
> +  /* ### HACK: The following code should be performed in the same transaction as the install */
> +  if (last_change)
> +    SVN_ERR(svn_wc__db_temp_op_set_working_last_change(wc_ctx->db, local_abspath,
> +                                                       last_change->cmt_rev,
> +                                                       last_change->cmt_date,
> +                                                       last_change->cmt_author,
> +                                                       pool));
> +  /* ### /HACK */
>   SVN_ERR(svn_wc__wq_add_loggy(wc_ctx->db, dir_abspath, post_props_accum, pool));
>
>
>
> Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
> +++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Wed Mar  3 16:15:27 2010
> @@ -372,6 +372,14 @@
>  update base_node set file_external = ?3
>  where wc_id = ?1 and local_relpath = ?2;
>
> +-- STMT_UPDATE_BASE_LAST_CHANGE
> +update base_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
> +where wc_id = ?1 and local_relpath = ?2;
> +
> +-- STMT_UPDATE_WORKING_LAST_CHANGE
> +update working_node set changed_rev = ?3, changed_date = ?4, changed_author = ?5
> +where wc_id = ?1 and local_relpath = ?2;
> +
>  /* ------------------------------------------------------------------------- */
>
>  /* these are used in upgrade.c  */
>
> Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
> +++ subversion/trunk/subversion/libsvn_wc/wc_db.c Wed Mar  3 16:15:27 2010
> @@ -6232,4 +6232,93 @@
>    }
>
>   return SVN_NO_ERROR;
> -}
> \ No newline at end of file
> +}
> +
> +svn_error_t *
> +svn_wc__db_temp_op_set_base_last_change(svn_wc__db_t *db,
> +                                        const char *local_abspath,
> +                                        svn_revnum_t changed_rev,
> +                                        apr_time_t changed_date,
> +                                        const char *changed_author,
> +                                        apr_pool_t *scratch_pool)
> +{
> +  svn_wc__db_pdh_t *pdh;
> +  svn_sqlite__stmt_t *stmt;
> +  const char *local_relpath;
> +  int affected;
> +
> +  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_CHANGE));
> +
> +  SVN_ERR(svn_sqlite__bindf(stmt, "isiis",
> +                            pdh->wcroot->wc_id, local_relpath,
> +                            (apr_int64_t)changed_rev,
> +                            (apr_int64_t)changed_date,
> +                            changed_author));
> +
> +  SVN_ERR(svn_sqlite__update(&affected, stmt));
> +
> +  /* ### Theoretically this check can fail if all the values match
> +         the values in the database. But we only call this function
> +         if the revision changes */
> +  if (affected != 1)
> +    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
> +                             _("'%s' has no BASE_NODE"),
> +                             svn_dirent_local_style(local_abspath,
> +                                                    scratch_pool));
> +
> +  flush_entries(pdh);
> +
> +  return SVN_NO_ERROR;
> +}
> +
> +svn_error_t *
> +svn_wc__db_temp_op_set_working_last_change(svn_wc__db_t *db,
> +                                           const char *local_abspath,
> +                                           svn_revnum_t changed_rev,
> +                                           apr_time_t changed_date,
> +                                           const char *changed_author,
> +                                           apr_pool_t *scratch_pool)
> +{
> +  svn_wc__db_pdh_t *pdh;
> +  svn_sqlite__stmt_t *stmt;
> +  const char *local_relpath;
> +  int affected;
> +
> +  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_WORKING_LAST_CHANGE));
> +
> +  SVN_ERR(svn_sqlite__bindf(stmt, "isiis",
> +                            pdh->wcroot->wc_id, local_relpath,
> +                            (apr_int64_t)changed_rev,
> +                            (apr_int64_t)changed_date,
> +                            changed_author));
> +
> +  SVN_ERR(svn_sqlite__update(&affected, stmt));
> +
> +  /* The following check might fail if none of the values changes.
> +     But currently this function is never called in such cases */
> +  if (affected != 1)
> +    return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
> +                             _("'%s' has no WORKING_NODE"),
> +                             svn_dirent_local_style(local_abspath,
> +                                                    scratch_pool));
> +
> +  flush_entries(pdh);
> +
> +  return SVN_NO_ERROR;
> +}
>
> Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=918542&r1=918541&r2=918542&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
> +++ subversion/trunk/subversion/libsvn_wc/wc_db.h Wed Mar  3 16:15:27 2010
> @@ -2034,6 +2034,24 @@
>                                           apr_pool_t *scratch_pool);
>
>
> +/* Update changed information in BASE_NODE with the supplied values */
> +svn_error_t *
> +svn_wc__db_temp_op_set_base_last_change(svn_wc__db_t *db,
> +                                        const char *local_abspath,
> +                                        svn_revnum_t changed_rev,
> +                                        apr_time_t changed_date,
> +                                        const char *changed_author,
> +                                        apr_pool_t *scratch_pool);
> +
> +/* Update changed information in WORKING_NODE with the supplied values */
> +svn_error_t *
> +svn_wc__db_temp_op_set_working_last_change(svn_wc__db_t *db,
> +                                           const char *local_abspath,
> +                                           svn_revnum_t changed_rev,
> +                                           apr_time_t changed_date,
> +                                           const char *changed_author,
> +                                           apr_pool_t *scratch_pool);
> +
>  /** @} */
>
>
>
>
>