Hi!

Questions
-------------
* Is it sane to add a svn_wc_notify_failed_prop_patch action for this
  special case? We're starting to have a lot of actions.

* What is wrong with the way I handle the error? I hit err_abort() when
  the program terminates. (I'm expecting the answer to hurt a bit - this
  is surely something that I should have understood by now). I thought
  that since the error is allocated on the heap I could just store the
  pointer to it and free it later, e.g. call svn_error_clear().

[[[
Print a warning instead of error out if a property could not be set on a
path with 'svn patch'.

* subversion/svn/notify.c
  (notify): Add svn_wc_notify_failed_prop_patch case.

* subversion/include/svn_wc.h
  (svn_wc_notify_action_t): Add svn_wc_notify_failed_prop_patch field.
  (svn_wc_notify_t): Update doc string for 'err' field to mention that
    it is set for svn_wc_notify_failed_prop_patch.

* subversion/libsvn_client/patch.c
  (prop_patch_target_t): Add 'was_rejected' and 'err' field to record
    failed property patches.
  (send_patch_notification): Send svn_wc_notify_failed_prop_patch
    notifications.
  (install_patched_prop_targets): Record failed propsets.
]]]

Daniel
Index: subversion/svn/notify.c
===================================================================
--- subversion/svn/notify.c     (revision 1001829)
+++ subversion/svn/notify.c     (arbetskopia)
@@ -464,6 +464,16 @@ notify(void *baton, const svn_wc_notify_t *n, apr_
         goto print_error;
       break;
 
+    case svn_wc_notify_failed_prop_patch:
+      nb->received_some_change = TRUE;
+      err = svn_cmdline_printf(pool,
+                               _("property '%s' rejected from '%s'.\n"),
+                               n->prop_name, path_local);
+      svn_handle_warning2(stderr, n->err, "svn: ");
+      if (err)
+        goto print_error;
+      break;
+
     case svn_wc_notify_update_update:
     case svn_wc_notify_merge_record_info:
       {
Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h (revision 1001829)
+++ subversion/include/svn_wc.h (arbetskopia)
@@ -1089,8 +1089,11 @@ typedef enum svn_wc_notify_action_t
   /** The server has instructed the client to follow a URL
    * redirection.
    * @since New in 1.7. */
-  svn_wc_notify_url_redirect
+  svn_wc_notify_url_redirect,
 
+  /** A hunk from a patch could not be applied. */
+  svn_wc_notify_failed_prop_patch
+
 } svn_wc_notify_action_t;
 
 
@@ -1198,7 +1201,8 @@ typedef struct svn_wc_notify_t {
 
   /** Points to an error describing the reason for the failure when @c
    * action is one of the following: #svn_wc_notify_failed_lock,
-   * #svn_wc_notify_failed_unlock, #svn_wc_notify_failed_external.
+   * #svn_wc_notify_failed_unlock, #svn_wc_notify_failed_external,
+   * #svn_wc_notify_failed_prop_patch.
    * Is @c NULL otherwise. */
   svn_error_t *err;
 
Index: subversion/libsvn_client/patch.c
===================================================================
--- subversion/libsvn_client/patch.c    (revision 1001829)
+++ subversion/libsvn_client/patch.c    (arbetskopia)
@@ -130,6 +130,12 @@ typedef struct prop_patch_target_t {
 
   /* ### Here we'll add flags telling if the prop was added, deleted,
    * ### had_rejects, had_local_mods prior to patching and so on. */
+
+  /* TRUE if the property could not be set on the path. */
+  svn_boolean_t was_rejected;
+
+  /* Set if was_rejected is TRUE. */
+  svn_error_t *err;
 } prop_patch_target_t;
 
 typedef struct patch_target_t {
@@ -1573,6 +1579,22 @@ send_patch_notification(const patch_target_t *targ
           
           prop_target = svn__apr_hash_index_val(hash_index);
 
+          if (prop_target->was_rejected)
+            {
+              svn_wc_notify_t *notify;
+              svn_wc_notify_action_t action = svn_wc_notify_failed_prop_patch;
+
+              notify = svn_wc_create_notify(target->local_abspath 
+                                            ? target->local_abspath
+                                            : target->local_relpath,
+                                            action, pool);
+              notify->prop_name = prop_target->name;
+              notify->err = prop_target->err;
+
+              (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);
+              svn_error_clear(prop_target->err);
+            }
+
           for (i = 0; i < prop_target->content_info->hunks->nelts; i++)
             {
               const hunk_info_t *hi;
@@ -2189,6 +2211,7 @@ install_patched_prop_targets(patch_target_t *targe
       svn_stringbuf_t *prop_content;
       const char *eol_str;
       svn_boolean_t eof;
+      svn_error_t *err;
 
       svn_pool_clear(iterpool);
 
@@ -2260,14 +2283,23 @@ install_patched_prop_targets(patch_target_t *targe
        * ### stsp: I'd say reject the property hunk.
        * ###       We should verify all modified prop hunk texts using
        * ###       svn_wc_canonicalize_svn_prop() before starting the
-       * ###       patching process, to reject them as early as possible. */
-      SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
-                               prop_target->name,
-                               svn_string_create_from_buf(prop_content, 
-                                                          iterpool),
-                               TRUE /* skip_checks */,
-                               NULL, NULL,
-                               iterpool));
+       * ###       patching process, to reject them as early as possible. 
+       *
+       * ### dannas: Unfortunately we need the prop_content to run
+       * ### svn_wc_canonicalize_svn_prop() and we don't have that 
+       * ### until we've applied our text changes. */
+      err = svn_wc_prop_set4(ctx->wc_ctx, target->local_abspath,
+                             prop_target->name,
+                             svn_string_create_from_buf(prop_content, 
+                                                        iterpool),
+                             TRUE /* skip_checks */,
+                             NULL, NULL,
+                             iterpool);
+      if (err)
+        {
+          prop_target->was_rejected = TRUE;
+          prop_target->err = err;
+        }
     }
 
   svn_pool_destroy(iterpool);

Reply via email to