⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commit_util.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* Sort our commit items by their URLs. */  qsort(ci->elts, ci->nelts,         ci->elt_size, svn_client__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.  */  for (i = 0; i < ci->nelts; i++)    {      item = APR_ARRAY_IDX(ci, i, svn_client_commit_item2_t *);      url = item->url;      if ((last_item) && (strcmp(last_item->url, url) == 0))        return svn_error_createf           (SVN_ERR_CLIENT_DUPLICATE_COMMIT_URL, NULL,           _("Cannot commit both '%s' and '%s' as they refer to the same URL"),           svn_path_local_style(item->path, pool),           svn_path_local_style(last_item->path, pool));      /* In the first iteration, our BASE_URL is just our only         encountered commit URL to date.  After that, we find the         longest ancestor between the current BASE_URL and the current         commit URL.  */      if (i == 0)        *base_url = apr_pstrdup(pool, url);      else        *base_url = svn_path_get_longest_ancestor(*base_url, url, pool);       /* If our BASE_URL is itself a to-be-committed item, and it is         anything other than an already-versioned directory with         property mods, we'll call its parent directory URL the         BASE_URL.  Why?  Because we can't have a file URL as our base         -- period -- and all other directory operations (removal,         addition, etc.) require that we open that directory's parent         dir first.  */      /* ### I don't understand the strlen()s here, hmmm.  -kff */      if ((strlen(*base_url) == strlen(url))          && (! ((item->kind == svn_node_dir)                 && item->state_flags == SVN_CLIENT_COMMIT_ITEM_PROP_MODS)))        *base_url = svn_path_dirname(*base_url, pool);      /* Stash our item here for the next iteration. */      last_item = item;    }    /* Now that we've settled on a *BASE_URL, go hack that base off     of all of our URLs. */  for (i = 0; i < ci->nelts; i++)    {      svn_client_commit_item2_t *this_item        = APR_ARRAY_IDX(ci, i, svn_client_commit_item2_t *);      int url_len = strlen(this_item->url);      int base_url_len = strlen(*base_url);      if (url_len > base_url_len)        this_item->url = apr_pstrdup(pool, this_item->url + base_url_len + 1);      else        this_item->url = "";    }#ifdef SVN_CLIENT_COMMIT_DEBUG  /* ### TEMPORARY CODE ### */  fprintf(stderr, "COMMITTABLES: (base URL=%s)\n", *base_url);  fprintf(stderr, "   FLAGS     REV  REL-URL (COPY-URL)\n");  for (i = 0; i < ci->nelts; i++)    {      svn_client_commit_item2_t *this_item        = APR_ARRAY_IDX(ci, i, svn_client_commit_item2_t *);      char flags[6];      flags[0] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)                   ? 'a' : '-';      flags[1] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)                   ? 'd' : '-';      flags[2] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)                   ? 't' : '-';      flags[3] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)                   ? 'p' : '-';      flags[4] = (this_item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)                   ? 'c' : '-';      flags[5] = '\0';      fprintf(stderr, "   %s  %6ld  '%s' (%s)\n",               flags,              this_item->revision,              this_item->url ? this_item->url : "",              this_item->copyfrom_url ? this_item->copyfrom_url : "none");    }  #endif /* SVN_CLIENT_COMMIT_DEBUG */  return SVN_NO_ERROR;}struct file_mod_t{  svn_client_commit_item2_t *item;  void *file_baton;};/* A baton for use with the path-based editor driver */struct path_driver_cb_baton{  svn_wc_adm_access_t *adm_access;     /* top-level access baton */  const svn_delta_editor_t *editor;    /* commit editor */  void *edit_baton;                    /* commit editor's baton */  apr_hash_t *file_mods;               /* hash: path->file_mod_t */  apr_hash_t *tempfiles;               /* hash of tempfiles created */  const char *notify_path_prefix;      /* notification path prefix */  svn_client_ctx_t *ctx;               /* client context baton */  apr_hash_t *commit_items;            /* the committables */};/* This implements svn_delta_path_driver_cb_func_t */static svn_error_t *do_item_commit(void **dir_baton,               void *parent_baton,               void *callback_baton,               const char *path,               apr_pool_t *pool){  struct path_driver_cb_baton *cb_baton = callback_baton;  svn_client_commit_item2_t *item = apr_hash_get(cb_baton->commit_items,                                                 path, APR_HASH_KEY_STRING);  svn_node_kind_t kind = item->kind;  void *file_baton = NULL;  const char *copyfrom_url = NULL;  apr_pool_t *file_pool = NULL;  svn_wc_adm_access_t *adm_access = cb_baton->adm_access;  const svn_delta_editor_t *editor = cb_baton->editor;  apr_hash_t *file_mods = cb_baton->file_mods;  apr_hash_t *tempfiles = cb_baton->tempfiles;  const char *notify_path_prefix = cb_baton->notify_path_prefix;  svn_client_ctx_t *ctx = cb_baton->ctx;  /* Do some initializations. */  *dir_baton = NULL;  if (item->copyfrom_url)    copyfrom_url = item->copyfrom_url;  /* If this is a file with textual mods, we'll be keeping its baton     around until the end of the commit.  So just lump its memory into     a single, big, all-the-file-batons-in-here pool.  Otherwise, we     can just use POOL, and trust our caller to clean that mess up. */  if ((kind == svn_node_file)       && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS))    file_pool = apr_hash_pool_get(file_mods);  else    file_pool = pool;  /* Call the cancellation function. */  if (ctx->cancel_func)    SVN_ERR(ctx->cancel_func(ctx->cancel_baton));  /* Validation. */  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)    {      if (! copyfrom_url)        return svn_error_createf           (SVN_ERR_BAD_URL, NULL,           _("Commit item '%s' has copy flag but no copyfrom URL"),           svn_path_local_style(path, pool));      if (! SVN_IS_VALID_REVNUM(item->copyfrom_rev))        return svn_error_createf           (SVN_ERR_CLIENT_BAD_REVISION, NULL,           _("Commit item '%s' has copy flag but an invalid revision"),           svn_path_local_style(path, pool));    }  /* If a feedback table was supplied by the application layer,     describe what we're about to do to this item.  */  if (ctx->notify_func2)    {      /* Convert an absolute path into a relative one (if possible.) */      const char *npath = NULL;      svn_wc_notify_t *notify;      if (notify_path_prefix)        {          if (strcmp(notify_path_prefix, item->path))            npath = svn_path_is_child(notify_path_prefix, item->path, pool);          else            npath = ".";        }      if (! npath)        npath = item->path; /* Otherwise just use full path */      if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)          && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD))        {          /* We don't print the "(bin)" notice for binary files when             replacing, only when adding.  So we don't bother to get             the mime-type here. */          notify = svn_wc_create_notify(npath, svn_wc_notify_commit_replaced,                                        pool);        }      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)        {          notify = svn_wc_create_notify(npath, svn_wc_notify_commit_deleted,                                        pool);        }      else if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)        {          notify = svn_wc_create_notify(npath, svn_wc_notify_commit_added,                                        pool);          if (item->kind == svn_node_file)            {              const svn_string_t *propval;              SVN_ERR(svn_wc_prop_get                      (&propval, SVN_PROP_MIME_TYPE, item->path, adm_access,                       pool));              if (propval)                notify->mime_type = propval->data;            }        }      else if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)               || (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS))        {          notify = svn_wc_create_notify(npath, svn_wc_notify_commit_modified,                                        pool);          if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS)            notify->content_state = svn_wc_notify_state_changed;          else            notify->content_state = svn_wc_notify_state_unchanged;          if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)            notify->prop_state = svn_wc_notify_state_changed;          else            notify->prop_state = svn_wc_notify_state_unchanged;        }      else        notify = NULL;      if (notify)        {          notify->kind = item->kind;          (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);        }    }  /* If this item is supposed to be deleted, do so. */  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)    {      assert(parent_baton);      SVN_ERR(editor->delete_entry(path, item->revision,                                    parent_baton, pool));    }  /* If this item is supposed to be added, do so. */  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)    {      if (kind == svn_node_file)        {          assert(parent_baton);          SVN_ERR(editor->add_file                   (path, parent_baton, copyfrom_url,                    copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,                   file_pool, &file_baton));        }      else        {          assert(parent_baton);          SVN_ERR(editor->add_directory                  (path, parent_baton, copyfrom_url,                   copyfrom_url ? item->copyfrom_rev : SVN_INVALID_REVNUM,                   pool, dir_baton));        }    }      /* Now handle property mods. */  if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_PROP_MODS)    {      const char *tempfile;      const svn_wc_entry_t *tmp_entry;      if (kind == svn_node_file)        {          if (! file_baton)            {              assert(parent_baton);              SVN_ERR(editor->open_file(path, parent_baton,                                         item->revision,                                         file_pool, &file_baton));            }        }      else        {          if (! *dir_baton)            {              if (! parent_baton)                {                  SVN_ERR(editor->open_root                          (cb_baton->edit_baton, item->revision,                           pool, dir_baton));                }              else                {                  SVN_ERR(editor->open_directory                          (path, parent_baton, item->revision,                            pool, dir_baton));                }            }        }      SVN_ERR(svn_wc_entry(&tmp_entry, item->path, adm_access, TRUE, pool));      SVN_ERR(svn_wc_transmit_prop_deltas               (item->path, adm_access, tmp_entry, editor,               (kind == svn_node_dir) ? *dir_baton : file_baton,                &tempfile, pool));      if (tempfile && tempfiles)        {          tempfile = apr_pstrdup(apr_hash_pool_get(tempfiles), tempfile);          apr_hash_set(tempfiles, tempfile, APR_HASH_KEY_STRING, (void *)1);        }    }  /* Finally, handle text mods (in that we need to open a file if it     hasn't already been opened, and we need to put the file baton in     our FILES hash). */  if ((kind == svn_node_file)       && (item->state_flags & SVN_CLIENT_COMMIT_ITEM_TEXT_MODS))    {      struct file_mod_t *mod = apr_palloc(file_pool, sizeof(*mod));      if (! file_baton)        {          assert(parent_baton);          SVN_ERR(editor->open_file(path, parent_baton,                                    item->revision,                                    file_pool, &file_baton));        }      /* Add this file mod to the FILE_MODS hash. */      mod->item = item;      mod->file_baton = file_baton;      apr_hash_set(file_mods, item->url, APR_HASH_KEY_STRING, mod);    }  else if (file_baton)    {      /* Close any outstanding file batons that didn't get caught by         the "has local mods" conditional above. */      SVN_ERR(editor->close_file(file_baton, NULL, file_pool));    }  return SVN_NO_ERROR;}#ifdef SVN_CLIENT_COMMIT_DEBUG/* Prototype for function below */static svn_error_t *get_test_editor(const svn_delta_editor_t **editor,                                    void **edit_baton,                                    const svn_delta_editor_t *real_editor,                                    void *real_eb,                                    const char *base_url,                                    apr_pool_t *pool);#endif /* SVN_CLIENT_COMMIT_DEBUG */svn_error_t *svn_client__do_commit(const char *base_url,                      apr_array_header_t *commit_items,                      svn_wc_adm_access_t *adm_access,                      const svn_delta_editor_t *editor,                      void *edit_baton,                      const char *notify_path_prefix,                      apr_hash_t **tempfiles,                      apr_hash_t **digests,                      svn_client_ctx_t *ctx,                      apr_pool_t *pool){  apr_hash_t *file_mods = apr_hash_make(pool);  apr_hash_t *items_hash = apr_hash_make(pool);  apr_pool_t *subpool = svn_pool_create(pool);  apr_hash_index_t *hi;  int i;  struct path_driver_cb_baton cb_baton;  apr_array_header_t *paths =     apr_array_make(pool, commit_items->nelts, sizeof(const char *));#ifdef SVN_CLIENT_COMMIT_DEBUG  {    SVN_ERR(get_test_editor(&editor, &edit_baton,                             editor, edit_baton,                            base_url, pool));  }#endif /* SVN_CLIENT_COMMIT_DEBUG */  /* If the caller wants us to track temporary file creation, create a     hash to store those paths in. */  if (tempfiles)    *tempfiles = apr_hash_make(pool);  /* Ditto for the md5 digests. */  if (digests)    *digests = apr_hash_make(pool);  /* Build a hash from our COMMIT_ITEMS array, keyed on the     URI-decoded relative paths (which come from the item URLs).  And     keep an array of those decoded paths, too.  */  for (i = 0; i < commit_items->nelts; i++)    {      svn_client_commit_item2_t *item =         APR_ARRAY_IDX(commit_items, i, svn_client_commit_item2_t *);      const char *path = svn_path_uri_decode(item->url, pool);      apr_hash_set(items_hash, path, APR_HASH_KEY_STRING, item);      APR_ARRAY_PUSH(paths, const char *) = path;    }  /* Setup the callback baton. */  cb_baton.adm_access = adm_access;  cb_baton.editor = editor;  cb_baton.edit_baton = edit_baton;  cb_baton.file_mods = file_mods;  cb_baton.tempfiles = tempfiles ? *tempfiles : NULL;  cb_baton.notify_path_prefix = notify_path_prefix;  cb_baton.ctx = ctx;  cb_baton.commit_items = items_hash;  /* Drive the commit editor! */  SVN_ERR(svn_delta_path_driver(editor, edit_baton, SVN_INVALID_REVNUM,                                paths, do_item_commit, &cb_baton, pool));  /* Transmit outstanding text deltas. */  for (hi = apr_hash_first(pool, file_mods); hi; hi = apr_hash_next(hi))    {      const void *key;      apr_ssize_t klen;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -