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

📄 commit.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (copy_path)    {            const char *fs_path;      svn_fs_root_t *copy_root;      svn_node_kind_t kind;      int repos_url_len;      /* Copy requires recursive write to the destination path and         parent path. */      SVN_ERR(check_authz(eb, full_path, eb->txn_root,                          svn_authz_write, subpool));      SVN_ERR(check_authz(eb, pb->path, eb->txn_root,                          svn_authz_write, subpool));      /* Check PATH in our transaction.  Make sure it does not exist         unless its parent directory was copied (in which case, the         thing might have been copied in as well), else return an         out-of-dateness error. */      SVN_ERR(svn_fs_check_path(&kind, eb->txn_root, full_path, subpool));      if ((kind != svn_node_none) && (! pb->was_copied))        return out_of_date(full_path, eb->txn_name);      /* For now, require that the url come from the same repository         that this commit is operating on. */      copy_path = svn_path_uri_decode(copy_path, subpool);      repos_url_len = strlen(eb->repos_url);      if (strncmp(copy_path, eb->repos_url, repos_url_len) != 0)            return svn_error_createf               (SVN_ERR_FS_GENERAL, NULL,               _("Source url '%s' is from different repository"), copy_path);            fs_path = apr_pstrdup(subpool, copy_path + repos_url_len);      /* Now use the "fs_path" as an absolute path within the         repository to make the copy from. */            SVN_ERR(svn_fs_revision_root(&copy_root, eb->fs,                                   copy_revision, subpool));      /* Copy also requires read access to the source */      SVN_ERR(check_authz(eb, fs_path, copy_root,                          svn_authz_read, subpool));      SVN_ERR(svn_fs_copy(copy_root, fs_path,                           eb->txn_root, full_path, subpool));    }  else    {      /* No ancestry given, just make a new, empty file.  Note that we         don't perform an existence check here like the copy-from case         does -- that's because svn_fs_make_file() already errors out         if the file already exists.  Verify write access to the full         path and to the parent. */      SVN_ERR(check_authz(eb, full_path, eb->txn_root, svn_authz_write,                          subpool));      SVN_ERR(check_authz(eb, pb->path, eb->txn_root, svn_authz_write,                          subpool));      SVN_ERR(svn_fs_make_file(eb->txn_root, full_path, subpool));    }  /* Cleanup our temporary subpool. */  svn_pool_destroy(subpool);  /* Build a new file baton */  new_fb = apr_pcalloc(pool, sizeof(*new_fb));  new_fb->edit_baton = eb;  new_fb->path = full_path;  *file_baton = new_fb;  return SVN_NO_ERROR;}static svn_error_t *open_file(const char *path,          void *parent_baton,          svn_revnum_t base_revision,          apr_pool_t *pool,          void **file_baton){  struct file_baton *new_fb;  struct dir_baton *pb = parent_baton;  struct edit_baton *eb = pb->edit_baton;  svn_revnum_t cr_rev;  apr_pool_t *subpool = svn_pool_create(pool);  const char *full_path = svn_path_join(eb->base_path, path, pool);  /* Check for read authorization. */  SVN_ERR(check_authz(eb, full_path, eb->txn_root,                      svn_authz_read, subpool));  /* Get this node's creation revision (doubles as an existence check). */  SVN_ERR(svn_fs_node_created_rev(&cr_rev, eb->txn_root, full_path,                                   subpool));    /* If the node our caller has is an older revision number than the     one in our transaction, return an out-of-dateness error. */  if (SVN_IS_VALID_REVNUM(base_revision) && (base_revision < cr_rev))    return out_of_date(full_path, eb->txn_name);  /* Build a new file baton */  new_fb = apr_pcalloc(pool, sizeof(*new_fb));  new_fb->edit_baton = eb;  new_fb->path = full_path;  *file_baton = new_fb;  /* Destory the work subpool. */  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}static svn_error_t *change_file_prop(void *file_baton,                 const char *name,                 const svn_string_t *value,                 apr_pool_t *pool){  struct file_baton *fb = file_baton;  struct edit_baton *eb = fb->edit_baton;  /* Check for write authorization. */  SVN_ERR(check_authz(eb, fb->path, eb->txn_root,                      svn_authz_write, pool));  return svn_repos_fs_change_node_prop(eb->txn_root, fb->path,                                        name, value, pool);}static svn_error_t *close_file(void *file_baton,           const char *text_checksum,           apr_pool_t *pool){  struct file_baton *fb = file_baton;  if (text_checksum)    {      unsigned char digest[APR_MD5_DIGESTSIZE];      const char *hex_digest;      SVN_ERR(svn_fs_file_md5_checksum              (digest, fb->edit_baton->txn_root, fb->path, pool));      hex_digest = svn_md5_digest_to_cstring(digest, pool);      if (hex_digest && strcmp(text_checksum, hex_digest) != 0)        {          return svn_error_createf            (SVN_ERR_CHECKSUM_MISMATCH, NULL,             _("Checksum mismatch for resulting fulltext\n"               "(%s):\n"               "   expected checksum:  %s\n"               "   actual checksum:    %s\n"),             fb->path, text_checksum, hex_digest);        }    }  return SVN_NO_ERROR;}static svn_error_t *change_dir_prop(void *dir_baton,                const char *name,                const svn_string_t *value,                apr_pool_t *pool){  struct dir_baton *db = dir_baton;  struct edit_baton *eb = db->edit_baton;  /* Check for write authorization. */  SVN_ERR(check_authz(eb, db->path, eb->txn_root,                      svn_authz_write, pool));  if (SVN_IS_VALID_REVNUM(db->base_rev))    {      /* Subversion rule:  propchanges can only happen on a directory         which is up-to-date. */      svn_revnum_t created_rev;      SVN_ERR(svn_fs_node_created_rev(&created_rev,                                      eb->txn_root, db->path, pool));      if (db->base_rev < created_rev)        return out_of_date(db->path, eb->txn_name);    }  return svn_repos_fs_change_node_prop(eb->txn_root, db->path,                                        name, value, pool);}static svn_error_t *close_edit(void *edit_baton,           apr_pool_t *pool){  struct edit_baton *eb = edit_baton;  svn_revnum_t new_revision = SVN_INVALID_REVNUM;  svn_error_t *err;  const char *conflict;  char *post_commit_err = NULL;  /* If no transaction has been created (ie. if open_root wasn't     called before close_edit), abort the operation here with an     error. */  if (! eb->txn)    return svn_error_create(SVN_ERR_REPOS_BAD_ARGS, NULL,                            "No valid transaction supplied to close_edit");  /* Commit. */  err = svn_repos_fs_commit_txn(&conflict, eb->repos,                                 &new_revision, eb->txn, pool);  /* We want to abort the transaction *unless* the error code tells us     the commit succeeded and something just went wrong in post-commit. */  if (err && (err->apr_err != SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED))    {      /* ### todo: we should check whether it really was a conflict,         and return the conflict info if so? */      /* If the commit failed, it's *probably* due to a conflict --         that is, the txn being out-of-date.  The filesystem gives us         the ability to continue diddling the transaction and try         again; but let's face it: that's not how the cvs or svn works         from a user interface standpoint.  Thus we don't make use of         this fs feature (for now, at least.)         So, in a nutshell: svn commits are an all-or-nothing deal.         Each commit creates a new fs txn which either succeeds or is         aborted completely.  No second chances;  the user simply         needs to update and commit again  :)         We ignore the possible error result from svn_fs_abort_txn();         it's more important to return the original error. */      svn_error_clear(svn_fs_abort_txn(eb->txn, pool));      return err;    }  else if (err)    {      /* Post-commit hook's failure output can be passed back to the         client. However, this cannot be a commit failure. Hence         passing back the post-commit error message as a string to         be displayed as a warning. */      if (err->child && err->child->message)        post_commit_err = apr_pstrdup(pool, err->child->message) ;        svn_error_clear(err);      err = SVN_NO_ERROR;    }    /* Pass new revision information to the caller's callback. */  {    svn_string_t *date, *author;    svn_error_t *err2;    svn_commit_info_t *commit_info;    /* Even if there was a post-commit hook failure, it's more serious       if one of the calls here fails, so we explicitly check for errors       here, while saving the possible post-commit error for later. */    err2 = svn_fs_revision_prop(&date, svn_repos_fs(eb->repos),                                new_revision, SVN_PROP_REVISION_DATE,                                pool);    if (! err2)      err2 =  svn_fs_revision_prop(&author, svn_repos_fs(eb->repos),                                   new_revision, SVN_PROP_REVISION_AUTHOR,                                   pool);    if (! err2)      {        commit_info = svn_create_commit_info(pool);        /* fill up the svn_commit_info structure */        commit_info->revision = new_revision;        commit_info->date = date ? date->data : NULL;        commit_info->author = author ? author->data : NULL;        commit_info->post_commit_err = post_commit_err;        err2 = (*eb->commit_callback)(commit_info,                                       eb->commit_callback_baton,                                      pool);        if (err2)          {            svn_error_clear(err);            return err2;          }      }  }  return err;}static svn_error_t *abort_edit(void *edit_baton,           apr_pool_t *pool){  struct edit_baton *eb = edit_baton;  if ((! eb->txn) || (! eb->txn_owner))    return SVN_NO_ERROR;  return svn_fs_abort_txn(eb->txn, pool);}/*** Public interfaces. ***/svn_error_t *svn_repos_get_commit_editor4(const svn_delta_editor_t **editor,                             void **edit_baton,                             svn_repos_t *repos,                             svn_fs_txn_t *txn,                             const char *repos_url,                             const char *base_path,                             const char *user,                             const char *log_msg,                             svn_commit_callback2_t callback,                             void *callback_baton,                             svn_repos_authz_callback_t authz_callback,                             void *authz_baton,                             apr_pool_t *pool){  svn_delta_editor_t *e;  apr_pool_t *subpool = svn_pool_create(pool);  struct edit_baton *eb;  /* Do a global authz access lookup.  Users with no write access     whatsoever to the repository don't get a commit editor. */  if (authz_callback)    {      svn_boolean_t allowed;      SVN_ERR(authz_callback(svn_authz_write, &allowed, NULL, NULL,                             authz_baton, pool));      if (!allowed)        return svn_error_create(SVN_ERR_AUTHZ_UNWRITABLE, NULL,                                "Not authorized to open a commit editor.");    }  /* Allocate the structures. */  e = svn_delta_default_editor(pool);  eb = apr_pcalloc(subpool, sizeof(*eb));  /* Set up the editor. */  e->open_root         = open_root;  e->delete_entry      = delete_entry;  e->add_directory     = add_directory;  e->open_directory    = open_directory;  e->change_dir_prop   = change_dir_prop;  e->add_file          = add_file;  e->open_file         = open_file;  e->close_file        = close_file;  e->apply_textdelta   = apply_textdelta;  e->change_file_prop  = change_file_prop;  e->close_edit        = close_edit;  e->abort_edit        = abort_edit;  /* Set up the edit baton. */  eb->pool = subpool;  eb->user = user ? apr_pstrdup(subpool, user) : NULL;  eb->log_msg = apr_pstrdup(subpool, log_msg);  eb->commit_callback = callback;  eb->commit_callback_baton = callback_baton;  eb->authz_callback = authz_callback;  eb->authz_baton = authz_baton;  eb->base_path = apr_pstrdup(subpool, base_path);  eb->repos = repos;  eb->repos_url = repos_url;  eb->repos_name = svn_path_basename(svn_repos_path(repos, subpool),                                     subpool);  eb->fs = svn_repos_fs(repos);  eb->txn = txn;  eb->txn_owner = txn ? FALSE : TRUE;  *edit_baton = eb;  *editor = e;    return SVN_NO_ERROR;}svn_error_t *svn_repos_get_commit_editor3(const svn_delta_editor_t **editor,                             void **edit_baton,                             svn_repos_t *repos,                             svn_fs_txn_t *txn,                             const char *repos_url,                             const char *base_path,                             const char *user,                             const char *log_msg,                             svn_commit_callback_t callback,                             void *callback_baton,                             svn_repos_authz_callback_t authz_callback,                             void *authz_baton,                             apr_pool_t *pool){  svn_commit_callback2_t callback2;  void *callback2_baton;  svn_compat_wrap_commit_callback(&callback2, &callback2_baton,                                  callback, callback_baton,                                  pool);  return svn_repos_get_commit_editor4(editor, edit_baton, repos, txn,                                      repos_url, base_path, user,                                      log_msg, callback2,                                      callback2_baton, authz_callback,                                      authz_baton, pool);}svn_error_t *svn_repos_get_commit_editor2(const svn_delta_editor_t **editor,                             void **edit_baton,                             svn_repos_t *repos,                             svn_fs_txn_t *txn,                             const char *repos_url,                             const char *base_path,                             const char *user,                             const char *log_msg,                             svn_commit_callback_t callback,                             void *callback_baton,                             apr_pool_t *pool){  return svn_repos_get_commit_editor3(editor, edit_baton, repos, txn,                                      repos_url, base_path, user,                                      log_msg, callback, callback_baton,                                      NULL, NULL, pool);}svn_error_t *svn_repos_get_commit_editor(const svn_delta_editor_t **editor,                            void **edit_baton,                            svn_repos_t *repos,                            const char *repos_url,                            const char *base_path,                            const char *user,                            const char *log_msg,                            svn_commit_callback_t callback,                            void *callback_baton,                            apr_pool_t *pool){  return svn_repos_get_commit_editor2(editor, edit_baton, repos, NULL,                                      repos_url, base_path, user,                                      log_msg, callback,                                      callback_baton, pool);}

⌨️ 快捷键说明

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