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

📄 commit.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Recursively import PATH to a repository using EDITOR and * EDIT_BATON.  PATH can be a file or directory. *  * NEW_ENTRIES is an ordered array of path components that must be * created in the repository (where the ordering direction is * parent-to-child).  If PATH is a directory, NEW_ENTRIES may be empty * -- the result is an import which creates as many new entries in the * top repository target directory as there are importable entries in * the top of PATH; but if NEW_ENTRIES is not empty, its last item is * the name of a new subdirectory in the repository to hold the * import.  If PATH is a file, NEW_ENTRIES may not be empty, and its * last item is the name used for the file in the repository.  If * NEW_ENTRIES contains more than one item, all but the last item are * the names of intermediate directories that are created before the * real import begins.  NEW_ENTRIES may NOT be NULL. *  * EXCLUDES is a hash whose keys are absolute paths to exclude from * the import (values are unused). * * If NO_IGNORE is FALSE, don't import files or directories that match * ignore patterns. * * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for  * each imported path, passing actions svn_wc_notify_commit_added. * * Use POOL for any temporary allocation. * * Note: the repository directory receiving the import was specified * when the editor was fetched.  (I.e, when EDITOR->open_root() is * called, it returns a directory baton for that directory, which is * not necessarily the root.) */static svn_error_t *import(const char *path,       apr_array_header_t *new_entries,       const svn_delta_editor_t *editor,       void *edit_baton,       svn_boolean_t nonrecursive,       apr_hash_t *excludes,       svn_boolean_t no_ignore,       svn_client_ctx_t *ctx,       apr_pool_t *pool){  void *root_baton;  svn_node_kind_t kind;  apr_array_header_t *ignores;  apr_array_header_t *batons = NULL;  const char *edit_path = "";  import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));  /* Get a root dir baton.  We pass an invalid revnum to open_root     to mean "base this on the youngest revision".  Should we have an     SVN_YOUNGEST_REVNUM defined for these purposes? */  SVN_ERR(editor->open_root(edit_baton, SVN_INVALID_REVNUM,                             pool, &root_baton));  /* Import a file or a directory tree. */  SVN_ERR(svn_io_check_path(path, &kind, pool));  /* Make the intermediate directory components necessary for properly     rooting our import source tree.  */  if (new_entries->nelts)    {      int i;      batons = apr_array_make(pool, new_entries->nelts, sizeof(void *));      for (i = 0; i < new_entries->nelts; i++)        {          const char *component = APR_ARRAY_IDX(new_entries, i, const char *);          edit_path = svn_path_join(edit_path, component, pool);          /* If this is the last path component, and we're importing a             file, then this component is the name of the file, not an             intermediate directory. */          if ((i == new_entries->nelts - 1) && (kind == svn_node_file))            break;          *((void **) apr_array_push(batons)) = root_baton;          SVN_ERR(editor->add_directory(edit_path,                                        root_baton,                                        NULL, SVN_INVALID_REVNUM,                                        pool, &root_baton));          /* Remember that the repository was modified */          import_ctx->repos_changed = TRUE;        }    }  else if (kind == svn_node_file)    {      return svn_error_create        (SVN_ERR_NODE_UNKNOWN_KIND, NULL,         _("New entry name required when importing a file"));    }  /* Note that there is no need to check whether PATH's basename is     the same name that we reserve for our administrative     subdirectories.  It would be strange -- though not illegal -- to     import the contents of a directory of that name, because the     directory's own name is not part of those contents.  Of course,     if something underneath it also has our reserved name, then we'll     error. */  if (kind == svn_node_file)    {      svn_boolean_t ignores_match = FALSE;      if (!no_ignore)        {          SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));          ignores_match = svn_cstring_match_glob_list(path, ignores);        }      if (!ignores_match)         SVN_ERR(import_file(editor, root_baton, path, edit_path,                            import_ctx, ctx, pool));    }  else if (kind == svn_node_dir)    {      SVN_ERR(import_dir(editor, root_baton, path, edit_path,                         nonrecursive, excludes, no_ignore, import_ctx,                          ctx, pool));    }  else if (kind == svn_node_none)    {      return svn_error_createf(SVN_ERR_NODE_UNKNOWN_KIND, NULL,                                _("'%s' does not exist"),                               svn_path_local_style(path, pool));      }  /* Close up shop; it's time to go home. */  SVN_ERR(editor->close_directory(root_baton, pool));  if (batons && batons->nelts)    {      void **baton;      while ((baton = (void **) apr_array_pop(batons)))        {          SVN_ERR(editor->close_directory(*baton, pool));        }    }  if (import_ctx->repos_changed)    SVN_ERR(editor->close_edit(edit_baton, pool));  else    SVN_ERR(editor->abort_edit(edit_baton, pool));  return SVN_NO_ERROR;}static svn_error_t *get_ra_editor(svn_ra_session_t **ra_session,              svn_revnum_t *latest_rev,              const svn_delta_editor_t **editor,              void **edit_baton,              svn_client_ctx_t *ctx,              const char *base_url,              const char *base_dir,              svn_wc_adm_access_t *base_access,              const char *log_msg,              apr_array_header_t *commit_items,              svn_commit_info_t **commit_info_p,              svn_boolean_t is_commit,              apr_hash_t *lock_tokens,              svn_boolean_t keep_locks,              apr_pool_t *pool){  void *commit_baton;  /* Open an RA session to URL. */  SVN_ERR(svn_client__open_ra_session_internal(ra_session,                                               base_url, base_dir,                                               base_access, commit_items,                                               is_commit, !is_commit,                                               ctx, pool));  /* If this is an import (aka, not a commit), we need to verify that     our repository URL exists. */  if (! is_commit)    {      svn_node_kind_t kind;      SVN_ERR(svn_ra_check_path(*ra_session, "", SVN_INVALID_REVNUM,                                &kind, pool));      if (kind == svn_node_none)        return svn_error_createf(SVN_ERR_FS_NO_SUCH_ENTRY, NULL,                                 _("Path '%s' does not exist"),                                 base_url);    }  /* Fetch the latest revision if requested. */  if (latest_rev)    SVN_ERR(svn_ra_get_latest_revnum(*ra_session, latest_rev, pool));    /* Fetch RA commit editor. */  SVN_ERR(svn_client__commit_get_baton(&commit_baton, commit_info_p, pool));  return svn_ra_get_commit_editor2(*ra_session, editor, edit_baton, log_msg,                                   svn_client__commit_callback,                                   commit_baton, lock_tokens, keep_locks,                                   pool);}/*** Public Interfaces. ***/svn_error_t *svn_client_import2(svn_commit_info_t **commit_info_p,                   const char *path,                   const char *url,                   svn_boolean_t nonrecursive,                   svn_boolean_t no_ignore,                   svn_client_ctx_t *ctx,                   apr_pool_t *pool){  svn_error_t *err = SVN_NO_ERROR;  const char *log_msg = "";  const svn_delta_editor_t *editor;  void *edit_baton;  svn_ra_session_t *ra_session;  apr_hash_t *excludes = apr_hash_make(pool);  svn_node_kind_t kind;  const char *base_dir = path;  apr_array_header_t *new_entries = apr_array_make(pool, 4,                                                    sizeof(const char *));  const char *temp;  const char *dir;  apr_pool_t *subpool;  /* Create a new commit item and add it to the array. */  if (ctx->log_msg_func || ctx->log_msg_func2)    {      /* If there's a log message gatherer, create a temporary commit         item array solely to help generate the log message.  The         array is not used for the import itself. */      svn_client_commit_item2_t *item;      const char *tmp_file;      apr_array_header_t *commit_items         = apr_array_make(pool, 1, sizeof(item));            item = apr_pcalloc(pool, sizeof(*item));      item->path = apr_pstrdup(pool, path);      item->state_flags = SVN_CLIENT_COMMIT_ITEM_ADD;      APR_ARRAY_PUSH(commit_items, svn_client_commit_item2_t *) = item;            SVN_ERR(svn_client__get_log_msg(&log_msg, &tmp_file, commit_items,                                      ctx, pool));      if (! log_msg)        return SVN_NO_ERROR;      if (tmp_file)        {          const char *abs_path;          SVN_ERR(svn_path_get_absolute(&abs_path, tmp_file, pool));          apr_hash_set(excludes, abs_path, APR_HASH_KEY_STRING, (void *)1);        }    }  SVN_ERR(svn_io_check_path(path, &kind, pool));  if (kind == svn_node_file)    svn_path_split(path, &base_dir, NULL, pool);  /* Figure out all the path components we need to create just to have     a place to stick our imported tree. */  subpool = svn_pool_create(pool);  do    {      svn_pool_clear(subpool);      /* See if the user is interested in cancelling this operation. */      if (ctx->cancel_func)        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));      if (err)        {          /* If get_ra_editor below failed we either tried to open             an invalid url, or else some other kind of error.  In case             the url was bad we back up a directory and try again. */                    if (err->apr_err != SVN_ERR_FS_NO_SUCH_ENTRY)            return err;          else            svn_error_clear(err);                    svn_path_split(url, &temp, &dir, pool);          *((const char **) apr_array_push(new_entries)) =             svn_path_uri_decode(dir, pool);          url = temp;        }    }  while ((err = get_ra_editor(&ra_session, NULL,                              &editor, &edit_baton, ctx, url, base_dir,                              NULL, log_msg, NULL, commit_info_p,                              FALSE, NULL, TRUE, subpool)));  /* Reverse the order of the components we added to our NEW_ENTRIES array. */  if (new_entries->nelts)    {      int i, j;      const char *component;      for (i = 0; i < (new_entries->nelts / 2); i++)        {          j = new_entries->nelts - i - 1;          component =             APR_ARRAY_IDX(new_entries, i, const char *);          APR_ARRAY_IDX(new_entries, i, const char *) =            APR_ARRAY_IDX(new_entries, j, const char *);          APR_ARRAY_IDX(new_entries, j, const char *) =             component;        }    }    /* An empty NEW_ENTRIES list the first call to get_ra_editor() above     succeeded.  That means that URL corresponds to an already     existing filesystem entity. */  if (kind == svn_node_file && (! new_entries->nelts))    return svn_error_createf      (SVN_ERR_ENTRY_EXISTS, NULL,       _("Path '%s' already exists"), url);  /* The repository doesn't know about the reserved administrative     directory. */  if (new_entries->nelts      /* What's this, what's this?  This assignment is here because we         use the value to construct the error message just below.  It         may not be asethetically pleasing, but it's less ugly than         calling APR_ARRAY_IDX twice. */      && svn_wc_is_adm_dir(temp = APR_ARRAY_IDX(new_entries,                                                new_entries->nelts - 1,                                                const char *),                           pool))    return svn_error_createf      (SVN_ERR_CL_ADM_DIR_RESERVED, NULL,       _("'%s' is a reserved name and cannot be imported"),       /* ### Is svn_path_local_style() really necessary for this? */       svn_path_local_style(temp, pool));  /* If an error occurred during the commit, abort the edit and return     the error.  We don't even care if the abort itself fails.  */  if ((err = import(path, new_entries, editor, edit_baton,                     nonrecursive, excludes, no_ignore, ctx, subpool)))    {      svn_error_clear(editor->abort_edit(edit_baton, subpool));      return err;    }  /* Transfer *COMMIT_INFO from the subpool to the callers pool */  if (*commit_info_p)    {      svn_commit_info_t *tmp_commit_info;      tmp_commit_info = svn_create_commit_info(pool);      *tmp_commit_info = **commit_info_p;      if (tmp_commit_info->date)        tmp_commit_info->date = apr_pstrdup(pool, tmp_commit_info->date);      if (tmp_commit_info->author)        tmp_commit_info->author = apr_pstrdup(pool, tmp_commit_info->author);      if (tmp_commit_info->post_commit_err)        tmp_commit_info->post_commit_err          = apr_pstrdup(pool, tmp_commit_info->post_commit_err);      *commit_info_p = tmp_commit_info;    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}svn_error_t *svn_client_import(svn_client_commit_info_t **commit_info_p,                  const char *path,                  const char *url,                  svn_boolean_t nonrecursive,                  svn_client_ctx_t *ctx,                  apr_pool_t *pool){  svn_commit_info_t *commit_info = NULL;  svn_error_t *err;  err = svn_client_import2(&commit_info,                           path, url, nonrecursive,                           FALSE, ctx, pool);  /* These structs have the same layout for the common fields. */  *commit_info_p = (svn_client_commit_info_t *) commit_info;  return err;}static svn_error_t *remove_tmpfiles(apr_hash_t *tempfiles,                apr_pool_t *pool){  apr_hash_index_t *hi;  apr_pool_t *subpool;  /* Split if there's nothing to be done. */  if (! tempfiles)    return SVN_NO_ERROR;  /* Make a subpool. */  subpool = svn_pool_create(pool);  /* Clean up any tempfiles. */  for (hi = apr_hash_first(pool, tempfiles); hi; hi = apr_hash_next(hi))    {      const void *key;      void *val;      svn_error_t *err;      svn_pool_clear(subpool);      apr_hash_this(hi, &key, NULL, &val);      err = svn_io_remove_file((const char *)key, subpool);      if (err)        {          if (! APR_STATUS_IS_ENOENT(err->apr_err))            return err;          else            svn_error_clear(err);

⌨️ 快捷键说明

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