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

📄 main.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (svn_property_kind(NULL, name) != svn_prop_regular_kind)    return SVN_NO_ERROR;  return eb->wrapped_editor->change_dir_prop(db->wrapped_node_baton,                                             name, value, pool);}static svn_error_t *close_edit(void *edit_baton,           apr_pool_t *pool){  edit_baton_t *eb = edit_baton;  /* If we haven't opened the root yet, that means we're transfering     an empty revision, probably because we aren't allowed to see the     contents for some reason.  In any event, we need to open the root     and close it again, before we can close out the edit, or the     commit will fail. */  if (! eb->called_open_root)    {      void *baton;      SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton,                                            eb->base_revision, pool,                                            &baton));      SVN_ERR(eb->wrapped_editor->close_directory(baton, pool));    }  return eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool);}/*** Editor factory function ***//* Set WRAPPED_EDITOR and WRAPPED_EDIT_BATON to an editor/baton pair * that wraps our own commit EDITOR/EDIT_BATON.  BASE_REVISION is the * revision on which the driver of this returned editor will be basing * the commit.  TO_URL is the URL of the root of the repository into * which the commit is being made. */static svn_error_t *get_sync_editor(const svn_delta_editor_t *wrapped_editor,                void *wrapped_edit_baton,                svn_revnum_t base_revision,                const char *to_url,                const svn_delta_editor_t **editor,                void **edit_baton,                apr_pool_t *pool){  svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool);  edit_baton_t *eb = apr_palloc(pool, sizeof(*eb));  tree_editor->set_target_revision = set_target_revision;  tree_editor->open_root = open_root;  tree_editor->delete_entry = delete_entry;  tree_editor->add_directory = add_directory;  tree_editor->open_directory = open_directory;  tree_editor->change_dir_prop = change_dir_prop;  tree_editor->close_directory = close_directory;  tree_editor->absent_directory = absent_directory;  tree_editor->add_file = add_file;  tree_editor->open_file = open_file;  tree_editor->apply_textdelta = apply_textdelta;  tree_editor->change_file_prop = change_file_prop;  tree_editor->close_file = close_file;  tree_editor->absent_file = absent_file;  tree_editor->close_edit = close_edit;  eb->wrapped_editor = wrapped_editor;  eb->wrapped_edit_baton = wrapped_edit_baton;  eb->called_open_root = FALSE;  eb->base_revision = base_revision;  eb->to_url = to_url;  *editor = tree_editor;  *edit_baton = eb;  return SVN_NO_ERROR;}/*** `svnsync sync' ***//* Baton for syncronizing the destination repository while locked. */typedef struct {  apr_hash_t *config;  svn_ra_callbacks2_t *callbacks;  const char *to_url;  svn_revnum_t committed_rev;} sync_baton_t;/* Implements `svn_commit_callback2_t' interface. */static svn_error_t *commit_callback(const svn_commit_info_t *commit_info,                void *baton,                apr_pool_t *pool){  sync_baton_t *sb = baton;  SVN_ERR(svn_cmdline_printf(pool, _("Committed revision %ld.\n"),                             commit_info->revision));  sb->committed_rev = commit_info->revision;  return SVN_NO_ERROR;}/* Set *FROM_SESSION to an RA session associated with the source * repository of the syncronization, as determined by reading * svn:sync- properties from the destination repository (associated * with TO_SESSION).  Set LAST_MERGED_REV to the value of the property * which records the most recently syncronized revision.   *  * CALLBACKS is a vtable of RA callbacks to provide when creating * *FROM_SESSION.  CONFIG is a configuration hash. */static svn_error_t *open_source_session(svn_ra_session_t **from_session,                    svn_string_t **last_merged_rev,                    svn_ra_session_t *to_session,                    svn_ra_callbacks2_t *callbacks,                    apr_hash_t *config,                    void *baton,                    apr_pool_t *pool){  svn_string_t *from_url, *from_uuid;  const char *uuid;  SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_URL,                          &from_url, pool));  SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_UUID,                          &from_uuid, pool));  SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_LAST_MERGED_REV,                          last_merged_rev, pool));  if (! from_url || ! from_uuid || ! *last_merged_rev)    return svn_error_create      (APR_EINVAL, NULL, _("Destination repository has not been initialized"));  SVN_ERR(svn_ra_open2(from_session, from_url->data, callbacks, baton,                       config, pool));  SVN_ERR(check_if_session_is_at_repos_root(*from_session, from_url->data,                                            pool));  /* Ok, now sanity check the UUID of the source repository, it     wouldn't be a good thing to sync from a different repository. */  SVN_ERR(svn_ra_get_uuid(*from_session, &uuid, pool));  if (strcmp(uuid, from_uuid->data) != 0)    return svn_error_createf(APR_EINVAL, NULL,                             _("UUID of source repository (%s) does not "                               "match expected UUID (%s)"),                             uuid, from_uuid->data);  return SVN_NO_ERROR;}/* Syncronize the repository associated with RA session TO_SESSION, * using information found in baton B, while the repository is * locked.  Implements `with_locked_func_t' interface. */static svn_error_t *do_synchronize(svn_ra_session_t *to_session, void *b, apr_pool_t *pool){  svn_string_t *last_merged_rev;  svn_revnum_t from_latest, current;  svn_ra_session_t *from_session;  sync_baton_t *baton = b;  apr_pool_t *subpool;  svn_string_t *currently_copying;  svn_revnum_t to_latest, copying, last_merged;  SVN_ERR(open_source_session(&from_session, &last_merged_rev, to_session,                              baton->callbacks, baton->config, baton, pool));  /* Check to see if we have revprops that still need to be copied for     a prior revision we didn't finish copying.  But first, check for     state sanity.  Remember, mirroring is not an atomic action,     because revision properties are copied separately from the     revision's contents.     So, any time that currently-copying is not set, then     last-merged-rev should be the HEAD revision of the destination     repository.  That is, if we didn't fall over in the middle of a     previous syncronization, then our destination repository should     have exactly as many revisions in it as we've syncronized.     Alternately, if currently-copying *is* set, it must     be either last-merged-rev or last-merged-rev + 1, and the HEAD     revision must be equal to either last-merged-rev or     currently-copying. If this is not the case, somebody has meddled     with the destination without using svnsync.  */  SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_CURRENTLY_COPYING,                          &currently_copying, pool));  SVN_ERR(svn_ra_get_latest_revnum(to_session, &to_latest, pool));  last_merged = SVN_STR_TO_REV(last_merged_rev->data);  if (currently_copying)    {      copying = SVN_STR_TO_REV(currently_copying->data);      if ((copying < last_merged)          || (copying > (last_merged + 1))          || ((to_latest != last_merged) && (to_latest != copying)))        {          return svn_error_createf            (APR_EINVAL, NULL,             _("Revision being currently copied (%ld), last merged revision "               "(%ld), and destination HEAD (%ld) are inconsistent; have you "               "committed to the destination without using svnsync?"),             copying, last_merged, to_latest);        }      else if (copying == to_latest)        {          if (copying > last_merged)            {              SVN_ERR(copy_revprops(from_session, to_session,                                     to_latest, TRUE, pool));              last_merged = copying;              last_merged_rev = svn_string_create                (apr_psprintf(pool, "%ld", last_merged), pool);            }          /* Now update last merged rev and drop currently changing.             Note that the order here is significant, if we do them             in the wrong order there are race conditions where we             end up not being able to tell if there have been bogus             (i.e. non-svnsync) commits to the dest repository. */          SVN_ERR(svn_ra_change_rev_prop(to_session, 0,                                         SVNSYNC_PROP_LAST_MERGED_REV,                                         last_merged_rev, pool));          SVN_ERR(svn_ra_change_rev_prop(to_session, 0,                                         SVNSYNC_PROP_CURRENTLY_COPYING,                                         NULL, pool));        }      /* If copying > to_latest, then we just fall through to         attempting to copy the revision again. */    }  else    {      if (to_latest != last_merged)        {          return svn_error_createf            (APR_EINVAL, NULL,             _("Destination HEAD (%ld) is not the last merged revision (%ld); "               "have you committed to the destination without using svnsync?"),             to_latest, last_merged);        }    }  /* Now check to see if there are any revisions to copy. */  SVN_ERR(svn_ra_get_latest_revnum(from_session, &from_latest, pool));  if (from_latest < atol(last_merged_rev->data))    return SVN_NO_ERROR;  subpool = svn_pool_create(pool);  /* Ok, so there are new revisions, iterate over them copying them     into the destination repository. */  for (current = atol(last_merged_rev->data) + 1;       current <= from_latest;       ++current)    {      const svn_delta_editor_t *commit_editor;      const svn_delta_editor_t *cancel_editor;      const svn_delta_editor_t *sync_editor;      void *commit_baton;      void *cancel_baton;      void *sync_baton;      svn_pool_clear(subpool);      /* We set this property so that if we error out for some reason         we can later determine where we were in the process of         merging a revision.  If we had committed the change, but we         hadn't finished copying the revprops we need to know that, so         we can go back and finish the job before we move on.                 NOTE: We have to set this before we start the commit editor,         because ra_svn doesn't let you change rev props during a         commit. */      SVN_ERR(svn_ra_change_rev_prop(to_session, 0,                                     SVNSYNC_PROP_CURRENTLY_COPYING,                                     svn_string_createf(subpool, "%ld",                                                        current),                                     subpool));      /* The actual copy is just a replay hooked up to a commit. */      SVN_ERR(svn_ra_get_commit_editor2(to_session, &commit_editor,                                        &commit_baton,                                        "", /* empty log */                                        commit_callback, baton,                                        NULL, FALSE, subpool));      /* There's one catch though, the diff shows us props we can't         send over the RA interface, so we need an editor that's smart         enough to filter those out for us.  */      SVN_ERR(get_sync_editor(commit_editor, commit_baton, current - 1,                              baton->to_url, &sync_editor, &sync_baton,                              subpool));      SVN_ERR(svn_delta_get_cancellation_editor(check_cancel, NULL,                                                sync_editor, sync_baton,                                                &cancel_editor,                                                &cancel_baton,                                                subpool));      SVN_ERR(svn_ra_replay(from_session, current, 0, TRUE,                            cancel_editor, cancel_baton, subpool));      SVN_ERR(cancel_editor->close_edit(cancel_baton, subpool));      /* Sanity check that we actually committed the revision we meant to. */      if (baton->committed_rev != current)        return svn_error_createf                 (APR_EINVAL, NULL,                  _("Commit created rev %ld but should have created %ld"),                  baton->committed_rev, current);      /* Ok, we're done with the data, now we just need to do the         revprops and we're all set. */      SVN_ERR(copy_revprops(from_session, to_session, current, TRUE, subpool));      /* Ok, we're done, bring the last-merged-rev property up to date. */      SVN_ERR(svn_ra_change_rev_prop              (to_session,               0,               SVNSYNC_PROP_LAST_MERGED_REV,               svn_string_create(apr_psprintf(subpool, "%ld", current),                                 subpool),               subpool));      /* And finally drop the currently copying prop, since we're done         with this revision. */      SVN_ERR(svn_ra_change_rev_prop(to_session, 0,                                     SVNSYNC_PROP_CURRENTLY_COPYING,                                     NULL, subpool));    }  return SVN_NO_ERROR;}/* SUBCOMMAND: sync */static svn_error_t *synchronize_cmd(apr_getopt_t *os, void *b, apr_pool_t *pool){  svn_ra_callbacks2_t callbacks = { 0 };  svn_ra_session_t *to_session;  opt_baton_t *opt_baton = b;  apr_array_header_t *args;  sync_baton_t baton;  const char *to_url;  SVN_ERR(svn_opt_parse_num_args(&args, os, 1, pool));  to_url = svn_path_canonicalize(APR_ARRAY_IDX(args, 0, const char *), pool);  if (! svn_path_is_url(to_url))    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,                              _("Path '%s' is not a URL"), to_url);  callbacks.open_tmp_file = open_tmp_file;  callbacks.auth_baton = opt_baton->auth_baton;

⌨️ 快捷键说明

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