subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1476675 [11/17] - in /subversion/branches/fsfs-format7: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/hook-scripts/ contrib/server-side/svncutter/ subversion/bindings/cxxhl/include/ subversion/bindings/cxxh...
Date Sat, 27 Apr 2013 21:30:43 GMT
Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/status.c Sat Apr 27 21:30:36 2013
@@ -533,11 +533,11 @@ assemble_status(svn_wc_status3_t **statu
             copied = TRUE; /* Working deletion */
         }
     }
-  else 
+  else
     {
       /* Examine whether our target is missing or obstructed. To detect
        * obstructions, we have to look at the on-disk status in DIRENT. */
-      svn_node_kind_t expected_kind = (info->kind == svn_node_dir) 
+      svn_node_kind_t expected_kind = (info->kind == svn_node_dir)
                                         ? svn_node_dir
                                         : svn_node_file;
 
@@ -693,7 +693,7 @@ assemble_status(svn_wc_status3_t **statu
               if (err)
                 {
                   if (err->apr_err != SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
-                    svn_error_trace(err);
+                    return svn_error_trace(err);
 
                   svn_error_clear(err);
                   /* We are no longer moved... So most likely we are somehow
@@ -2665,7 +2665,7 @@ stat_wc_dirent_case_sensitive(const svn_
 
   /* Note that for performance this is really just a few hashtable lookups,
      as we just used local_abspath for a db call in both our callers */
-  SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath, 
+  SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
                                scratch_pool));
 
   return svn_error_trace(
@@ -2894,8 +2894,8 @@ internal_status(svn_wc_status3_t **statu
          on 'hidden' nodes. */
       conflicted = FALSE;
 
-      SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
-                                 scratch_pool, scratch_pool));
+      SVN_ERR(svn_io_stat_dirent2(&dirent, local_abspath, FALSE, TRUE,
+                                  scratch_pool, scratch_pool));
     }
   else
     SVN_ERR(stat_wc_dirent_case_sensitive(&dirent, db, local_abspath,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/translate.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/translate.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/translate.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/translate.c Sat Apr 27 21:30:36 2013
@@ -314,10 +314,10 @@ svn_wc__expand_keywords(apr_hash_t **key
   apr_time_t changed_date;
   const char *changed_author;
   const char *url;
+  const char *repos_root_url;
 
   if (! for_normalization)
     {
-      const char *repos_root_url;
       const char *repos_relpath;
 
       SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, &repos_relpath,
@@ -342,15 +342,14 @@ svn_wc__expand_keywords(apr_hash_t **key
       changed_rev = SVN_INVALID_REVNUM;
       changed_date = 0;
       changed_author = "";
+      repos_root_url = "";
     }
 
-  SVN_ERR(svn_subst_build_keywords2(keywords,
-                                    keyword_list,
+  SVN_ERR(svn_subst_build_keywords3(keywords, keyword_list,
                                     apr_psprintf(scratch_pool, "%ld",
                                                  changed_rev),
-                                    url,
-                                    changed_date,
-                                    changed_author,
+                                    url, repos_root_url,
+                                    changed_date, changed_author,
                                     result_pool));
 
   if (apr_hash_count(*keywords) == 0)

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/update_editor.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/update_editor.c Sat Apr 27 21:30:36 2013
@@ -618,6 +618,7 @@ make_dir_baton(struct dir_baton **d_p,
 /* Forward declarations. */
 static svn_error_t *
 already_in_a_tree_conflict(svn_boolean_t *conflicted,
+                           svn_boolean_t *ignored,
                            svn_wc__db_t *db,
                            const char *local_abspath,
                            apr_pool_t *scratch_pool);
@@ -1168,7 +1169,7 @@ open_root(void *edit_baton,
 {
   struct edit_baton *eb = edit_baton;
   struct dir_baton *db;
-  svn_boolean_t already_conflicted;
+  svn_boolean_t already_conflicted, conflict_ignored;
   svn_error_t *err;
   svn_wc__db_status_t status;
   svn_wc__db_status_t base_status;
@@ -1182,8 +1183,8 @@ open_root(void *edit_baton,
   SVN_ERR(make_dir_baton(&db, NULL, eb, NULL, FALSE, pool));
   *dir_baton = db;
 
-  err = already_in_a_tree_conflict(&already_conflicted, eb->db,
-                                   db->local_abspath, pool);
+  err = already_in_a_tree_conflict(&already_conflicted, &conflict_ignored,
+                                   eb->db, db->local_abspath, pool);
 
   if (err)
     {
@@ -1191,7 +1192,7 @@ open_root(void *edit_baton,
         return svn_error_trace(err);
 
       svn_error_clear(err);
-      already_conflicted = FALSE;
+      already_conflicted = conflict_ignored = FALSE;
     }
   else if (already_conflicted)
     {
@@ -1222,7 +1223,11 @@ open_root(void *edit_baton,
                                eb->db, db->local_abspath,
                                db->pool, pool));
 
-  if (have_work)
+  if (conflict_ignored)
+    {
+      db->shadowed = TRUE;
+    }
+  else if (have_work)
     {
       const char *move_src_root_abspath;
 
@@ -1514,7 +1519,7 @@ check_tree_conflict(svn_skel_t **pconfli
           {
             /* An edit onto a local edit or onto *no* local changes is no
              * tree-conflict. (It's possibly a text- or prop-conflict,
-             * but we don't handle those here.) 
+             * but we don't handle those here.)
              *
              * Except when there is a local obstruction
              */
@@ -1590,17 +1595,30 @@ check_tree_conflict(svn_skel_t **pconfli
       || reason == svn_wc_conflict_reason_deleted
       || reason == svn_wc_conflict_reason_moved_away
       || reason == svn_wc_conflict_reason_replaced)
-    /* When the node existed before (it was locally deleted, replaced or
-     * edited), then 'update' cannot add it "again". So it can only send
-     * _action_edit, _delete or _replace. */
-    SVN_ERR_ASSERT(action == svn_wc_conflict_action_edit
-                   || action == svn_wc_conflict_action_delete
-                   || action == svn_wc_conflict_action_replace);
+    {
+      /* When the node existed before (it was locally deleted, replaced or
+       * edited), then 'update' cannot add it "again". So it can only send
+       * _action_edit, _delete or _replace. */
+    if (action != svn_wc_conflict_action_edit
+        && action != svn_wc_conflict_action_delete
+        && action != svn_wc_conflict_action_replace)
+      return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
+               _("Unexpected attempt to add a node at path '%s'"),
+               svn_dirent_local_style(local_abspath, scratch_pool));
+    }
   else if (reason == svn_wc_conflict_reason_added ||
            reason == svn_wc_conflict_reason_moved_here)
-    /* When the node did not exist before (it was locally added), then 'update'
-     * cannot want to modify it in any way. It can only send _action_add. */
-    SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
+    {
+      /* When the node did not exist before (it was locally added),
+       * then 'update' cannot want to modify it in any way.
+       * It can only send _action_add. */
+      if (action != svn_wc_conflict_action_add)
+        return svn_error_createf(SVN_ERR_WC_FOUND_CONFLICT, NULL,
+                 _("Unexpected attempt to edit, delete, or replace "
+                   "a node at path '%s'"),
+                 svn_dirent_local_style(local_abspath, scratch_pool));
+
+    }
 
 
   /* A conflict was detected. Create a conflict skel to record it. */
@@ -1623,6 +1641,7 @@ check_tree_conflict(svn_skel_t **pconfli
  */
 static svn_error_t *
 already_in_a_tree_conflict(svn_boolean_t *conflicted,
+                           svn_boolean_t *ignored,
                            svn_wc__db_t *db,
                            const char *local_abspath,
                            apr_pool_t *scratch_pool)
@@ -1632,7 +1651,7 @@ already_in_a_tree_conflict(svn_boolean_t
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  *conflicted = FALSE;
+  *conflicted = *ignored = FALSE;
 
   while (TRUE)
     {
@@ -1640,9 +1659,10 @@ already_in_a_tree_conflict(svn_boolean_t
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, db, ancestor_abspath,
-                                              TRUE, scratch_pool));
-      if (*conflicted)
+      SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, ignored, db,
+                                              ancestor_abspath, TRUE,
+                                              scratch_pool));
+      if (*conflicted || *ignored)
         break;
 
       SVN_ERR(svn_wc__db_is_wcroot(&is_wc_root, db, ancestor_abspath,
@@ -1661,11 +1681,13 @@ already_in_a_tree_conflict(svn_boolean_t
 /* Temporary helper until the new conflict handling is in place */
 static svn_error_t *
 node_already_conflicted(svn_boolean_t *conflicted,
+                        svn_boolean_t *conflict_ignored,
                         svn_wc__db_t *db,
                         const char *local_abspath,
                         apr_pool_t *scratch_pool)
 {
-  SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, db, local_abspath, FALSE,
+  SVN_ERR(svn_wc__conflicted_for_update_p(conflicted, conflict_ignored, db,
+                                          local_abspath, FALSE,
                                           scratch_pool));
 
   return SVN_NO_ERROR;
@@ -1766,8 +1788,8 @@ delete_entry(const char *path,
   if (pb->shadowed)
     conflicted = FALSE; /* Conflict applies to WORKING */
   else if (conflicted)
-    SVN_ERR(node_already_conflicted(&conflicted, eb->db, local_abspath,
-                                    scratch_pool));
+    SVN_ERR(node_already_conflicted(&conflicted, NULL,
+                                    eb->db, local_abspath, scratch_pool));
   if (conflicted)
     {
       SVN_ERR(remember_skipped_tree(eb, local_abspath, scratch_pool));
@@ -1782,7 +1804,6 @@ delete_entry(const char *path,
     }
 
 
-
   /* Receive the remote removal of excluded/server-excluded/not present node.
      Do not notify, but perform the change even when the node is shadowed */
   if (base_status == svn_wc__db_status_not_present
@@ -1957,6 +1978,7 @@ add_directory(const char *path,
   svn_wc__db_status_t status;
   svn_node_kind_t wc_kind;
   svn_boolean_t conflicted;
+  svn_boolean_t conflict_ignored = FALSE;
   svn_boolean_t versioned_locally_and_present;
   svn_skel_t *tree_conflict = NULL;
   svn_error_t *err;
@@ -2115,8 +2137,8 @@ add_directory(const char *path,
           conflicted = FALSE; /* No skip */
         }
       else
-        SVN_ERR(node_already_conflicted(&conflicted, eb->db,
-                                        db->local_abspath, pool));
+        SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+                                        eb->db, db->local_abspath, pool));
     }
 
   /* Now the "usual" behaviour if already conflicted. Skip it. */
@@ -2153,6 +2175,10 @@ add_directory(const char *path,
                       svn_wc_notify_skip_conflicted, pool);
       return SVN_NO_ERROR;
     }
+  else if (conflict_ignored)
+    {
+      db->shadowed = TRUE;
+    }
 
   if (db->shadowed)
     {
@@ -2305,6 +2331,7 @@ open_directory(const char *path,
   struct edit_baton *eb = pb->edit_baton;
   svn_boolean_t have_work;
   svn_boolean_t conflicted;
+  svn_boolean_t conflict_ignored = FALSE;
   svn_skel_t *tree_conflict = NULL;
   svn_wc__db_status_t status, base_status;
   svn_node_kind_t wc_kind;
@@ -2367,8 +2394,8 @@ open_directory(const char *path,
   if (db->shadowed)
     conflicted = FALSE; /* Conflict applies to WORKING */
   else if (conflicted)
-    SVN_ERR(node_already_conflicted(&conflicted, eb->db,
-                                    db->local_abspath, pool));
+    SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+                                    eb->db, db->local_abspath, pool));
   if (conflicted)
     {
       SVN_ERR(remember_skipped_tree(eb, db->local_abspath, pool));
@@ -2381,6 +2408,10 @@ open_directory(const char *path,
 
       return SVN_NO_ERROR;
     }
+  else if (conflict_ignored)
+    {
+      db->shadowed = TRUE;
+    }
 
   /* Is this path a fresh tree conflict victim?  If so, skip the tree
      with one notification. */
@@ -3053,6 +3084,7 @@ add_file(const char *path,
   svn_wc__db_status_t status = svn_wc__db_status_normal;
   apr_pool_t *scratch_pool;
   svn_boolean_t conflicted = FALSE;
+  svn_boolean_t conflict_ignored = FALSE;
   svn_boolean_t versioned_locally_and_present = FALSE;
   svn_skel_t *tree_conflict = NULL;
   svn_error_t *err = SVN_NO_ERROR;
@@ -3199,8 +3231,8 @@ add_file(const char *path,
           conflicted = FALSE; /* No skip */
         }
       else
-        SVN_ERR(node_already_conflicted(&conflicted, eb->db,
-                                        fb->local_abspath, pool));
+        SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+                                        eb->db, fb->local_abspath, pool));
     }
 
   /* Now the usual conflict handling: skip. */
@@ -3232,6 +3264,10 @@ add_file(const char *path,
 
       return SVN_NO_ERROR;
     }
+  else if (conflict_ignored)
+    {
+      fb->shadowed = TRUE;
+    }
 
   if (fb->shadowed)
     {
@@ -3367,6 +3403,7 @@ open_file(const char *path,
   struct edit_baton *eb = pb->edit_baton;
   struct file_baton *fb;
   svn_boolean_t conflicted;
+  svn_boolean_t conflict_ignored = FALSE;
   svn_boolean_t have_work;
   svn_wc__db_status_t status;
   svn_node_kind_t wc_kind;
@@ -3431,8 +3468,8 @@ open_file(const char *path,
   if (fb->shadowed)
     conflicted = FALSE; /* Conflict applies to WORKING */
   else if (conflicted)
-    SVN_ERR(node_already_conflicted(&conflicted, eb->db,
-                                    fb->local_abspath, pool));
+    SVN_ERR(node_already_conflicted(&conflicted, &conflict_ignored,
+                                    eb->db, fb->local_abspath, pool));
   if (conflicted)
     {
       SVN_ERR(remember_skipped_tree(eb, fb->local_abspath, pool));
@@ -3447,6 +3484,10 @@ open_file(const char *path,
 
       return SVN_NO_ERROR;
     }
+  else if (conflict_ignored)
+    {
+      fb->shadowed = TRUE;
+    }
 
   /* Check for conflicts only when we haven't already recorded
    * a tree-conflict on a parent node. */
@@ -3484,6 +3525,48 @@ open_file(const char *path,
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_stream_lazyopen_func_t. */
+static svn_error_t *
+lazy_open_source(svn_stream_t **stream,
+                 void *baton,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct file_baton *fb = baton;
+
+  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, fb->edit_baton->db,
+                                   fb->local_abspath,
+                                   fb->original_checksum,
+                                   result_pool, scratch_pool));
+
+
+  return SVN_NO_ERROR;
+}
+
+struct lazy_target_baton {
+  struct file_baton *fb;
+  struct handler_baton *hb;
+  struct edit_baton *eb;
+};
+
+/* Implements svn_stream_lazyopen_func_t. */
+static svn_error_t *
+lazy_open_target(svn_stream_t **stream,
+                 void *baton,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  struct lazy_target_baton *tb = baton;
+
+  SVN_ERR(svn_wc__open_writable_base(stream, &tb->hb->new_text_base_tmp_abspath,
+                                     NULL, &tb->hb->new_text_base_sha1_checksum,
+                                     tb->fb->edit_baton->db,
+                                     tb->eb->wcroot_abspath,
+                                     result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* An svn_delta_editor_t function. */
 static svn_error_t *
 apply_textdelta(void *file_baton,
@@ -3496,10 +3579,10 @@ apply_textdelta(void *file_baton,
   apr_pool_t *handler_pool = svn_pool_create(fb->pool);
   struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
   struct edit_baton *eb = fb->edit_baton;
-  svn_error_t *err;
   const svn_checksum_t *recorded_base_checksum;
   svn_checksum_t *expected_base_checksum;
   svn_stream_t *source;
+  struct lazy_target_baton *tb;
   svn_stream_t *target;
 
   if (fb->skip_this)
@@ -3566,10 +3649,8 @@ apply_textdelta(void *file_baton,
       SVN_ERR_ASSERT(!fb->original_checksum
                      || fb->original_checksum->kind == svn_checksum_sha1);
 
-      SVN_ERR(svn_wc__db_pristine_read(&source, NULL, fb->edit_baton->db,
-                                       fb->local_abspath,
-                                       fb->original_checksum,
-                                       handler_pool, handler_pool));
+      source = svn_stream_lazyopen_create(lazy_open_source, fb, FALSE,
+                                          handler_pool);
     }
   else
     {
@@ -3595,16 +3676,11 @@ apply_textdelta(void *file_baton,
       hb->source_checksum_stream = source;
     }
 
-  /* Open the text base for writing (this will get us a temporary file).  */
-  err = svn_wc__open_writable_base(&target, &hb->new_text_base_tmp_abspath,
-                                   NULL, &hb->new_text_base_sha1_checksum,
-                                   fb->edit_baton->db, eb->wcroot_abspath,
-                                   handler_pool, pool);
-  if (err)
-    {
-      svn_pool_destroy(handler_pool);
-      return svn_error_trace(err);
-    }
+  tb = apr_palloc(handler_pool, sizeof(struct lazy_target_baton));
+  tb->hb = hb;
+  tb->fb = fb;
+  tb->eb = eb;
+  target = svn_stream_lazyopen_create(lazy_open_target, tb, TRUE, handler_pool);
 
   /* Prepare to apply the delta.  */
   svn_txdelta_apply(source, target,
@@ -4173,7 +4249,7 @@ close_file(void *file_baton,
           {
             /* If we lose the lock, but not because we are switching to
                another url, remove the state lock from the wc */
-            if (! eb->switch_relpath 
+            if (! eb->switch_relpath
                 || strcmp(fb->new_relpath, fb->old_repos_relpath) == 0)
               {
                 SVN_ERR_ASSERT(prop->value == NULL);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/upgrade.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/upgrade.c Sat Apr 27 21:30:36 2013
@@ -1377,7 +1377,7 @@ svn_wc__upgrade_conflict_skel_from_raw(s
 {
   svn_skel_t *conflict_data = NULL;
   const char *wcroot_abspath;
-  
+
   SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, db, wri_abspath,
                                 scratch_pool, scratch_pool));
 
@@ -1589,9 +1589,41 @@ bump_to_31(void *baton,
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_array_header_t *empty_iprops = apr_array_make(
     scratch_pool, 0, sizeof(svn_prop_inherited_item_t *));
+  svn_boolean_t iprops_column_exists = FALSE;
+  svn_error_t *err;
 
-  /* Add the inherited_props column to NODES. */
-  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_31));
+  /* Add the inherited_props column to NODES if it does not yet exist.
+   *
+   * When using a format >= 31 client to upgrade from old formats which
+   * did not yet have a NODES table, the inherited_props column has
+   * already been created as part of the NODES table. Attemping to add
+   * the inherited_props column will raise an error in this case, so check
+   * if the column exists first.
+   *
+   * Checking for the existence of a column before ALTER TABLE is not
+   * possible within SQLite. We need to run a separate query and evaluate
+   * its result in C first.
+   */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PRAGMA_TABLE_INFO_NODES));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  while (have_row)
+    {
+      const char *column_name = svn_sqlite__column_text(stmt, 1, NULL);
+
+      if (strcmp(column_name, "inherited_props") == 0)
+        {
+          iprops_column_exists = TRUE;
+          break;
+        }
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+  if (!iprops_column_exists)
+    SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_31_ALTER_TABLE));
+
+  /* Run additional statements to finalize the upgrade to format 31. */
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_UPGRADE_TO_31_FINALIZE));
 
   /* Set inherited_props to an empty array for the roots of all
      switched subtrees in the WC.  This allows subsequent updates
@@ -1600,23 +1632,42 @@ bump_to_31(void *baton,
                                     STMT_UPGRADE_31_SELECT_WCROOT_NODES));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt_mark_switch_roots, sdb,
-                                    STMT_UPDATE_IPROP));
+  err = svn_sqlite__get_statement(&stmt_mark_switch_roots, sdb,
+                                  STMT_UPDATE_IPROP);
+  if (err)
+    return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+
   while (have_row)
     {
       const char *switched_relpath = svn_sqlite__column_text(stmt, 1, NULL);
       apr_int64_t wc_id = svn_sqlite__column_int64(stmt, 0);
 
-      SVN_ERR(svn_sqlite__bindf(stmt_mark_switch_roots, "is", wc_id,
-                                switched_relpath));
-      SVN_ERR(svn_sqlite__bind_iprops(stmt_mark_switch_roots, 3,
-                                      empty_iprops, iterpool));
-      SVN_ERR(svn_sqlite__step_done(stmt_mark_switch_roots));
-      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      err = svn_sqlite__bindf(stmt_mark_switch_roots, "is", wc_id,
+                              switched_relpath);
+      if (!err)
+        err = svn_sqlite__bind_iprops(stmt_mark_switch_roots, 3,
+                                      empty_iprops, iterpool);
+      if (!err)
+        err = svn_sqlite__step_done(stmt_mark_switch_roots);
+      if (!err)
+        err = svn_sqlite__step(&have_row, stmt);
+
+      if (err)
+        return svn_error_compose_create(
+                err,
+                svn_error_compose_create(
+                  /* Reset in either order is OK. */
+                  svn_sqlite__reset(stmt),
+                  svn_sqlite__reset(stmt_mark_switch_roots)));
     }
 
+  err = svn_sqlite__reset(stmt_mark_switch_roots);
+  if (err)
+    return svn_error_compose_create(err, svn_sqlite__reset(stmt));
   SVN_ERR(svn_sqlite__reset(stmt));
+
   svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-metadata.sql?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-metadata.sql Sat Apr 27 21:30:36 2013
@@ -814,11 +814,20 @@ WHERE wc_id = ?1 and local_relpath = ?2
 /* Format 31 adds the inherited_props column to the NODES table. C code then
    initializes the update/switch roots to make sure future updates fetch the
    inherited properties */
--- STMT_UPGRADE_TO_31
+-- STMT_UPGRADE_TO_31_ALTER_TABLE
 ALTER TABLE NODES ADD COLUMN inherited_props BLOB;
+-- STMT_UPGRADE_TO_31_FINALIZE
 DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST;
 DROP INDEX IF EXISTS I_EXTERNALS_PARENT;
 
+DROP INDEX I_NODES_PARENT;
+CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath,
+                                             local_relpath, op_depth);
+
+DROP INDEX I_ACTUAL_PARENT;
+CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath,
+                                                    local_relpath);
+
 PRAGMA user_version = 31;
 
 -- STMT_UPGRADE_31_SELECT_WCROOT_NODES
@@ -831,17 +840,13 @@ PRAGMA user_version = 31;
 SELECT l.wc_id, l.local_relpath FROM nodes as l
 LEFT OUTER JOIN nodes as r
 ON l.wc_id = r.wc_id
-   AND l.repos_id = r.repos_id
    AND r.local_relpath = l.parent_relpath
-WHERE (l.local_relpath = '' AND l.repos_path != '')
-   OR (l.op_depth = 0
-       AND l.local_relpath != ''
-       AND l.repos_path != ltrim(r.repos_path
-                                 || '/'
-                                 || ltrim(substr(l.local_relpath,
-                                                 length(l.parent_relpath) + 1),
-                                          '/'),
-                                 '/'))
+   AND r.op_depth = 0
+WHERE l.op_depth = 0
+  AND l.repos_path != ''
+  AND ((l.repos_id IS NOT r.repos_id)
+       OR (l.repos_path IS NOT RELPATH_SKIP_JOIN(r.local_relpath, r.repos_path, l.local_relpath)))
+
 
 /* ------------------------------------------------------------------------- */
 /* Format 32 ....  */
@@ -857,8 +862,8 @@ CREATE UNIQUE INDEX I_NODES_PARENT ON NO
                                              local_relpath, op_depth);
 
 DROP INDEX I_ACTUAL_PARENT;
-CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL (wc_id, parent_relpath,
-                                               local_relpath);
+CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath,
+                                                    local_relpath);
 
 /* ------------------------------------------------------------------------- */
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-queries.sql?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc-queries.sql Sat Apr 27 21:30:36 2013
@@ -1219,6 +1219,9 @@ WHERE wc_id = ?1 AND parent_relpath = ?2
 UPDATE nodes SET properties = ?4
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
 
+-- STMT_PRAGMA_TABLE_INFO_NODES
+PRAGMA table_info("NODES")
+
 /* --------------------------------------------------------------------------
  * Complex queries for callback walks, caching results in a temporary table.
  *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc.h?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc.h Sat Apr 27 21:30:36 2013
@@ -504,10 +504,13 @@ svn_wc__internal_conflicted_p(svn_boolea
                               apr_pool_t *scratch_pool);
 
 /* Similar to svn_wc__internal_conflicted_p(), but ignores
- * moved-away-edit tree conflicts.  Also ignores text and property
- * conflicts if TREE_ONLY is TRUE */
+ * moved-away-edit tree conflicts.  If CONFLICT_IGNORED_P is not NULL
+ * then sets *CONFLICT_IGNORED_P TRUE if a tree-conflict is ignored
+ * and FALSE otherwise. Also ignores text and property conflicts if
+ * TREE_ONLY is TRUE */
 svn_error_t *
 svn_wc__conflicted_for_update_p(svn_boolean_t *conflicted_p,
+                                svn_boolean_t *conflict_ignored_p,
                                 svn_wc__db_t *db,
                                 const char *local_abspath,
                                 svn_boolean_t tree_only,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.c Sat Apr 27 21:30:36 2013
@@ -958,7 +958,7 @@ insert_working_node(const insert_working
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   if (have_row)
     moved_to_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
-  SVN_ERR(svn_sqlite__reset(stmt)); 
+  SVN_ERR(svn_sqlite__reset(stmt));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_INSERT_NODE));
   SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnntstrisn"
@@ -1520,7 +1520,7 @@ svn_wc__db_init(svn_wc__db_t *db,
 
   /* Create the SDB and insert the basic rows.  */
   SVN_ERR(create_db(&sdb, &repos_id, &wc_id, local_abspath, repos_root_url,
-                    repos_uuid, SDB_FILE, 
+                    repos_uuid, SDB_FILE,
                     repos_relpath, initial_rev, depth, sqlite_exclusive,
                     db->state_pool, scratch_pool));
 
@@ -2226,7 +2226,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
     {
       apr_pool_t *iterpool;
 
-      /* 
+      /*
        * When deleting a conflicted node, moves of any moved-outside children
        * of the node must be broken. Else, the destination will still be marked
        * moved-here after the move source disappears from the working copy.
@@ -2249,7 +2249,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
         {
           const char *child_relpath;
           svn_error_t *err;
-          
+
           svn_pool_clear(iterpool);
           child_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
           err = clear_moved_here(child_relpath, wcroot, iterpool);
@@ -3497,7 +3497,7 @@ svn_wc__db_committable_externals_below(a
 
   SVN_ERR(svn_sqlite__get_statement(
                 &stmt, wcroot->sdb,
-                immediates_only 
+                immediates_only
                     ? STMT_SELECT_COMMITTABLE_EXTERNALS_IMMEDIATELY_BELOW
                     : STMT_SELECT_COMMITTABLE_EXTERNALS_BELOW));
 
@@ -6939,7 +6939,7 @@ remove_node_txn(svn_boolean_t *left_chan
 
   /* Need info for not_present node? */
   if (SVN_IS_VALID_REVNUM(not_present_rev))
-    SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL, 
+    SVN_ERR(svn_wc__db_base_get_info_internal(NULL, NULL, NULL,
                                               &repos_relpath, &repos_id,
                                               NULL, NULL, NULL, NULL, NULL,
                                               NULL, NULL, NULL, NULL, NULL,
@@ -6996,8 +6996,8 @@ remove_node_txn(svn_boolean_t *left_chan
           if (err)
             break;
 
-          err = svn_io_stat_dirent(&dirent, child_abspath, TRUE,
-                                   iterpool, iterpool);
+          err = svn_io_stat_dirent2(&dirent, child_abspath, FALSE, TRUE,
+                                    iterpool, iterpool);
 
           if (err)
             break;
@@ -7007,7 +7007,7 @@ remove_node_txn(svn_boolean_t *left_chan
               || child_kind != svn_node_file)
             {
               /* Not interested in keeping changes */
-              modified_p = FALSE; 
+              modified_p = FALSE;
             }
           else if (child_kind == svn_node_file
                    && dirent->kind == svn_node_file
@@ -7534,7 +7534,7 @@ delete_node(void *baton,
         {
           const char *part = svn_relpath_skip_ancestor(local_relpath,
                                                        moved_from_relpath);
-            
+
           /* Existing move-root is moved to another location */
           moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
           if (!part)
@@ -9019,7 +9019,7 @@ svn_wc__db_read_node_install_info(const 
 
   if (have_row)
     {
-      if (!err && sha1_checksum)
+      if (sha1_checksum)
         err = svn_sqlite__column_checksum(sha1_checksum, stmt, 6, result_pool);
 
       if (!err && pristine_props)
@@ -10434,7 +10434,7 @@ determine_repos_info(apr_int64_t *repos_
    This code is only valid to fix-up a move from an old location, to a new
    location during a commit.
 
-   Assumptions: 
+   Assumptions:
      * local_relpath is not the working copy root (can't be moved)
      * repos_relpath is not the repository root (can't be moved)
    */
@@ -10537,7 +10537,7 @@ moved_descendant_commit(svn_wc__db_wcroo
    Makes all nodes below LOCAL_RELPATH represent the descendants of repository
    location repos_id:repos_relpath@revision.
 
-   Assumptions: 
+   Assumptions:
      * local_relpath is not the working copy root (can't be replaced)
      * repos_relpath is not the repository root (can't be replaced)
    */
@@ -11909,7 +11909,7 @@ svn_wc__db_scan_moved(const char **moved
                             : NULL,
                         wcroot, local_relpath, scratch_pool, scratch_pool));
 
-  if (status != svn_wc__db_status_moved_here)
+  if (status != svn_wc__db_status_moved_here || !moved_from_relpath)
     return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                              _("Path '%s' was not moved here"),
                              path_for_error_message(wcroot, local_relpath,
@@ -13424,7 +13424,7 @@ svn_wc__db_is_switched(svn_boolean_t *is
       /* Easy out */
       if (is_wcroot)
         *is_wcroot = TRUE;
-      
+
       if (kind)
         *kind = svn_node_dir;
       return SVN_NO_ERROR;
@@ -14638,8 +14638,8 @@ has_local_mods(svn_boolean_t *is_modifie
             {
               const svn_io_dirent2_t *dirent;
 
-              err = svn_io_stat_dirent(&dirent, node_abspath, TRUE,
-                                       iterpool, iterpool);
+              err = svn_io_stat_dirent2(&dirent, node_abspath, FALSE, TRUE,
+                                        iterpool, iterpool);
               if (err)
                 return svn_error_trace(svn_error_compose_create(
                                                     err,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db.h Sat Apr 27 21:30:36 2013
@@ -3354,7 +3354,7 @@ svn_wc__db_base_moved_to(const char **mo
                          const char *local_abspath,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
-                         
+
 /* Recover space from the database file for LOCAL_ABSPATH by running
  * the "vacuum" command. */
 svn_error_t *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_pristine.c Sat Apr 27 21:30:36 2013
@@ -823,6 +823,37 @@ svn_wc__db_pristine_remove(svn_wc__db_t 
 }
 
 
+/* Remove all unreferenced pristines in the WC DB in WCROOT.
+ *
+ * Look for pristine texts whose 'refcount' in the DB is zero, and remove
+ * them from the 'pristine' table and from disk.
+ *
+ * TODO: At least check that any zero refcount is really correct, before
+ *       using it.  See dev@ email thread "Pristine text missing - cleanup
+ *       doesn't work", <http://svn.haxx.se/dev/archive-2013-04/0426.shtml>.
+ *
+ * TODO: Ideas for possible extra clean-up operations:
+ *
+ *       * Check and correct all the refcounts.  Identify any rows missing
+ *         from the 'pristine' table.  (Create a temporary index for speed
+ *         if necessary?)
+ *
+ *       * Check the checksums.  (Very expensive to check them all, so find
+ *         a way to not check them all.)
+ *
+ *       * Check for pristine files missing from disk but referenced in the
+ *         'pristine' table.
+ *
+ *       * Repair any pristine files missing from disk and/or rows missing
+ *         from the 'pristine' table and/or bad checksums.  Generally
+ *         requires contacting the server, so requires support at a higher
+ *         level than this function.
+ *
+ *       * Identify any pristine text files on disk that are not referenced
+ *         in the DB, and delete them.
+ *
+ * TODO: Provide feedback about any errors found and any corrections made.
+ */
 static svn_error_t *
 pristine_cleanup_wcroot(svn_wc__db_wcroot_t *wcroot,
                         apr_pool_t *scratch_pool)

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_private.h Sat Apr 27 21:30:36 2013
@@ -265,7 +265,7 @@ svn_wc__db_base_get_info_internal(svn_wc
                                   apr_pool_t *result_pool,
                                   apr_pool_t *scratch_pool);
 
-/* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH 
+/* Similar to svn_wc__db_base_get_info(), but taking WCROOT+LOCAL_RELPATH
  * instead of DB+LOCAL_ABSPATH, an explicit op-depth of the node to get
  * information about, and outputting REPOS_ID instead of URL+UUID, and
  * without the LOCK or UPDATE_ROOT outputs.

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_update_move.c Sat Apr 27 21:30:36 2013
@@ -128,7 +128,7 @@ struct tc_editor_baton {
   apr_pool_t *result_pool;  /* For things that live as long as the baton. */
 };
 
-/* 
+/*
  * Notifications are delayed until the entire update-move transaction
  * completes. These functions provide the necessary support by storing
  * notification information in a temporary db table (the "update_move_list")
@@ -582,7 +582,7 @@ tc_editor_add_file(void *baton,
       SVN_ERR(err);
       old_kind = move_dst_kind;
     }
-  
+
   /* Check for NODES tree-conflict. */
   SVN_ERR(check_tree_conflict(&is_conflicted, b, relpath,
                               old_kind, svn_node_file, move_dst_repos_relpath,
@@ -1373,8 +1373,6 @@ get_tc_info(svn_wc_operation_t *operatio
   svn_boolean_t tree_conflicted;
   svn_skel_t *conflict_skel;
 
-  /* ### Check for mixed-rev src or dst? */
-
   /* Check for tree conflict on src. */
   SVN_ERR(svn_wc__db_read_conflict(&conflict_skel, db,
                                    src_abspath,
@@ -1449,7 +1447,7 @@ get_info(apr_hash_t **props,
   else
     SVN_ERR(err);
 
-  
+
   SVN_ERR(svn_wc__db_get_children_op_depth(&hash_children, wcroot,
                                            local_relpath, op_depth,
                                            scratch_pool, scratch_pool));
@@ -1464,7 +1462,7 @@ get_info(apr_hash_t **props,
     APR_ARRAY_PUSH(*children, const char *)
       = apr_pstrdup(result_pool, APR_ARRAY_IDX(sorted_children, i,
                                                svn_sort__item_t).key);
-                                                           
+
   return SVN_NO_ERROR;
 }
 
@@ -1548,7 +1546,7 @@ update_moved_away_node(svn_editor_t *tc_
       SVN_ERR(svn_editor_delete(tc_editor, dst_relpath,
                                 move_root_dst_revision));
     }
- 
+
   if (src_kind != svn_node_none && src_kind != dst_kind)
     {
       if (src_kind == svn_node_file || src_kind == svn_node_symlink)
@@ -1577,7 +1575,7 @@ update_moved_away_node(svn_editor_t *tc_
       SVN_ERR(props_match(&match, src_props, dst_props, scratch_pool));
       props = match ? NULL: src_props;
 
-      
+
       if (src_kind == svn_node_file || src_kind == svn_node_symlink)
         {
           svn_stream_t *contents;
@@ -1711,7 +1709,7 @@ replace_moved_layer(const char *src_relp
         err = svn_sqlite__step_done(stmt2);
       if (err)
         return svn_error_compose_create(err, svn_sqlite__reset(stmt));
- 
+
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
   SVN_ERR(svn_sqlite__reset(stmt));
@@ -1817,7 +1815,7 @@ suitable_for_move(svn_wc__db_wcroot_t *w
         return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                  svn_sqlite__reset(stmt),
                                  _("Cannot apply update because move source "
-                                   "%s' is a mixed-revision working copy"), 
+                                   "%s' is a mixed-revision working copy"),
                                  svn_dirent_local_style(svn_dirent_join(
                                                           wcroot->abspath,
                                                           local_relpath,
@@ -1828,7 +1826,7 @@ suitable_for_move(svn_wc__db_wcroot_t *w
         return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                  svn_sqlite__reset(stmt),
                                  _("Cannot apply update because move source "
-                                   "'%s' is a switched subtree"), 
+                                   "'%s' is a switched subtree"),
                                  svn_dirent_local_style(svn_dirent_join(
                                                           wcroot->abspath,
                                                           local_relpath,
@@ -1960,6 +1958,8 @@ svn_wc__db_update_moved_away_conflict_vi
   svn_wc_conflict_version_t *new_version;
   const char *move_src_op_root_abspath, *move_src_op_root_relpath;
 
+  /* ### Check for mixed-rev src or dst? */
+
   SVN_ERR(get_tc_info(&operation, &local_change, &incoming_change,
                       &move_src_op_root_abspath,
                       &old_version, &new_version,
@@ -2023,7 +2023,7 @@ depth_sufficient_to_bump(svn_boolean_t *
 {
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
-          
+
   switch (depth)
     {
     case svn_depth_infinity:
@@ -2076,8 +2076,6 @@ bump_mark_tree_conflict(svn_wc__db_wcroo
   const char *new_repos_relpath;
   svn_revnum_t old_rev;
   svn_revnum_t new_rev;
-  const char *old_repos_url;
-  const char *new_repos_url;
   svn_node_kind_t old_kind;
   svn_node_kind_t new_kind;
   svn_wc_conflict_version_t *old_version;
@@ -2092,11 +2090,6 @@ bump_mark_tree_conflict(svn_wc__db_wcroo
                                             scratch_pool, scratch_pool));
   SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
                                       wcroot->sdb, repos_id, scratch_pool));
-  new_repos_url = svn_uri_canonicalize(apr_pstrcat(scratch_pool,
-                                                   repos_root_url, "/",
-                                                   new_repos_relpath,
-                                                   (const char *)NULL),
-                                       scratch_pool);
 
   /* Read old (pre-update) information from the move destination node. */
   SVN_ERR(svn_wc__db_depth_get_info(NULL, &old_kind, &old_rev,
@@ -2105,17 +2098,12 @@ bump_mark_tree_conflict(svn_wc__db_wcroo
                                     wcroot, move_dst_op_root_relpath,
                                     relpath_depth(move_dst_op_root_relpath),
                                     scratch_pool, scratch_pool));
-  old_repos_url = svn_uri_canonicalize(apr_pstrcat(scratch_pool,
-                                                   repos_root_url, "/",
-                                                   old_repos_relpath,
-                                                   (const char *)NULL),
-                                       scratch_pool);
 
   old_version = svn_wc_conflict_version_create2(
-                  old_repos_url, repos_uuid, old_repos_relpath, old_rev,
+                  repos_root_url, repos_uuid, old_repos_relpath, old_rev,
                   old_kind, scratch_pool);
   new_version = svn_wc_conflict_version_create2(
-                  new_repos_url, repos_uuid, new_repos_relpath, new_rev,
+                  repos_root_url, repos_uuid, new_repos_relpath, new_rev,
                   new_kind, scratch_pool);
 
   SVN_ERR(mark_tree_conflict(move_src_root_relpath,
@@ -2339,7 +2327,7 @@ resolve_delete_raise_moved_away(svn_wc__
   svn_boolean_t have_row;
   int op_depth = relpath_depth(local_relpath);
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  
+
   SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
                                       STMT_CREATE_UPDATE_MOVE_LIST));
 
@@ -2408,7 +2396,7 @@ svn_wc__db_resolve_delete_raise_moved_aw
 
   SVN_ERR(svn_wc__db_update_move_list_notify(wcroot,
                                              old_version->peg_rev,
-                                             (new_version 
+                                             (new_version
                                               ? new_version->peg_rev
                                               : SVN_INVALID_REVNUM),
                                              notify_func, notify_baton,
@@ -2489,7 +2477,7 @@ break_moved_away_children_internal(svn_w
       const char *src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
       const char *dst_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
       int src_op_depth = svn_sqlite__column_int(stmt, 2);
-      
+
       svn_pool_clear(iterpool);
 
       SVN_ERR(break_move(wcroot, src_relpath, src_op_depth, dst_relpath,
@@ -2595,12 +2583,12 @@ required_lock_for_resolve(const char **r
                                     STMT_SELECT_MOVED_OUTSIDE));
   SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath, 0));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  
+
   while (have_row)
     {
       const char *move_dst_relpath = svn_sqlite__column_text(stmt, 1,
                                                              NULL);
-      
+
       *required_relpath
         = svn_relpath_get_longest_ancestor(*required_relpath,
                                            move_dst_relpath,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_wcroot.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/wc_db_wcroot.c Sat Apr 27 21:30:36 2013
@@ -397,7 +397,7 @@ read_link_target(const char **link_targe
                              svn_dirent_local_style(local_abspath, pool));
 
   canon_link_target = svn_dirent_canonicalize(link_target->data, pool);
-                
+
   /* Treat relative symlinks as relative to LOCAL_ABSPATH's parent. */
   if (!svn_dirent_is_absolute(canon_link_target))
     canon_link_target = svn_dirent_join(svn_dirent_dirname(local_abspath,
@@ -548,8 +548,17 @@ svn_wc__db_wcroot_parse_local_abspath(sv
             {
 #ifdef SVN_DEBUG
               /* Install self-verification trigger statements. */
-              SVN_ERR(svn_sqlite__exec_statements(sdb,
-                                                  STMT_VERIFICATION_TRIGGERS));
+              err = svn_sqlite__exec_statements(sdb,
+                                                STMT_VERIFICATION_TRIGGERS);
+              if (err && err->apr_err == SVN_ERR_SQLITE_ERROR)
+                {
+                  /* Verification triggers can fail to install on old 1.7-dev
+                   * formats which didn't have a NODES table yet. Ignore sqlite
+                   * errors so such working copies can be upgraded. */
+                  svn_error_clear(err);
+                }
+              else
+                SVN_ERR(err);
 #endif
               break;
             }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_wc/workqueue.h?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_wc/workqueue.h Sat Apr 27 21:30:36 2013
@@ -73,7 +73,11 @@ extern "C" {
    These will be combined as appropriate, and returned in one of the
    above three styles.
 
-   The resulting list will be ordered: WORK_ITEM1 first, then WORK_ITEM2  */
+   The resulting list will be ordered: WORK_ITEM1 first, then WORK_ITEM2.
+
+   The result contains a shallow copy of the inputs.  Allocate any
+   additional storage needed in RESULT_POOL.
+ */
 svn_skel_t *
 svn_wc__wq_merge(svn_skel_t *work_item1,
                  svn_skel_t *work_item2,

Modified: subversion/branches/fsfs-format7/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_authz_svn/mod_authz_svn.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_authz_svn/mod_authz_svn.c Sat Apr 27 21:30:36 2013
@@ -110,7 +110,7 @@ canonicalize_access_file(const char *acc
     }
 
   /* We don't canonicalize repos relative urls since they get
-   * canonicalized inside svn_repos_authz_read2() when they
+   * canonicalized before calling svn_repos_authz_read2() when they
    * are resolved. */
 
   return access_file;
@@ -289,7 +289,7 @@ log_svn_error(LOG_ARGS_SIGNATURE,
       else
         {
           char strerr[256];
-          
+
           svn_stringbuf_appendcstr(buff, svn_strerror(err->apr_err, strerr,
                                                        sizeof(strerr)));
         }
@@ -309,6 +309,28 @@ log_svn_error(LOG_ARGS_SIGNATURE,
   svn_error_clear(err);
 }
 
+/* Resolve *PATH into an absolute canonical URL iff *PATH is a repos-relative
+ * URL.  If *REPOS_URL is NULL convert REPOS_PATH into a file URL stored
+ * in *REPOS_URL, if *REPOS_URL is not null REPOS_PATH is ignored.  The
+ * resulting *REPOS_URL will be used as the root of the repos-relative URL.
+ * The result will be stored in *PATH. */
+static svn_error_t *
+resolve_repos_relative_url(const char **path, const char **repos_url,
+                           const char *repos_path, apr_pool_t *pool)
+{
+  if (svn_path_is_repos_relative_url(*path))
+    {
+      if (!*repos_url)
+        SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, repos_path, pool));
+
+      SVN_ERR(svn_path_resolve_repos_relative_url(path, *path,
+                                                  *repos_url, pool));
+      *path = svn_uri_canonicalize(*path, pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /*
  * Get the, possibly cached, svn_authz_t for this request.
  */
@@ -318,10 +340,12 @@ get_access_conf(request_rec *r, authz_sv
 {
   const char *cache_key = NULL;
   const char *access_file;
+  const char *groups_file;
   const char *repos_path;
+  const char *repos_url = NULL;
   void *user_data = NULL;
   svn_authz_t *access_conf = NULL;
-  svn_error_t *svn_err;
+  svn_error_t *svn_err = SVN_NO_ERROR;
   dav_error *dav_err;
 
   dav_err = dav_svn_get_repos_path(r, conf->base_path, &repos_path);
@@ -346,29 +370,54 @@ get_access_conf(request_rec *r, authz_sv
     {
       access_file = conf->access_file;
     }
+  groups_file = conf->groups_file;
+
+  svn_err = resolve_repos_relative_url(&access_file, &repos_url, repos_path,
+                                       scratch_pool);
+  if (svn_err)
+    {
+      log_svn_error(APLOG_MARK, r,
+                    conf->repo_relative_access_file ?
+                    "Failed to load the AuthzSVNReposRelativeAccessFile:" :
+                    "Failed to load the AuthzSVNAccessFile:",
+                    svn_err, scratch_pool);
+      return NULL;
+    }
 
   ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                 "Path to authz file is %s", access_file);
 
-  if (conf->groups_file)
+  if (groups_file)
     {
+      svn_err = resolve_repos_relative_url(&groups_file, &repos_url, repos_path,
+                                           scratch_pool);
+      if (svn_err)
+        {
+          log_svn_error(APLOG_MARK, r,
+                        "Failed to load the AuthzSVNGroupsFile:",
+                        svn_err, scratch_pool);
+          return NULL;
+        }
+
       ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
-                    "Path to groups file is %s", conf->groups_file);
+                    "Path to groups file is %s", groups_file);
     }
 
   cache_key = apr_pstrcat(scratch_pool, "mod_authz_svn:",
-                          access_file, (char *)NULL);
+                          access_file, groups_file, (char *)NULL);
   apr_pool_userdata_get(&user_data, cache_key, r->connection->pool);
   access_conf = user_data;
   if (access_conf == NULL)
     {
+
       svn_err = svn_repos_authz_read2(&access_conf, access_file,
-                                      conf->groups_file, TRUE, repos_path,
+                                      groups_file, TRUE,
                                       r->connection->pool);
+
       if (svn_err)
         {
           log_svn_error(APLOG_MARK, r,
-                        "Failed to load the AuthzSVNAccessFile:",
+                        "Failed to load the mod_authz_svn config:",
                         svn_err, scratch_pool);
           access_conf = NULL;
         }

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/dav_svn.h?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/dav_svn.h Sat Apr 27 21:30:36 2013
@@ -284,11 +284,15 @@ struct dav_resource_private {
   svn_boolean_t auto_checked_out;
 
   /* was this resource fetched using our public peg-/working-rev CGI
-     interface (ie: /path/to/item?p=PEGREV]? */
+     interface (ie: /path/to/item?p=PEGREV)? */
   svn_boolean_t pegged;
 
   /* Cache any revprop change error */
   svn_error_t *revprop_error;
+
+  /* was keyword substitution requested using our public CGI interface
+     (ie: /path/to/item?kw=1)? */
+  svn_boolean_t keyword_subst;
 };
 
 

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/liveprops.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/liveprops.c Sat Apr 27 21:30:36 2013
@@ -834,10 +834,10 @@ insert_prop(const dav_resource *resource
 static int
 is_writable(const dav_resource *resource, int propid)
 {
-  const dav_liveprop_spec *info;
+  const dav_liveprop_spec *info = NULL;
 
   (void) dav_get_liveprop_info(propid, &dav_svn__liveprop_group, &info);
-  return info->is_writable;
+  return info ? info->is_writable : FALSE;
 }
 
 

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/lock.c Sat Apr 27 21:30:36 2013
@@ -143,6 +143,8 @@ unescape_xml(const char **output,
   if (apr_err)
     {
       char errbuf[1024];
+
+      errbuf[0] = '\0';
       (void)apr_xml_parser_geterror(xml_parser, errbuf, sizeof(errbuf));
       return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR,
                                 DAV_ERR_LOCK_SAVE_LOCK, errbuf);
@@ -642,7 +644,7 @@ append_locks(dav_lockdb *lockdb,
   svn_error_t *serr;
   dav_error *derr;
   dav_svn_repos *repos = resource->info->repos;
-      
+
   /* We don't allow anonymous locks */
   if (! repos->username)
     return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED,

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/merge.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/merge.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/merge.c Sat Apr 27 21:30:36 2013
@@ -224,6 +224,7 @@ dav_svn__merge_response(ap_filter_t *out
   svn_string_t *creationdate, *creator_displayname;
   const char *post_commit_err_elem = NULL,
              *post_commit_header_info = NULL;
+  apr_status_t status;
 
   serr = svn_fs_revision_root(&root, repos->fs, new_rev, pool);
   if (serr != NULL)
@@ -284,7 +285,7 @@ dav_svn__merge_response(ap_filter_t *out
     }
 
 
-  (void) ap_fputstrs(output, bb,
+  status = ap_fputstrs(output, bb,
                      DAV_XML_HEADER DEBUG_CR
                      "<D:merge-response xmlns:D=\"DAV:\"",
                      post_commit_header_info,
@@ -304,30 +305,43 @@ dav_svn__merge_response(ap_filter_t *out
                      post_commit_err_elem, DEBUG_CR
                      "<D:version-name>", rev, "</D:version-name>" DEBUG_CR,
                      NULL);
+  if (status != APR_SUCCESS)
+    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              "Could not write output");
+
   if (creationdate)
     {
-      (void) ap_fputstrs(output, bb,
+      status = ap_fputstrs(output, bb,
                          "<D:creationdate>",
                          apr_xml_quote_string(pool, creationdate->data, 1),
                          "</D:creationdate>" DEBUG_CR,
                          NULL);
+      if (status != APR_SUCCESS)
+        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Could not write output");
     }
   if (creator_displayname)
     {
-      (void) ap_fputstrs(output, bb,
+      status = ap_fputstrs(output, bb,
                          "<D:creator-displayname>",
                          apr_xml_quote_string(pool,
                                               creator_displayname->data, 1),
                          "</D:creator-displayname>" DEBUG_CR,
                          NULL);
+      if (status != APR_SUCCESS)
+        return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                  "Could not write output");
     }
-  (void) ap_fputstrs(output, bb,
+  status = ap_fputstrs(output, bb,
                      "</D:prop>" DEBUG_CR
                      "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR
                      "</D:propstat>" DEBUG_CR
                      "</D:response>" DEBUG_CR,
 
                      NULL);
+  if (status != APR_SUCCESS)
+    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              "Could not write output");
 
   /* ONLY have dir_delta drive the editor if the caller asked us to
      generate a full MERGE response.  svn clients can ask us to
@@ -356,12 +370,18 @@ dav_svn__merge_response(ap_filter_t *out
     }
 
   /* wrap up the merge response */
-  (void) ap_fputs(output, bb,
+  status = ap_fputs(output, bb,
                   "</D:updated-set>" DEBUG_CR
                   "</D:merge-response>" DEBUG_CR);
+  if (status != APR_SUCCESS)
+    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              "Could not write output");
 
   /* send whatever is left in the brigade */
-  (void) ap_pass_brigade(output, bb);
+  status = ap_pass_brigade(output, bb);
+  if (status != APR_SUCCESS)
+    return dav_svn__new_error(repos->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
+                              "Could not write output");
 
   return NULL;
 }

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/mod_dav_svn.c Sat Apr 27 21:30:36 2013
@@ -315,7 +315,7 @@ SVNMasterVersion_cmd(cmd_parms *cmd, voi
       svn_error_clear(err);
       return "Malformed master server version string.";
     }
-  
+
   conf->master_version = version;
   return NULL;
 }
@@ -1150,7 +1150,7 @@ static const command_rec cmds[] =
   AP_INIT_TAKE1("SVNMasterVersion", SVNMasterVersion_cmd, NULL, ACCESS_CONF,
                 "specifies the Subversion release version of a master "
                 "Subversion server "),
-  
+
   /* per directory/location */
   AP_INIT_TAKE1("SVNActivitiesDB", SVNActivitiesDB_cmd, NULL, ACCESS_CONF,
                 "specifies the location in the filesystem in which the "

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/posts/create_txn.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/posts/create_txn.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/posts/create_txn.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/posts/create_txn.c Sat Apr 27 21:30:36 2013
@@ -91,7 +91,7 @@ dav_svn__post_create_txn_with_props(cons
       return dav_svn__convert_err(err, HTTP_BAD_REQUEST,
                                   "Malformatted request skel", resource->pool);
     }
-  
+
   /* Create a Subversion repository transaction based on HEAD. */
   if ((derr = dav_svn__create_txn(resource->info->repos, &txn_name,
                                   revprops, resource->pool)))

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/inherited-props.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/inherited-props.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/inherited-props.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/inherited-props.c Sat Apr 27 21:30:36 2013
@@ -194,7 +194,7 @@ dav_svn__get_inherited_props_report(cons
                 }
 
               if (serr)
-                break;              
+                break;
             }
           if (!serr)
             serr = dav_svn__brigade_printf(bb, output,

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/replay.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/replay.c Sat Apr 27 21:30:36 2013
@@ -450,7 +450,7 @@ dav_svn__replay_report(const dav_resourc
       rev = SVN_INVALID_REVNUM;
       base_dir = resource->info->repos_path;
     }
-  
+
   arb.r = resource->info->r;
   arb.repos = resource->info->repos;
 

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/update.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/reports/update.c Sat Apr 27 21:30:36 2013
@@ -116,10 +116,10 @@ typedef struct item_baton_t {
   const char *path3;   /* ... uc->dst_path, without dst_path prefix. */
 
   /* Base_checksum (from apply_textdelta). */
-  const char *base_checksum;   
+  const char *base_checksum;
 
   /* Did the file's contents change? */
-  svn_boolean_t text_changed; 
+  svn_boolean_t text_changed;
 
   /* File/dir added? (Implies text_changed for files.) */
   svn_boolean_t added;
@@ -470,7 +470,7 @@ close_helper(svn_boolean_t is_dir, item_
   if (baton->fetch_props)
     SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output,
                                     "<S:fetch-props/>" DEBUG_CR));
-    
+
 
   /* Let's tie it off, nurse. */
   if (baton->added)
@@ -655,7 +655,7 @@ send_propchange(item_baton_t *b,
                                       DEBUG_CR,
                                       qname));
     }
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -711,7 +711,7 @@ upd_change_xxx_prop(void *baton,
             {
               if (! b->removed_props)
                 b->removed_props = apr_array_make(b->pool, 1, sizeof(name));
-              
+
               APR_ARRAY_PUSH(b->removed_props, const char *) = name;
             }
         }
@@ -935,7 +935,7 @@ validate_input_revision(svn_revnum_t rev
 {
   if (! SVN_IS_VALID_REVNUM(revision))
     return SVN_NO_ERROR;
-    
+
   if (revision > youngest)
     {
       svn_error_t *serr;
@@ -1021,7 +1021,7 @@ dav_svn__update_report(const dav_resourc
      (a report with props and textdeltas inline, rather than placeholder tags
      that tell the client to do further fetches), look to see if client
      requested as much.
-      
+
      SVNAllowBulkUpdates Off: no bulk updates allowed, force skelta mode.
    */
   if (repos->bulk_updates == CONF_BULKUPD_ON ||

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/repos.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/repos.c Sat Apr 27 21:30:36 2013
@@ -49,6 +49,7 @@
 #include "svn_version.h"
 #include "svn_props.h"
 #include "svn_ctype.h"
+#include "svn_subst.h"
 #include "mod_dav_svn.h"
 #include "svn_ra.h"  /* for SVN_RA_CAPABILITY_* */
 #include "svn_dirent_uri.h"
@@ -1821,6 +1822,12 @@ parse_querystring(request_rec *r, const 
   apr_table_t *pairs = querystring_to_table(query, pool);
   const char *prevstr = apr_table_get(pairs, "p");
   const char *wrevstr;
+  const char *keyword_subst;
+
+  /* Will we be doing keyword substitution? */
+  keyword_subst = apr_table_get(pairs, "kw");
+  if (keyword_subst && (strcmp(keyword_subst, "1") == 0))
+    comb->priv.keyword_subst = TRUE;
 
   if (prevstr)
     {
@@ -1880,7 +1887,7 @@ parse_querystring(request_rec *r, const 
     }
   else
     {
-      const char *newpath;
+      const char *newpath, *location;
       apr_hash_t *locations;
       apr_array_header_t *loc_revs = apr_array_make(pool, 1,
                                                     sizeof(svn_revnum_t));
@@ -1909,15 +1916,17 @@ parse_querystring(request_rec *r, const 
       /* Redirect folks to a canonical, peg-revision-only location.
          If they used a peg revision in this request, we can use a
          permanent redirect.  If they didn't (peg-rev is HEAD), we can
-         only use a temporary redirect. */
-      apr_table_setn(r->headers_out, "Location",
-                     ap_construct_url(r->pool,
-                                  apr_psprintf(r->pool, "%s%s?p=%ld",
+         only use a temporary redirect.  In either case, preserve the
+         "keyword_subst" state in the redirected location, too.  */
+      location = ap_construct_url(r->pool,
+                                  apr_psprintf(r->pool, "%s%s?p=%ld%s",
                                                (comb->priv.repos->root_path[1]
                                                 ? comb->priv.repos->root_path
                                                 : ""),
-                                               newpath, working_rev),
-                                      r));
+                                               newpath, working_rev,
+                                               keyword_subst ? "&kw=1" : ""),
+                                  r);
+      apr_table_setn(r->headers_out, "Location", location);
       return dav_svn__new_error(r->pool,
                                 prevstr ? HTTP_MOVED_PERMANENTLY
                                         : HTTP_MOVED_TEMPORARILY,
@@ -2219,7 +2228,7 @@ get_resource(request_rec *r,
 
       /* Configure hook script environment variables. */
       serr = svn_repos_hooks_setenv(repos->repos, dav_svn__get_hooks_env(r),
-                                    r->connection->pool, r->pool);
+                                    r->pool);
       if (serr)
         return dav_svn__sanitize_error(serr,
                                        "Error settings hooks environment",
@@ -3025,19 +3034,23 @@ set_headers(request_rec *r, const dav_re
         mimetype = "text/plain";
 
 
-      /* if we aren't sending a diff, then we know the length of the file,
-         so set up the Content-Length header */
-      serr = svn_fs_file_length(&length,
-                                resource->info->root.root,
-                                resource->info->repos_path,
-                                resource->pool);
-      if (serr != NULL)
-        {
-          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
-                                      "could not fetch the resource length",
-                                      resource->pool);
+      /* if we aren't sending a diff and aren't expanding keywords,
+         then we know the exact length of the file, so set up the
+         Content-Length header. */
+      if (! resource->info->keyword_subst)
+        {
+          serr = svn_fs_file_length(&length,
+                                    resource->info->root.root,
+                                    resource->info->repos_path,
+                                    resource->pool);
+          if (serr != NULL)
+            {
+              return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                          "could not fetch the resource length",
+                                          resource->pool);
+            }
+          ap_set_content_length(r, (apr_off_t) length);
         }
-      ap_set_content_length(r, (apr_off_t) length);
     }
 
   /* set the discovered MIME type */
@@ -3563,6 +3576,77 @@ deliver(const dav_resource *resource, ap
                                       resource->pool);
         }
 
+      /* Perform keywords substitution if requested by client */
+      if (resource->info->keyword_subst)
+        {
+          svn_string_t *keywords;
+
+          serr = svn_fs_node_prop(&keywords,
+                                  resource->info->root.root,
+                                  resource->info->repos_path,
+                                  SVN_PROP_KEYWORDS,
+                                  resource->pool);
+          if (serr != NULL)
+            return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                        "could not get fetch '"
+                                        SVN_PROP_KEYWORDS "' property for "
+                                        "for keywords substitution",
+                                        resource->pool);
+
+          if (keywords)
+            {
+              apr_hash_t *kw;
+              svn_revnum_t cmt_rev;
+              const char *str_cmt_rev, *str_uri, *str_root;
+              const char *cmt_date, *cmt_author;
+              apr_time_t when = 0;
+
+              serr = svn_repos_get_committed_info(&cmt_rev,
+                                                  &cmt_date,
+                                                  &cmt_author,
+                                                  resource->info->root.root,
+                                                  resource->info->repos_path,
+                                                  resource->pool);
+              if (serr != NULL)
+                return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                            "could not fetch committed info "
+                                            "for keywords substitution",
+                                            resource->pool);
+
+              serr = svn_time_from_cstring(&when, cmt_date, resource->pool);
+              if (serr != NULL)
+                return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                            "could not parse committed date "
+                                            "for keywords substitution",
+                                            resource->pool);
+              str_cmt_rev = apr_psprintf(resource->pool, "%ld", cmt_rev);
+              str_uri = apr_pstrcat(resource->pool,
+                                    resource->info->repos->base_url,
+                                    ap_escape_uri(resource->pool,
+                                                  resource->info->r->uri),
+                                    NULL);
+              str_root = apr_pstrcat(resource->pool,
+                                     resource->info->repos->base_url,
+                                     resource->info->repos->root_path,
+                                     NULL);
+
+              serr = svn_subst_build_keywords3(&kw, keywords->data,
+                                               str_cmt_rev, str_uri, str_root,
+                                               when, cmt_author,
+                                               resource->pool);
+              if (serr != NULL)
+                return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                            "could not perform keywords "
+                                            "substitution", resource->pool);
+
+              /* Replace the raw file STREAM with a wrapper that
+                 handles keyword translation. */
+              stream = svn_subst_stream_translated(
+                           svn_stream_disown(stream, resource->pool),
+                           NULL, FALSE, kw, TRUE, resource->pool);
+            }
+        }
+
       /* ### one day in the future, we can create a custom bucket type
          ### which will read from the FS stream on demand */
 
@@ -4379,6 +4463,32 @@ handle_post_request(request_rec *r,
                             "Unsupported skel POST request flavor.");
 }
 
+
+/* A stripped down version of mod_dav's dav_handle_err so that POST
+   errors, which are not passed via mod_dav, are handled in the same
+   way as errors for requests that are passed via mod_dav. */
+static int
+handle_err(request_rec *r, dav_error *err)
+{
+  dav_error *stackerr = err;
+
+  dav_svn__log_err(r, err, APLOG_ERR);
+
+  /* our error messages are safe; tell Apache this */
+  apr_table_setn(r->notes, "verbose-error-to", "*");
+
+  /* We might be able to generate a standard <D:error> response.
+     Search the error stack for an errortag. */
+  while (stackerr != NULL && stackerr->tagname == NULL)
+    stackerr = stackerr->prev;
+
+  if (stackerr != NULL && stackerr->tagname != NULL)
+    return dav_svn__error_response_tag(r, stackerr);
+
+  return err->status;
+}
+
+
 int dav_svn__method_post(request_rec *r)
 {
   dav_resource *resource;
@@ -4411,9 +4521,8 @@ int dav_svn__method_post(request_rec *r)
   if (derr)
     {
       /* POST is not a DAV method and so mod_dav isn't involved and
-         won't log this error.  Do it explicitly. */
-      dav_svn__log_err(r, derr, APLOG_ERR);
-      return dav_svn__error_response_tag(r, derr);
+         won't handle this error.  Do it explicitly. */
+      return handle_err(r, derr);
     }
 
   return OK;

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/util.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/util.c Sat Apr 27 21:30:36 2013
@@ -621,7 +621,7 @@ dav_svn__final_flush_or_error(request_re
   if (! do_flush)
     {
       /* Ask about the length of the bucket brigade, ignoring errors. */
-      apr_off_t len;
+      apr_off_t len = 0;
       (void)apr_brigade_length(bb, FALSE, &len);
       do_flush = (len != 0);
     }

Modified: subversion/branches/fsfs-format7/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/mod_dav_svn/version.c?rev=1476675&r1=1476674&r2=1476675&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/fsfs-format7/subversion/mod_dav_svn/version.c Sat Apr 27 21:30:36 2013
@@ -269,7 +269,7 @@ get_option(const dav_resource *resource,
       int i;
       svn_version_t *master_version = dav_svn__get_master_version(r);
       dav_svn__bulk_upd_conf bulk_upd_conf = dav_svn__get_bulk_updates_flag(r);
-      
+
       /* The list of Subversion's custom POSTs and which versions of
          Subversion support them.  We need this latter information
          when acting as a WebDAV slave -- we don't want to claim
@@ -1222,7 +1222,7 @@ make_activity(dav_resource *resource)
                                   SVN_DAV_ERROR_NAMESPACE,
                                   SVN_DAV_ERROR_TAG);
 
-  err = dav_svn__create_txn(resource->info->repos, &txn_name, 
+  err = dav_svn__create_txn(resource->info->repos, &txn_name,
                             NULL, resource->pool);
   if (err != NULL)
     return err;



Mime
View raw message