diff options
| author | Peter Wemm <peter@FreeBSD.org> | 2015-10-12 08:54:49 +0000 | 
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 2015-10-12 08:54:49 +0000 | 
| commit | dc5d469d6574e9fb03bdd793658bb371315b306a (patch) | |
| tree | 013c2e6845398e5a9ca4901dcc077769c7520e1d /subversion/libsvn_client/commit_util.c | |
| parent | 58218291fa73a17020ef0447398e9e8a78f9e8c7 (diff) | |
Diffstat (limited to 'subversion/libsvn_client/commit_util.c')
| -rw-r--r-- | subversion/libsvn_client/commit_util.c | 87 | 
1 files changed, 64 insertions, 23 deletions
| diff --git a/subversion/libsvn_client/commit_util.c b/subversion/libsvn_client/commit_util.c index a32ec5d3ef80..1f3d87783436 100644 --- a/subversion/libsvn_client/commit_util.c +++ b/subversion/libsvn_client/commit_util.c @@ -40,11 +40,11 @@  #include "svn_hash.h"  #include <assert.h> -#include <stdlib.h>  /* for qsort() */  #include "svn_private_config.h"  #include "private/svn_wc_private.h"  #include "private/svn_client_private.h" +#include "private/svn_sorts_private.h"  /*** Uncomment this to turn on commit driver debugging. ***/  /* @@ -62,10 +62,12 @@ fixup_commit_error(const char *local_abspath,                     apr_pool_t *scratch_pool)  {    if (err->apr_err == SVN_ERR_FS_NOT_FOUND +      || err->apr_err == SVN_ERR_FS_CONFLICT        || err->apr_err == SVN_ERR_FS_ALREADY_EXISTS        || err->apr_err == SVN_ERR_FS_TXN_OUT_OF_DATE        || err->apr_err == SVN_ERR_RA_DAV_PATH_NOT_FOUND        || err->apr_err == SVN_ERR_RA_DAV_ALREADY_EXISTS +      || err->apr_err == SVN_ERR_RA_DAV_PRECONDITION_FAILED        || svn_error_find_cause(err, SVN_ERR_RA_OUT_OF_DATE))      {        if (ctx->notify_func2) @@ -102,6 +104,7 @@ fixup_commit_error(const char *local_abspath,      }    else if (svn_error_find_cause(err, SVN_ERR_FS_NO_LOCK_TOKEN)             || err->apr_err == SVN_ERR_FS_LOCK_OWNER_MISMATCH +           || err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN             || err->apr_err == SVN_ERR_RA_NOT_LOCKED)      {        if (ctx->notify_func2) @@ -464,10 +467,12 @@ harvest_not_present_for_copy(svn_wc_context_t *wc_ctx,    apr_pool_t *iterpool = svn_pool_create(scratch_pool);    int i; +  SVN_ERR_ASSERT(commit_relpath != NULL); +    /* A function to retrieve not present children would be nice to have */ -  SVN_ERR(svn_wc__node_get_children_of_working_node( -                                    &children, wc_ctx, local_abspath, TRUE, -                                    scratch_pool, iterpool)); +  SVN_ERR(svn_wc__node_get_not_present_children(&children, wc_ctx, +                                                local_abspath, +                                                scratch_pool, iterpool));    for (i = 0; i < children->nelts; i++)      { @@ -483,13 +488,10 @@ harvest_not_present_for_copy(svn_wc_context_t *wc_ctx,                                            this_abspath, FALSE, scratch_pool));        if (!not_present) -        continue; +        continue; /* Node is replaced */ -      if (commit_relpath == NULL) -        this_commit_relpath = NULL; -      else -        this_commit_relpath = svn_relpath_join(commit_relpath, name, -                                              iterpool); +      this_commit_relpath = svn_relpath_join(commit_relpath, name, +                                             iterpool);        /* We should check if we should really add a delete operation */        if (check_url_func) @@ -502,7 +504,7 @@ harvest_not_present_for_copy(svn_wc_context_t *wc_ctx,            /* Determine from what parent we would be the deleted child */            SVN_ERR(svn_wc__node_get_origin(                                NULL, &parent_rev, &parent_repos_relpath, -                              &parent_repos_root_url, NULL, NULL, +                              &parent_repos_root_url, NULL, NULL, NULL,                                wc_ctx,                                svn_dirent_dirname(this_abspath,                                                    scratch_pool), @@ -768,13 +770,14 @@ harvest_status_callback(void *status_baton,             && !(state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE))      {        svn_revnum_t dir_rev = SVN_INVALID_REVNUM; +      const char *dir_repos_relpath = NULL; -      if (!copy_mode_root && !status->switched && !is_added) -        SVN_ERR(svn_wc__node_get_base(NULL, &dir_rev, NULL, NULL, NULL, NULL, +      if (!copy_mode_root && !is_added) +        SVN_ERR(svn_wc__node_get_base(NULL, &dir_rev, &dir_repos_relpath, NULL, +                                      NULL, NULL,                                        wc_ctx, svn_dirent_dirname(local_abspath,                                                                   scratch_pool),                                        FALSE /* ignore_enoent */, -                                      FALSE /* show_hidden */,                                        scratch_pool, scratch_pool));        if (copy_mode_root || status->switched || node_rev != dir_rev) @@ -794,6 +797,25 @@ harvest_status_callback(void *status_baton,                cf_rev = status->revision;                cf_relpath = status->repos_relpath;              } + +          if (!copy_mode_root && !is_added && baton->check_url_func +              && dir_repos_relpath) +            { +              svn_node_kind_t me_kind; +              /* Maybe we need to issue an delete (mixed rev/switched) */ + +              SVN_ERR(baton->check_url_func( +                            baton->check_url_baton, &me_kind, +                            svn_path_url_add_component2(repos_root_url, +                                        svn_relpath_join(dir_repos_relpath, +                                            svn_dirent_basename(local_abspath, +                                                                NULL), +                                            scratch_pool), +                                        scratch_pool), +                                        dir_rev, scratch_pool)); +              if (me_kind != svn_node_none) +                state_flags |= SVN_CLIENT_COMMIT_ITEM_DELETE; +            }          }      } @@ -919,7 +941,7 @@ harvest_status_callback(void *status_baton,             * directory. In either case, we require the op-root of the parent             * to be part of the commit. See issue #4059. */            SVN_ERR(svn_wc__node_get_origin(&parent_is_copy, NULL, NULL, NULL, -                                          NULL, ©_root_abspath, +                                          NULL, NULL, ©_root_abspath,                                            wc_ctx, parent_abspath,                                            FALSE, scratch_pool, scratch_pool)); @@ -1233,13 +1255,13 @@ svn_client__harvest_committables(svn_client__committables_t **committables,    /* Make sure that every path in danglers is part of the commit. */    for (hi = apr_hash_first(scratch_pool, danglers); hi; hi = apr_hash_next(hi))      { -      const char *dangling_parent = svn__apr_hash_index_key(hi); +      const char *dangling_parent = apr_hash_this_key(hi);        svn_pool_clear(iterpool);        if (! look_up_committable(*committables, dangling_parent, iterpool))          { -          const char *dangling_child = svn__apr_hash_index_val(hi); +          const char *dangling_child = apr_hash_this_val(hi);            if (ctx->notify_func2 != NULL)              { @@ -1357,7 +1379,10 @@ svn_client__get_copy_committables(svn_client__committables_t **committables,  } -int svn_client__sort_commit_item_urls(const void *a, const void *b) +/* A svn_sort__array()/qsort()-compatible sort routine for sorting +   an array of svn_client_commit_item_t *'s by their URL member. */ +static int +sort_commit_item_urls(const void *a, const void *b)  {    const svn_client_commit_item3_t *item1      = *((const svn_client_commit_item3_t * const *) a); @@ -1381,8 +1406,7 @@ svn_client__condense_commit_items(const char **base_url,    SVN_ERR_ASSERT(ci && ci->nelts);    /* Sort our commit items by their URLs. */ -  qsort(ci->elts, ci->nelts, -        ci->elt_size, svn_client__sort_commit_item_urls); +  svn_sort__array(ci, sort_commit_item_urls);    /* Loop through the URLs, finding the longest usable ancestor common       to all of them, and making sure there are no duplicate URLs.  */ @@ -1470,6 +1494,7 @@ struct file_mod_t  {    const svn_client_commit_item3_t *item;    void *file_baton; +  apr_pool_t *file_pool;  }; @@ -1535,6 +1560,9 @@ do_item_commit(void **dir_baton,    else      file_pool = pool; +  /* Subpools are cheap, but memory isn't */ +  file_pool = svn_pool_create(file_pool); +    /* Call the cancellation function. */    if (ctx->cancel_func)      SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); @@ -1618,11 +1646,12 @@ do_item_commit(void **dir_baton,        else          notify = NULL; +        if (notify)          {            notify->kind = item->kind;            notify->path_prefix = icb->notify_path_prefix; -          (*ctx->notify_func2)(ctx->notify_baton2, notify, pool); +          ctx->notify_func2(ctx->notify_baton2, notify, pool);          }      } @@ -1783,6 +1812,7 @@ do_item_commit(void **dir_baton,        /* Add this file mod to the FILE_MODS hash. */        mod->item = item;        mod->file_baton = file_baton; +      mod->file_pool = file_pool;        svn_hash_sets(file_mods, item->session_relpath, mod);      }    else if (file_baton) @@ -1790,7 +1820,7 @@ do_item_commit(void **dir_baton,        /* Close any outstanding file batons that didn't get caught by           the "has local mods" conditional above. */        err = editor->close_file(file_baton, NULL, file_pool); - +      svn_pool_destroy(file_pool);        if (err)          goto fixup_error;      } @@ -1858,7 +1888,7 @@ svn_client__do_commit(const char *base_url,         hi;         hi = apr_hash_next(hi))      { -      struct file_mod_t *mod = svn__apr_hash_index_val(hi); +      struct file_mod_t *mod = apr_hash_this_val(hi);        const svn_client_commit_item3_t *item = mod->item;        const svn_checksum_t *new_text_base_md5_checksum;        const svn_checksum_t *new_text_base_sha1_checksum; @@ -1905,6 +1935,17 @@ svn_client__do_commit(const char *base_url,        if (sha1_checksums)          svn_hash_sets(*sha1_checksums, item->path, new_text_base_sha1_checksum); + +      svn_pool_destroy(mod->file_pool); +    } + +  if (ctx->notify_func2) +    { +      svn_wc_notify_t *notify; +      notify = svn_wc_create_notify_url(base_url, +                                        svn_wc_notify_commit_finalizing, +                                        iterpool); +      ctx->notify_func2(ctx->notify_baton2, notify, iterpool);      }    svn_pool_destroy(iterpool); | 
