Modified: 
subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.c 
Wed Nov 23 16:12:52 2011
@@ -149,6 +149,49 @@ svn_client__record_wc_mergeinfo(const ch
 }
 
 svn_error_t *
+svn_client__record_wc_mergeinfo_catalog(apr_hash_t *result_catalog,
+                                        svn_client_ctx_t *ctx,
+                                        apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+  if (apr_hash_count(result_catalog))
+    {
+      int i;
+      apr_array_header_t *sorted_cat =
+        svn_sort__hash(result_catalog, svn_sort_compare_items_as_paths,
+                       scratch_pool);
+      for (i = 0; i < sorted_cat->nelts; i++)
+        {
+          svn_sort__item_t elt = APR_ARRAY_IDX(sorted_cat, i,
+                                               svn_sort__item_t);
+          svn_error_t *err;
+
+          svn_pool_clear(iterpool);
+          err = svn_client__record_wc_mergeinfo(elt.key, elt.value, TRUE,
+                                                ctx, iterpool);
+
+          if (err && err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
+            {
+              /* PATH isn't just missing, it's not even versioned as far
+                 as this working copy knows.  But it was included in
+                 MERGES, which means that the server knows about it.
+                 Likely we don't have access to the source due to authz
+                 restrictions.  For now just clear the error and
+                 continue... */
+              svn_error_clear(err);
+            }
+          else
+            {
+              SVN_ERR(err);
+            }
+        }
+    }
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_client__rangelist_intersect_range(apr_array_header_t **out_rangelist,
                                       const apr_array_header_t *in_rangelist,
                                       svn_revnum_t rev1,
@@ -182,7 +225,7 @@ svn_client__rangelist_intersect_range(ap
 
 svn_error_t *
 svn_client__get_wc_mergeinfo(svn_mergeinfo_t *mergeinfo,
-                             svn_boolean_t *inherited,
+                             svn_boolean_t *inherited_p,
                              svn_mergeinfo_inheritance_t inherit,
                              const char *local_abspath,
                              const char *limit_abspath,
@@ -196,6 +239,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
   svn_mergeinfo_t wc_mergeinfo;
   svn_revnum_t base_revision;
   apr_pool_t *iterpool;
+  svn_boolean_t inherited;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
   if (limit_abspath)
@@ -298,7 +342,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
   if (svn_path_is_empty(walk_relpath))
     {
       /* Mergeinfo is explicit. */
-      *inherited = FALSE;
+      inherited = FALSE;
       *mergeinfo = wc_mergeinfo;
     }
   else
@@ -306,7 +350,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
       /* Mergeinfo may be inherited. */
       if (wc_mergeinfo)
         {
-          *inherited = TRUE;
+          inherited = TRUE;
           SVN_ERR(svn_mergeinfo__add_suffix_to_mergeinfo(mergeinfo,
                                                          wc_mergeinfo,
                                                          walk_relpath,
@@ -315,7 +359,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
         }
       else
         {
-          *inherited = FALSE;
+          inherited = FALSE;
           *mergeinfo = NULL;
         }
     }
@@ -325,7 +369,7 @@ svn_client__get_wc_mergeinfo(svn_mergein
 
   /* Remove non-inheritable mergeinfo and paths mapped to empty ranges
      which may occur if WCPATH's mergeinfo is not explicit. */
-  if (*inherited
+  if (inherited
       && apr_hash_count(*mergeinfo)) /* Nothing to do for empty mergeinfo. */
     {
       SVN_ERR(svn_mergeinfo_inheritable2(mergeinfo, *mergeinfo, NULL,
@@ -334,6 +378,9 @@ svn_client__get_wc_mergeinfo(svn_mergein
       svn_mergeinfo__remove_empty_rangelists(*mergeinfo, result_pool);
     }
 
+  if (inherited_p)
+    *inherited_p = inherited;
+
   return SVN_NO_ERROR;
 }
 
@@ -364,7 +411,8 @@ svn_client__get_wc_mergeinfo_catalog(svn
     {
       if (walked_path)
         *walked_path = "";
-      *inherited = FALSE;
+      if (inherited)
+        *inherited = FALSE;
       return SVN_NO_ERROR;
     }
 
@@ -574,7 +622,7 @@ svn_client__get_wc_or_repos_mergeinfo(sv
 svn_error_t *
 svn_client__get_wc_or_repos_mergeinfo_catalog(
   svn_mergeinfo_catalog_t *target_mergeinfo_catalog,
-  svn_boolean_t *inherited,
+  svn_boolean_t *inherited_p,
   svn_boolean_t *from_repos,
   svn_boolean_t include_descendants,
   svn_boolean_t repos_only,
@@ -616,8 +664,9 @@ svn_client__get_wc_or_repos_mergeinfo_ca
 
   if (!repos_only)
     {
+      svn_boolean_t inherited;
       SVN_ERR(svn_client__get_wc_mergeinfo_catalog(&target_mergeinfo_cat_wc,
-                                                   inherited,
+                                                   &inherited,
                                                    include_descendants,
                                                    inherit,
                                                    local_abspath,
@@ -626,11 +675,13 @@ svn_client__get_wc_or_repos_mergeinfo_ca
                                                    ctx,
                                                    result_pool,
                                                    scratch_pool));
+      if (inherited_p)
+        *inherited_p = inherited;
 
       /* If we want LOCAL_ABSPATH's inherited mergeinfo, were we able to
          get it from the working copy?  If not, then we must ask the
          repository. */
-      if (! ((*inherited)
+      if (! (inherited
              || (inherit == svn_mergeinfo_explicit)
              || (repos_relpath
                  && target_mergeinfo_cat_wc
@@ -688,7 +739,8 @@ svn_client__get_wc_or_repos_mergeinfo_ca
                                   repos_relpath,
                                   APR_HASH_KEY_STRING))
                 {
-                  *inherited = TRUE;
+                  if (inherited_p)
+                    *inherited_p = TRUE;
                   if (from_repos)
                     *from_repos = TRUE;
                 }
@@ -1058,7 +1110,7 @@ svn_client__elide_mergeinfo(const char *
         return SVN_NO_ERROR;
 
       /* Get TARGET_WCPATH's inherited mergeinfo from the WC. */
-      err = svn_client__get_wc_mergeinfo(&mergeinfo, &inherited,
+      err = svn_client__get_wc_mergeinfo(&mergeinfo, NULL,
                                          svn_mergeinfo_nearest_ancestor,
                                          target_abspath,
                                          limit_abspath,
@@ -1083,7 +1135,7 @@ svn_client__elide_mergeinfo(const char *
       if (!mergeinfo && !wc_elision_limit_path)
         {
           err = svn_client__get_wc_or_repos_mergeinfo(
-            &mergeinfo, &inherited, NULL, TRUE,
+            &mergeinfo, NULL, NULL, TRUE,
             svn_mergeinfo_nearest_ancestor,
             NULL, target_wcpath, ctx, pool);
           if (err)
@@ -1195,11 +1247,9 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
     }
   else /* ! svn_path_is_url() */
     {
-      svn_boolean_t inherited;
-
       /* Acquire return values. */
       SVN_ERR(svn_client__get_wc_or_repos_mergeinfo_catalog(
-        mergeinfo_catalog, &inherited, NULL, include_descendants, FALSE,
+        mergeinfo_catalog, NULL, NULL, include_descendants, FALSE,
         ignore_invalid_mergeinfo, svn_mergeinfo_inherited,
         ra_session, path_or_url, ctx,
         result_pool, scratch_pool));
@@ -1616,15 +1666,30 @@ filter_log_entry_with_rangelist(void *ba
                                                       iterpool));
                       if (intersection->nelts)
                         {
-                          SVN_ERR(svn_rangelist_intersect(&intersection,
-                                                          rangelist,
-                                                          this_rev_rangelist,
-                                                          TRUE, iterpool));
-                          if (intersection->nelts)
+                          if (ancestor_is_self)
                             {
+                              /* TARGET_PATH_AFFECTED has explicit mergeinfo,
+                                 so we don't need to worry if that mergeinfo
+                                 is inheritable or not. */
                               found_this_revision = TRUE;
                               break;
                             }
+                          else
+                            {
+                              /* TARGET_PATH_AFFECTED inherited its mergeinfo,
+                                 se we have to ignore non-inheritable
+                                 ranges. */
+                              SVN_ERR(svn_rangelist_intersect(
+                                &intersection,
+                                rangelist,
+                                this_rev_rangelist,
+                                TRUE, iterpool));
+                              if (intersection->nelts)
+                                {
+                                  found_this_revision = TRUE;
+                                  break;
+                                }
+                            }
                         }
                     }
                 }

Modified: 
subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.h?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.h 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/mergeinfo.h 
Wed Nov 23 16:12:52 2011
@@ -99,7 +99,8 @@ svn_client__merge_path_create(const char
 
 /* Find explicit or inherited WC mergeinfo for LOCAL_ABSPATH, and return it
    in *MERGEINFO (NULL if no mergeinfo is set).  Set *INHERITED to
-   whether the mergeinfo was inherited (TRUE or FALSE).
+   whether the mergeinfo was inherited (TRUE or FALSE), if INHERITED is
+   non-null.
 
    This function will search for inherited mergeinfo in the parents of
    LOCAL_ABSPATH only if the base revision of LOCAL_ABSPATH falls within
@@ -233,7 +234,7 @@ svn_client__get_repos_mergeinfo_catalog(
 
    If TARGET_WCPATH inherited its mergeinfo from a working copy ancestor
    or if it was obtained from the repository, set *INHERITED to TRUE, set it
-   to FALSE otherwise. */
+   to FALSE otherwise, if INHERITED is non-null. */
 svn_error_t *
 svn_client__get_wc_or_repos_mergeinfo(svn_mergeinfo_t *target_mergeinfo,
                                       svn_boolean_t *inherited,
@@ -320,6 +321,13 @@ svn_client__record_wc_mergeinfo(const ch
                                 svn_client_ctx_t *ctx,
                                 apr_pool_t *scratch_pool);
 
+/* Write mergeinfo into the WC.  RESULT_CATALOG maps (const char *) WC paths
+ * to (svn_mergeinfo_t) mergeinfo. */
+svn_error_t *
+svn_client__record_wc_mergeinfo_catalog(apr_hash_t *result_catalog,
+                                        svn_client_ctx_t *ctx,
+                                        apr_pool_t *scratch_pool);
+
 /* Elide any svn:mergeinfo set on TARGET_WCPATH to its nearest working
    copy (or possibly repository) ancestor with equivalent mergeinfo.
 

Modified: 
subversion/branches/showing-merge-info/subversion/libsvn_delta/compat.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_delta/compat.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_delta/compat.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_delta/compat.c Wed 
Nov 23 16:12:52 2011
@@ -99,11 +99,15 @@ typedef svn_error_t *(*start_edit_func_t
     apr_pool_t *result_pool,
     void **root_baton);
 
+typedef svn_error_t *(*target_revision_func_t)(
+    void *baton,
+    svn_revnum_t target_revision,
+    apr_pool_t *scratch_pool);
+
 struct ev2_edit_baton
 {
   svn_editor_t *editor;
   apr_hash_t *paths;
-  svn_revnum_t target_revision;
   apr_pool_t *edit_pool;
 
   svn_boolean_t *found_abs_paths; /* Did we strip an incoming '/' from the
@@ -116,6 +120,9 @@ struct ev2_edit_baton
 
   svn_delta_fetch_props_func_t fetch_props_func;
   void *fetch_props_baton;
+
+  target_revision_func_t target_revision_func;
+  void *target_revision_baton;
 };
 
 struct ev2_dir_baton
@@ -128,6 +135,7 @@ struct ev2_file_baton
 {
   struct ev2_edit_baton *eb;
   const char *path;
+  const char *delta_base;
 };
 
 enum action_code_t
@@ -138,7 +146,9 @@ enum action_code_t
   ACTION_PROPSET,
   ACTION_PUT,
   ACTION_ADD,
-  ACTION_DELETE
+  ACTION_DELETE,
+  ACTION_ADD_ABSENT,
+  ACTION_SET_TEXT
 };
 
 struct path_action
@@ -196,7 +206,7 @@ process_actions(void *edit_baton,
   apr_hash_t *props = NULL;
   svn_boolean_t need_add = FALSE;
   apr_array_header_t *children;
-  svn_stream_t *contents;
+  svn_stream_t *contents = NULL;
   svn_kind_t kind;
   int i;
 
@@ -258,12 +268,21 @@ process_actions(void *edit_baton,
                 }
               else
                 {
-                  /* ### Someday, we'll need the real contents here. */
+                  /* The default is an empty file. */
                   contents = svn_stream_empty(scratch_pool);
                 }
               break;
             }
 
+          case ACTION_SET_TEXT:
+            {
+              const char *src_path = action->args;
+
+              SVN_ERR(svn_stream_open_readonly(&contents, src_path,
+                                               scratch_pool, scratch_pool));
+              break;
+            }
+
           case ACTION_COPY:
             {
               struct copy_args *c_args = action->args;
@@ -274,6 +293,14 @@ process_actions(void *edit_baton,
               break;
             }
 
+          case ACTION_ADD_ABSENT:
+            {
+              kind = *((svn_kind_t *) action->args);
+              SVN_ERR(svn_editor_add_absent(eb->editor, path, kind,
+                                            SVN_INVALID_REVNUM));
+              break;
+            }
+
           default:
             SVN_ERR_MALFUNCTION();
         }
@@ -301,8 +328,15 @@ process_actions(void *edit_baton,
         {
           /* We fetched and modified the props in some way. Apply 'em now that
              we have the new set.  */
-          SVN_ERR(svn_editor_set_props(eb->editor, path, eb->target_revision,
-                                       props, TRUE));
+          SVN_ERR(svn_editor_set_props(eb->editor, path, SVN_INVALID_REVNUM,
+                                       props, contents == NULL));
+        }
+
+      if (contents)
+        {
+          /* If we have an content for this node, set it now. */
+          SVN_ERR(svn_editor_set_text(eb->editor, path, SVN_INVALID_REVNUM,
+                                      NULL, contents));
         }
     }
 
@@ -347,7 +381,8 @@ ev2_set_target_revision(void *edit_baton
 {
   struct ev2_edit_baton *eb = edit_baton;
 
-  eb->target_revision = target_revision;
+  SVN_ERR(eb->target_revision_func(eb->target_revision_baton, target_revision,
+                                   scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -470,6 +505,11 @@ ev2_absent_directory(const char *path,
                      apr_pool_t *scratch_pool)
 {
   struct ev2_dir_baton *pb = parent_baton;
+  svn_kind_t *kind = apr_palloc(pb->eb->edit_pool, sizeof(*kind));
+  
+  *kind = svn_kind_dir;
+  SVN_ERR(add_action(pb->eb, path, ACTION_ADD_ABSENT, kind));
+
   return SVN_NO_ERROR;
 }
 
@@ -486,6 +526,7 @@ ev2_add_file(const char *path,
 
   fb->eb = pb->eb;
   fb->path = apr_pstrdup(result_pool, path);
+  fb->delta_base = NULL;
   *file_baton = fb;
 
   if (!copyfrom_path)
@@ -521,11 +562,35 @@ ev2_open_file(const char *path,
 
   fb->eb = pb->eb;
   fb->path = apr_pstrdup(result_pool, path);
+  fb->delta_base = NULL;
 
   *file_baton = fb;
   return SVN_NO_ERROR;
 }
 
+struct handler_baton
+{
+  svn_txdelta_window_handler_t apply_handler;
+  void *apply_baton;
+
+  apr_pool_t *pool;
+};
+
+static svn_error_t *
+window_handler(svn_txdelta_window_t *window, void *baton)
+{
+  struct handler_baton *hb = baton;
+  svn_error_t *err;
+
+  err = hb->apply_handler(window, hb->apply_baton);
+  if (window != NULL && !err)
+    return SVN_NO_ERROR;
+
+  svn_pool_destroy(hb->pool);
+
+  return SVN_NO_ERROR;
+}
+
 
 static svn_error_t *
 ev2_apply_textdelta(void *file_baton,
@@ -535,9 +600,31 @@ ev2_apply_textdelta(void *file_baton,
                     void **handler_baton)
 {
   struct ev2_file_baton *fb = file_baton;
+  apr_pool_t *handler_pool = svn_pool_create(fb->eb->edit_pool);
+  struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
+  const char *target_path;
+  svn_stream_t *source;
+  svn_stream_t *target;
+
+  if (! fb->delta_base)
+    source = svn_stream_empty(handler_pool);
+
+  SVN_ERR(svn_stream_open_unique(&target, &target_path, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 fb->eb->edit_pool, result_pool));
+
+  svn_txdelta_apply(source, target,
+                    NULL, NULL,
+                    handler_pool,
+                    &hb->apply_handler, &hb->apply_baton);
+
+  hb->pool = handler_pool;
+                    
+  *handler_baton = hb;
+  *handler = window_handler;
+
+  SVN_ERR(add_action(fb->eb, fb->path, ACTION_SET_TEXT, (void *)target_path));
 
-  *handler_baton = NULL;
-  *handler = svn_delta_noop_window_handler;
   return SVN_NO_ERROR;
 }
 
@@ -572,6 +659,11 @@ ev2_absent_file(const char *path,
                 apr_pool_t *scratch_pool)
 {
   struct ev2_dir_baton *pb = parent_baton;
+  svn_kind_t *kind = apr_palloc(pb->eb->edit_pool, sizeof(*kind));
+  
+  *kind = svn_kind_file;
+  SVN_ERR(add_action(pb->eb, path, ACTION_ADD_ABSENT, kind));
+
   return SVN_NO_ERROR;
 }
 
@@ -616,6 +708,19 @@ start_edit_func(void *baton,
 }
 
 static svn_error_t *
+target_revision_func(void *baton,
+                     svn_revnum_t target_revision,
+                     apr_pool_t *scratch_pool)
+{
+  struct start_edit_baton *seb = baton;
+
+  SVN_ERR(seb->deditor->set_target_revision(seb->dedit_baton, target_revision,
+                                            scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 delta_from_editor(const svn_delta_editor_t **deditor,
                   void **dedit_baton,
                   svn_editor_t *editor,
@@ -624,6 +729,8 @@ delta_from_editor(const svn_delta_editor
                   void *fetch_props_baton,
                   start_edit_func_t start_edit,
                   void *start_edit_baton,
+                  target_revision_func_t target_revision,
+                  void *target_revision_baton,
                   apr_pool_t *pool)
 {
   /* Static 'cause we don't want it to be on the stack. */
@@ -649,7 +756,6 @@ delta_from_editor(const svn_delta_editor
 
   eb->editor = editor;
   eb->paths = apr_hash_make(pool);
-  eb->target_revision = SVN_INVALID_REVNUM;
   eb->edit_pool = pool;
   eb->found_abs_paths = found_abs_paths;
 
@@ -659,6 +765,9 @@ delta_from_editor(const svn_delta_editor
   eb->start_edit = start_edit;
   eb->start_edit_baton = start_edit_baton;
 
+  eb->target_revision_func = target_revision;
+  eb->target_revision_baton = target_revision_baton;
+
   *dedit_baton = eb;
   *deditor = &delta_editor;
 
@@ -675,6 +784,7 @@ struct operation {
     OP_DELETE,
     OP_ADD,
     OP_REPLACE,
+    OP_ADD_ABSENT,
     OP_PROPSET           /* only for files for which no other operation is
                             occuring; directories are OP_OPEN with non-empty
                             props */
@@ -790,8 +900,12 @@ build(struct editor_baton *eb,
       apr_hash_t *current_props;
       apr_array_header_t *propdiffs;
 
-      SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
-                                  relpath, scratch_pool));
+      if (kind == svn_kind_unknown)
+        SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
+                                    relpath, scratch_pool));
+      else
+        operation->kind = kind;
+
       SVN_ERR(eb->fetch_props_func(&current_props, eb->fetch_props_baton,
                                    relpath, scratch_pool, scratch_pool));
 
@@ -827,6 +941,9 @@ build(struct editor_baton *eb,
   if (action == ACTION_DELETE)
     operation->operation = OP_DELETE;
 
+  else if (action == ACTION_ADD_ABSENT)
+    operation->operation = OP_ADD_ABSENT;
+
   /* Handle copy operations (which can be adds or replacements). */
   else if (action == ACTION_COPY)
     {
@@ -907,6 +1024,11 @@ add_directory_cb(void *baton,
                 NULL, SVN_INVALID_REVNUM,
                 NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
 
+  if (props && apr_hash_count(props) > 0)
+    SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_dir,
+                  NULL, SVN_INVALID_REVNUM, props,
+                  NULL, SVN_INVALID_REVNUM, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -937,6 +1059,11 @@ add_file_cb(void *baton,
                 NULL, SVN_INVALID_REVNUM,
                 NULL, tmp_filename, SVN_INVALID_REVNUM, scratch_pool));
 
+  if (props && apr_hash_count(props) > 0)
+    SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_file,
+                  NULL, SVN_INVALID_REVNUM, props,
+                  NULL, SVN_INVALID_REVNUM, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -968,6 +1095,10 @@ add_absent_cb(void *baton,
 
   SVN_ERR(ensure_root_opened(eb));
 
+  SVN_ERR(build(eb, ACTION_ADD_ABSENT, relpath, kind,
+                NULL, SVN_INVALID_REVNUM,
+                NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -984,7 +1115,7 @@ set_props_cb(void *baton,
 
   SVN_ERR(ensure_root_opened(eb));
 
-  SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_none,
+  SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_unknown,
                 NULL, SVN_INVALID_REVNUM,
                 props, NULL, SVN_INVALID_REVNUM, scratch_pool));
 
@@ -1137,10 +1268,10 @@ change_props(const svn_delta_editor_t *e
 }
 
 static svn_error_t *
-drive(const struct operation *operation,
-      const svn_delta_editor_t *editor,
-      svn_boolean_t *make_abs_paths,
-      apr_pool_t *scratch_pool)
+drive_tree(const struct operation *operation,
+           const svn_delta_editor_t *editor,
+           svn_boolean_t *make_abs_paths,
+           apr_pool_t *scratch_pool)
 {
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_hash_index_t *hi;
@@ -1192,6 +1323,15 @@ drive(const struct operation *operation,
                                      &file_baton));
         }
 
+      if (child->operation == OP_ADD_ABSENT)
+        {
+          if (child->kind == svn_kind_dir)
+            SVN_ERR(editor->absent_directory(path, operation->baton,
+                                             iterpool));
+          else
+            SVN_ERR(editor->absent_file(path, operation->baton, iterpool));
+        }
+
       if (child->src_file && file_baton)
         {
           /* We need to change textual contents. */
@@ -1224,7 +1364,7 @@ drive(const struct operation *operation,
                     || child->operation == OP_PROPSET
                     || child->operation == OP_ADD))
         {
-          SVN_ERR(drive(child, editor, make_abs_paths, iterpool));
+          SVN_ERR(drive_tree(child, editor, make_abs_paths, iterpool));
           SVN_ERR(change_props(editor, child->baton, child, iterpool));
           SVN_ERR(editor->close_directory(child->baton, iterpool));
         }
@@ -1242,7 +1382,7 @@ complete_cb(void *baton,
   svn_error_t *err;
 
   /* Drive the tree we've created. */
-  err = drive(&eb->root, eb->deditor, eb->make_abs_paths, scratch_pool);
+  err = drive_tree(&eb->root, eb->deditor, eb->make_abs_paths, scratch_pool);
   if (!err)
      err = eb->deditor->close_edit(eb->dedit_baton, scratch_pool);
   if (err)
@@ -1264,7 +1404,7 @@ abort_cb(void *baton,
      point. */
 
   /* Drive the tree we've created. */
-  err = drive(&eb->root, eb->deditor, eb->make_abs_paths, scratch_pool);
+  err = drive_tree(&eb->root, eb->deditor, eb->make_abs_paths, scratch_pool);
 
   err2 = eb->deditor->abort_edit(eb->dedit_baton, scratch_pool);
 
@@ -1373,7 +1513,7 @@ svn_editor__insert_shims(const svn_delta
 
   /* The reason this is a pointer is that we don't know the appropriate
      value until we start receiving paths.  So process_actions() sets the
-     flag, which drive() later consumes. */
+     flag, which drive_tree() later consumes. */
   svn_boolean_t *found_abs_paths = apr_palloc(result_pool,
                                               sizeof(*found_abs_paths));
 
@@ -1392,6 +1532,7 @@ svn_editor__insert_shims(const svn_delta
                             shim_callbacks->fetch_props_func,
                             shim_callbacks->fetch_props_baton,
                             start_edit_func, seb,
+                            target_revision_func, seb,
                             result_pool));
 
 #endif

Modified: 
subversion/branches/showing-merge-info/subversion/libsvn_delta/editor.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_delta/editor.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_delta/editor.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_delta/editor.c Wed 
Nov 23 16:12:52 2011
@@ -605,7 +605,8 @@ svn_editor_complete(svn_editor_t *editor
 
   err = editor->funcs.cb_complete(editor->baton, editor->scratch_pool);
 #ifdef ENABLE_ORDERING_CHECK
-  editor->finished = TRUE;
+  if (!err)
+    editor->finished = TRUE;
 #endif
   svn_pool_clear(editor->scratch_pool);
   return err;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs_fs.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs_fs.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_fs_fs/fs_fs.c Wed 
Nov 23 16:12:52 2011
@@ -5600,7 +5600,7 @@ rep_write_contents_close(void *baton)
           /* Something's wrong with the rep-sharing index.  We can continue
              without rep-sharing, but warn.
            */
-          (b->fs->warning)(b->fs->warning_baton, svn_error_root_cause(err));
+          (b->fs->warning)(b->fs->warning_baton, err);
           svn_error_clear(err);
           old_rep = NULL;
         }

Modified: 
subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/client.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/client.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/client.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_ra_svn/client.c 
Wed Nov 23 16:12:52 2011
@@ -1166,15 +1166,12 @@ static svn_error_t *ra_svn_get_dir(svn_r
 static svn_tristate_t
 optbool_to_tristate(apr_uint64_t v)
 {
-  switch (v)
-  {
-    case TRUE:
-      return svn_tristate_true;
-    case FALSE:
-      return svn_tristate_false;
-    default: /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
-      return svn_tristate_unknown;
-  }
+  if (v == TRUE)
+    return svn_tristate_true;
+  if (v == FALSE)
+    return svn_tristate_false;
+
+  return svn_tristate_unknown; /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
 }
 
 /* If REVISION is SVN_INVALID_REVNUM, no value is sent to the

Modified: subversion/branches/showing-merge-info/subversion/libsvn_subr/io.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_subr/io.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_subr/io.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_subr/io.c Wed Nov 
23 16:12:52 2011
@@ -2980,6 +2980,13 @@ svn_io_is_binary_data(const void *data, 
 {
   const unsigned char *buf = data;
 
+  if (len == 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
+    {
+      /* This is an empty UTF-8 file which only contains the UTF-8 BOM.
+       * Treat it as plain text. */
+      return FALSE;
+    }
+
   /* Right now, this function is going to be really stupid.  It's
      going to examine the block of data, and make sure that 15%
      of the bytes are such that their value is in the ranges 0x07-0x0D

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/status.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/status.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/status.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/status.c Wed 
Nov 23 16:12:52 2011
@@ -2455,6 +2455,7 @@ svn_wc_get_status_editor5(const svn_delt
   struct edit_baton *eb;
   svn_delta_editor_t *tree_editor = svn_delta_default_editor(result_pool);
   void *inner_baton;
+  struct svn_wc__shim_fetch_baton_t *sfb;
   const svn_delta_editor_t *inner_editor;
   svn_delta_shim_callbacks_t *shim_callbacks =
                                 svn_delta_shim_callbacks_default(result_pool);
@@ -2545,6 +2546,15 @@ svn_wc_get_status_editor5(const svn_delt
   if (set_locks_baton)
     *set_locks_baton = eb;
 
+  sfb = apr_palloc(result_pool, sizeof(*sfb));
+  sfb->db = wc_ctx->db;
+  sfb->base_abspath = eb->target_abspath;
+
+  shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
+  shim_callbacks->fetch_kind_baton = sfb;
+  shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;
+  shim_callbacks->fetch_props_baton = sfb;
+
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
                                    shim_callbacks,
                                    result_pool, scratch_pool));

Modified: 
subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c 
Wed Nov 23 16:12:52 2011
@@ -4719,55 +4719,6 @@ close_edit(void *edit_baton,
 
 /*** Returning editors. ***/
 
-struct fetch_baton
-{
-  svn_wc__db_t *db;
-  const char *target_abspath;
-};
-
-static svn_error_t *
-fetch_props_func(apr_hash_t **props,
-                 void *baton,
-                 const char *path,
-                 apr_pool_t *result_pool,
-                 apr_pool_t *scratch_pool)
-{
-  struct fetch_baton *fpb = baton;
-  const char *local_abspath = svn_dirent_join(fpb->target_abspath, path,
-                                              scratch_pool);
-  svn_error_t *err;
-
-  err = svn_wc__db_read_props(props, fpb->db, local_abspath,
-                              result_pool, scratch_pool);
-
-  /* If the path doesn't exist, just return an empty set of props. */
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-    {
-      svn_error_clear(err);
-      *props = apr_hash_make(result_pool);
-    }
-  else if (err)
-    return svn_error_trace(err);
-
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-fetch_kind_func(svn_kind_t *kind,
-                void *baton,
-                const char *path,
-                apr_pool_t *scratch_pool)
-{
-  struct fetch_baton *fpb = baton;
-  const char *local_abspath = svn_dirent_join(fpb->target_abspath, path,
-                                              scratch_pool);
-
-  SVN_ERR(svn_wc__db_read_kind(kind, fpb->db, local_abspath, FALSE,
-                               scratch_pool));
-  
-  return SVN_NO_ERROR;
-}
-
 /* Helper for the three public editor-supplying functions. */
 static svn_error_t *
 make_editor(svn_revnum_t *target_revision,
@@ -4805,7 +4756,7 @@ make_editor(svn_revnum_t *target_revisio
   svn_delta_editor_t *tree_editor = svn_delta_default_editor(edit_pool);
   const svn_delta_editor_t *inner_editor;
   const char *repos_root, *repos_uuid;
-  struct fetch_baton *fpb;
+  struct svn_wc__shim_fetch_baton_t *sfb;
   svn_delta_shim_callbacks_t *shim_callbacks =
                                 svn_delta_shim_callbacks_default(edit_pool);
 
@@ -5035,14 +4986,14 @@ make_editor(svn_revnum_t *target_revisio
                                             edit_baton,
                                             result_pool));
 
-  fpb = apr_palloc(result_pool, sizeof(*fpb));
-  fpb->db = db;
-  fpb->target_abspath = eb->target_abspath;
-
-  shim_callbacks->fetch_kind_func = fetch_kind_func;
-  shim_callbacks->fetch_kind_baton = fpb;
-  shim_callbacks->fetch_props_func = fetch_props_func;
-  shim_callbacks->fetch_props_baton = fpb;
+  sfb = apr_palloc(result_pool, sizeof(*sfb));
+  sfb->db = db;
+  sfb->base_abspath = eb->target_abspath;
+
+  shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
+  shim_callbacks->fetch_kind_baton = sfb;
+  shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;
+  shim_callbacks->fetch_props_baton = sfb;
 
   SVN_ERR(svn_editor__insert_shims(editor, edit_baton, *editor, *edit_baton,
                                    shim_callbacks, result_pool, scratch_pool));

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c Wed Nov 
23 16:12:52 2011
@@ -533,3 +533,48 @@ svn_wc__status2_from_3(svn_wc_status2_t 
 
   return SVN_NO_ERROR;
 }
+
+
+svn_error_t *
+svn_wc__fetch_kind_func(svn_kind_t *kind,
+                        void *baton,
+                        const char *path,
+                        apr_pool_t *scratch_pool)
+{
+  struct svn_wc__shim_fetch_baton_t *sfb = baton;
+  const char *local_abspath = svn_dirent_join(sfb->base_abspath, path,
+                                              scratch_pool);
+
+  SVN_ERR(svn_wc__db_read_kind(kind, sfb->db, local_abspath, FALSE,
+                               scratch_pool));
+  
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__fetch_props_func(apr_hash_t **props,
+                         void *baton,
+                         const char *path,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  struct svn_wc__shim_fetch_baton_t *sfb = baton;
+  const char *local_abspath = svn_dirent_join(sfb->base_abspath, path,
+                                              scratch_pool);
+  svn_error_t *err;
+
+  err = svn_wc__db_read_props(props, sfb->db, local_abspath,
+                              result_pool, scratch_pool);
+
+  /* If the path doesn't exist, just return an empty set of props. */
+  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      *props = apr_hash_make(result_pool);
+    }
+  else if (err)
+    return svn_error_trace(err);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h Wed Nov 23 
16:12:52 2011
@@ -724,6 +724,30 @@ svn_wc__perform_file_merge(svn_skel_t **
                            apr_pool_t *scratch_pool);
 
 
+/* Couple of random helpers for the Ev2 shims.
+   ### These will eventually be obsoleted and removed. */
+struct svn_wc__shim_fetch_baton_t
+{
+  svn_wc__db_t *db;
+  const char *base_abspath;
+};
+
+/* Using a BATON of struct shim_fetch_baton, return KIND for PATH. */
+svn_error_t *
+svn_wc__fetch_kind_func(svn_kind_t *kind,
+                        void *baton,
+                        const char *path,
+                        apr_pool_t *scratch_pool);
+
+/* Using a BATON of struct shim_fetch_baton, return PROPS for PATH. */
+svn_error_t *
+svn_wc__fetch_props_func(apr_hash_t **props,
+                         void *baton,
+                         const char *path,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: 
subversion/branches/showing-merge-info/subversion/mod_dav_svn/mod_dav_svn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/mod_dav_svn/mod_dav_svn.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/mod_dav_svn/mod_dav_svn.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/mod_dav_svn/mod_dav_svn.c 
Wed Nov 23 16:12:52 2011
@@ -215,8 +215,15 @@ merge_dir_config(apr_pool_t *p, void *ba
   newconf->list_parentpath = INHERIT_VALUE(parent, child, list_parentpath);
   newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
   newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
-  /* Prefer our parent's value over our new one - hence the swap. */
-  newconf->root_dir = INHERIT_VALUE(child, parent, root_dir);
+  newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
+
+  if (parent->fs_path)
+    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
+                 "mod_dav_svn: nested Location '%s' hinders access to '%s' "
+                 "in SVNPath Location '%s'",
+                 child->root_dir,
+                 svn_urlpath__skip_ancestor(parent->root_dir, child->root_dir),
+                 parent->root_dir);
 
   return newconf;
 }

Modified: subversion/branches/showing-merge-info/subversion/mod_dav_svn/repos.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/mod_dav_svn/repos.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/mod_dav_svn/repos.c 
(original)
+++ subversion/branches/showing-merge-info/subversion/mod_dav_svn/repos.c Wed 
Nov 23 16:12:52 2011
@@ -1161,6 +1161,7 @@ create_private_resource(const dav_resour
 static void log_warning(void *baton, svn_error_t *err)
 {
   request_rec *r = baton;
+  const char *continuation = "";
 
   /* ### hmm. the FS is cleaned up at request cleanup time. "r" might
      ### not really be valid. we should probably put the FS into a
@@ -1170,7 +1171,15 @@ static void log_warning(void *baton, svn
      ### of our functions ... ??
   */
 
-  ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, "%s", err->message);
+  /* Not showing file/line so no point in tracing */
+  err = svn_error_purge_tracing(err);
+  while (err)
+    {
+      ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, "%s%s",
+                    continuation, err->message);
+      continuation = "-";
+      err = err->child;
+    }
 }
 
 

Modified: subversion/branches/showing-merge-info/subversion/svn/status.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/status.c?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/status.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/status.c Wed Nov 23 
16:12:52 2011
@@ -548,9 +548,31 @@ svn_cl__print_status(const char *cwd_abs
           && status->repos_node_status == svn_wc_status_none))
     return SVN_NO_ERROR;
 
-  if (suppress_externals_placeholders
-      && status->node_status == svn_wc_status_external)
-    return SVN_NO_ERROR;
+  /* If we're trying not to print boring "X  /path/to/external"
+     lines..." */
+  if (suppress_externals_placeholders)
+    {
+      /* ... skip regular externals unmodified in the repository. */
+      if ((status->node_status == svn_wc_status_external)
+          && (status->repos_node_status == svn_wc_status_none)
+          && (! status->conflicted))
+        return SVN_NO_ERROR;
+
+      /* ... skip file externals that aren't modified locally or
+         remotely, changelisted, or locked (in either sense of the
+         word). */
+      if ((status->file_external)
+          && (status->repos_node_status == svn_wc_status_none)
+          && ((status->node_status == svn_wc_status_normal)
+              || (status->node_status == svn_wc_status_none))
+          && ((status->prop_status == svn_wc_status_normal)
+              || (status->prop_status == svn_wc_status_none))
+          && (! status->changelist)
+          && (! status->lock)
+          && (! status->wc_is_locked)
+          && (! status->conflicted))
+        return SVN_NO_ERROR;
+    }
 
   return print_status(cwd_abspath, svn_dirent_local_style(path, pool),
                       detailed, show_last_committed, repos_locks, status,

Modified: 
subversion/branches/showing-merge-info/subversion/tests/cmdline/mergeinfo_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/mergeinfo_tests.py?rev=1205472&r1=1205471&r2=1205472&view=diff
==============================================================================
--- 
subversion/branches/showing-merge-info/subversion/tests/cmdline/mergeinfo_tests.py
 (original)
+++ 
subversion/branches/showing-merge-info/subversion/tests/cmdline/mergeinfo_tests.py
 Wed Nov 23 16:12:52 2011
@@ -685,7 +685,6 @@ def natural_history_is_not_eligible_nor_
 # A test for issue 4050 "'svn mergeinfo' always considers non-inheritable
 # ranges as partially merged".
 @Issue(4050)
-@XFail()
 @SkipUnless(server_has_mergeinfo)
 def noninheritabled_mergeinfo_not_always_eligible(sbox):
   "noninheritabled mergeinfo not always eligible"
@@ -695,11 +694,11 @@ def noninheritabled_mergeinfo_not_always
 
   A_path      = os.path.join(wc_dir, 'A')
   branch_path = os.path.join(wc_dir, 'branch')
-  
+
   # r2 - Branch ^/A to ^/branch.
   svntest.main.run_svn(None, 'copy', sbox.repo_url + '/A',
                        sbox.repo_url + '/branch', '-m', 'make a branch')
-  
+
   # r3 - Make prop edit to A.
   svntest.main.run_svn(None, 'ps', 'prop', 'val', A_path)
   svntest.main.run_svn(None, 'commit', '-m', 'file edit', wc_dir)
@@ -711,11 +710,15 @@ def noninheritabled_mergeinfo_not_always
                                      '-c3', '--depth=empty')
   svntest.main.run_svn(None, 'commit', '-m', 'shallow merge', wc_dir)
 
+  # A sanity check that we really have non-inheritable mergeinfo.
+  # If issue #4057 is ever fixed then the above merge will record
+  # inheritable mergeinfo and this test will spuriously pass.
+  svntest.actions.run_and_verify_svn(None, ["/A:3*\n"], [],
+                                     'propget', SVN_PROP_MERGEINFO,
+                                     branch_path)
+
   # Now check that r3 is reported as fully merged from ^/A to ^/branch
   # and does not show up all when asking for eligible revs.
-  #
-  # Currently this fails because r3 shows up as partially merged, even
-  # though it is fully merged to ^/branch.
   svntest.actions.run_and_verify_mergeinfo(
     adjust_error_for_server_version(''),
     ['3'], sbox.repo_url + '/A', sbox.repo_url + '/branch',


Reply via email to