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

📄 load.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:
      if ((src_rev_from_map = apr_hash_get (pb->rev_map, &nb->copyfrom_rev,
                                            sizeof(nb->copyfrom_rev))))
        src_rev = *src_rev_from_map;

      if (! SVN_IS_VALID_REVNUM(src_rev))
        return svn_error_createf (SVN_ERR_FS_NO_SUCH_REVISION, NULL,
                                  _("Relative source revision %ld is not"
                                    " available in current repository"),
                                  src_rev);

      SVN_ERR (svn_fs_revision_root (&copy_root, pb->fs, src_rev, pool));
      SVN_ERR (svn_fs_copy (copy_root, nb->copyfrom_path,
                            rb->txn_root, nb->path, pool));

      if (pb->outstream)
        {
          apr_size_t len = 9;
          SVN_ERR (svn_stream_write (pb->outstream, "COPIED...", &len));
        }
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
uuid_record (const char *uuid,
             void *parse_baton,
             apr_pool_t *pool)
{
  struct parse_baton *pb = parse_baton;
  svn_revnum_t youngest_rev;

  if (pb->uuid_action == svn_repos_load_uuid_ignore)
    return SVN_NO_ERROR;

  if (pb->uuid_action != svn_repos_load_uuid_force)
    {
      SVN_ERR (svn_fs_youngest_rev (&youngest_rev, pb->fs, pool));
      if (youngest_rev != 0)
        return SVN_NO_ERROR;
    }

  return svn_fs_set_uuid (pb->fs, uuid, pool);
}

static svn_error_t *
new_node_record (void **node_baton,
                 apr_hash_t *headers,
                 void *revision_baton,
                 apr_pool_t *pool)
{
  struct revision_baton *rb = revision_baton;
  struct parse_baton *pb = rb->pb;
  struct node_baton *nb;
  
  if (rb->rev == 0)
    return svn_error_create (SVN_ERR_STREAM_MALFORMED_DATA, NULL,
                             "Malformed dumpstream: "
                             "Revision 0 must not contain node records");

  nb = make_node_baton (headers, rb, pool);

  switch (nb->action)
    {
    case svn_node_action_change:
      {
        if (pb->outstream)
          SVN_ERR (svn_stream_printf (pb->outstream, pool,
                                      "     * editing path : %s ...",
                                      nb->path));
        break;
      }
    case svn_node_action_delete:
      {
        if (pb->outstream)
          SVN_ERR (svn_stream_printf (pb->outstream, pool,
                                      "     * deleting path : %s ...",
                                      nb->path));
        SVN_ERR (svn_fs_delete (rb->txn_root, nb->path, pool));
        break;
      }
    case svn_node_action_add:
      {
        if (pb->outstream)
          SVN_ERR (svn_stream_printf (pb->outstream, pool,
                                      "     * adding path : %s ...",
                                      nb->path));

        SVN_ERR (maybe_add_with_history (nb, rb, pool));
        break;
      }
    case svn_node_action_replace:
      {
        if (pb->outstream)
          SVN_ERR (svn_stream_printf (pb->outstream, pool,
                                      "     * replacing path : %s ...",
                                      nb->path));

        SVN_ERR (svn_fs_delete (rb->txn_root, nb->path, pool));

        SVN_ERR (maybe_add_with_history (nb, rb, pool));
        break;
      }
    default:
      return svn_error_createf (SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
                                "Unrecognized node-action on node '%s'",
                                nb->path);
    }

  *node_baton = nb;
  return SVN_NO_ERROR;
}


static svn_error_t *
set_revision_property (void *baton,
                       const char *name,
                       const svn_string_t *value)
{
  struct revision_baton *rb = baton;

  if (rb->rev > 0)
    {
      SVN_ERR (svn_fs_change_txn_prop (rb->txn, name, value, rb->pool));
      
      /* Remember any datestamp that passes through!  (See comment in
         close_revision() below.) */
      if (! strcmp (name, SVN_PROP_REVISION_DATE))
        rb->datestamp = svn_string_dup (value, rb->pool);
    }
  else if (rb->rev == 0)
    {     
      /* Special case: set revision 0 properties when loading into an
         'empty' filesystem. */
      struct parse_baton *pb = rb->pb;
      svn_revnum_t youngest_rev;

      SVN_ERR (svn_fs_youngest_rev (&youngest_rev, pb->fs, rb->pool));

      if (youngest_rev == 0)
        SVN_ERR (svn_fs_change_rev_prop (pb->fs, 0, name, value, rb->pool));
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
set_node_property (void *baton,
                   const char *name,
                   const svn_string_t *value)
{
  struct node_baton *nb = baton;
  struct revision_baton *rb = nb->rb;

  SVN_ERR (svn_fs_change_node_prop (rb->txn_root, nb->path,
                                    name, value, nb->pool));
  
  return SVN_NO_ERROR;
}


static svn_error_t *
delete_node_property (void *baton,
                      const char *name)
{
  struct node_baton *nb = baton;
  struct revision_baton *rb = nb->rb;

  SVN_ERR (svn_fs_change_node_prop (rb->txn_root, nb->path,
                                    name, NULL, nb->pool));
  
  return SVN_NO_ERROR;
}


static svn_error_t *
remove_node_props (void *baton)
{
  struct node_baton *nb = baton;
  struct revision_baton *rb = nb->rb;
  apr_hash_t *proplist;
  apr_hash_index_t *hi;

  SVN_ERR (svn_fs_node_proplist (&proplist,
                                 rb->txn_root, nb->path, nb->pool));

  for (hi = apr_hash_first (nb->pool, proplist); hi; hi = apr_hash_next (hi))
    {
      const void *key;
      apr_ssize_t keylen;
      void *val;

      apr_hash_this (hi, &key, &keylen, &val);

      SVN_ERR (svn_fs_change_node_prop (rb->txn_root, nb->path,
                                        (const char *) key, NULL,
                                        nb->pool));
    }

  return SVN_NO_ERROR;
}


static svn_error_t *
apply_textdelta (svn_txdelta_window_handler_t *handler,
                 void **handler_baton,
                 void *node_baton)
{
  struct node_baton *nb = node_baton;
  struct revision_baton *rb = nb->rb;

  return svn_fs_apply_textdelta (handler, handler_baton,
                                 rb->txn_root, nb->path,
                                 NULL, nb->md5_checksum,
                                 nb->pool);
}


static svn_error_t *
set_fulltext (svn_stream_t **stream,
              void *node_baton)
{
  struct node_baton *nb = node_baton;
  struct revision_baton *rb = nb->rb;

  return svn_fs_apply_text (stream,
                            rb->txn_root, nb->path,
                            nb->md5_checksum,
                            nb->pool);
}


static svn_error_t *
close_node (void *baton)
{
  struct node_baton *nb = baton;
  struct revision_baton *rb = nb->rb;
  struct parse_baton *pb = rb->pb;

  if (pb->outstream)
    {
      apr_size_t len = 7;
      SVN_ERR (svn_stream_write (pb->outstream, " done.\n", &len));
    }
  
  return SVN_NO_ERROR;
}


static svn_error_t *
close_revision (void *baton)
{
  struct revision_baton *rb = baton;
  struct parse_baton *pb = rb->pb;
  const char *conflict_msg = NULL;
  svn_revnum_t *old_rev, *new_rev;
  svn_error_t *err;

  if (rb->rev <= 0)
    return SVN_NO_ERROR;

  /* Prepare memory for saving dump-rev -> in-repos-rev mapping. */
  old_rev = apr_palloc (pb->pool, sizeof(svn_revnum_t) * 2);
  new_rev = old_rev + 1;
  *old_rev = rb->rev;

  err = svn_fs_commit_txn (&conflict_msg, &(*new_rev), rb->txn, rb->pool);

  if (err)
    {
      svn_error_clear (svn_fs_abort_txn (rb->txn, rb->pool));
      if (conflict_msg)
        return svn_error_quick_wrap (err, conflict_msg);
      else
        return err;
    }

  /* After a successful commit, must record the dump-rev -> in-repos-rev
     mapping, so that copyfrom instructions in the dump file can look up the
     correct repository revision to copy from. */
  apr_hash_set (pb->rev_map, old_rev, sizeof(svn_revnum_t), new_rev);

  /* Deltify the predecessors of paths changed in this revision. */
  SVN_ERR (svn_fs_deltify_revision (pb->fs, *new_rev, rb->pool));

  /* Grrr, svn_fs_commit_txn rewrites the datestamp property to the
     current clock-time.  We don't want that, we want to preserve
     history exactly.  Good thing revision props aren't versioned! */
  if (rb->datestamp)
    SVN_ERR (svn_fs_change_rev_prop (pb->fs, *new_rev,
                                     SVN_PROP_REVISION_DATE, rb->datestamp,
                                     rb->pool));

  if (pb->outstream)
    {
      if (*new_rev == rb->rev)
        {
          SVN_ERR (svn_stream_printf (pb->outstream, rb->pool,
                                      _("\n------- Committed revision %ld"
                                        " >>>\n\n"), *new_rev));
        }
      else
        {
          SVN_ERR (svn_stream_printf (pb->outstream, rb->pool,
                                      _("\n------- Committed new rev %ld"
                                        " (loaded from original rev %ld"
                                        ") >>>\n\n"), *new_rev, rb->rev));
        }
    }

  return SVN_NO_ERROR;
}


/*----------------------------------------------------------------------*/

/** The public routines **/


svn_error_t *
svn_repos_get_fs_build_parser2 (const svn_repos_parser_fns2_t **callbacks,
                                void **parse_baton,
                                svn_repos_t *repos,
                                svn_boolean_t use_history,
                                enum svn_repos_load_uuid uuid_action,
                                svn_stream_t *outstream,
                                const char *parent_dir,
                                apr_pool_t *pool)
{
  const svn_repos_parser_fns_t *fns;
  svn_repos_parser_fns2_t *parser;

  /* Fetch the old-style vtable and baton, convert the vtable to a
   * new-style vtable, and set the new callbacks. */
  SVN_ERR (svn_repos_get_fs_build_parser (&fns, parse_baton, repos,
                                          use_history, uuid_action, outstream,
                                          parent_dir, pool));
  parser = fns2_from_fns (fns, pool);
  parser->delete_node_property = delete_node_property;
  parser->apply_textdelta = apply_textdelta;
  *callbacks = parser;
  return SVN_NO_ERROR;
}



svn_error_t *
svn_repos_get_fs_build_parser (const svn_repos_parser_fns_t **parser_callbacks,
                               void **parse_baton,
                               svn_repos_t *repos,
                               svn_boolean_t use_history,
                               enum svn_repos_load_uuid uuid_action,
                               svn_stream_t *outstream,
                               const char *parent_dir,
                               apr_pool_t *pool)
{
  svn_repos_parser_fns_t *parser = apr_pcalloc (pool, sizeof(*parser));
  struct parse_baton *pb = apr_pcalloc (pool, sizeof(*pb));

  parser->new_revision_record = new_revision_record;
  parser->new_node_record = new_node_record;
  parser->uuid_record = uuid_record;
  parser->set_revision_property = set_revision_property;
  parser->set_node_property = set_node_property;
  parser->remove_node_props = remove_node_props;
  parser->set_fulltext = set_fulltext;
  parser->close_node = close_node;
  parser->close_revision = close_revision;

  pb->repos = repos;
  pb->fs = svn_repos_fs (repos);
  pb->use_history = use_history;
  pb->outstream = outstream;
  pb->uuid_action = uuid_action;
  pb->parent_dir = parent_dir;
  pb->pool = pool;
  pb->rev_map = apr_hash_make (pool);

  *parser_callbacks = parser;
  *parse_baton = pb;
  return SVN_NO_ERROR;
}



svn_error_t *
svn_repos_load_fs (svn_repos_t *repos,
                   svn_stream_t *dumpstream,
                   svn_stream_t *feedback_stream,
                   enum svn_repos_load_uuid uuid_action,
                   const char *parent_dir,
                   svn_cancel_func_t cancel_func,
                   void *cancel_baton,
                   apr_pool_t *pool)
{
  const svn_repos_parser_fns2_t *parser;
  void *parse_baton;
  
  /* This is really simple. */  

  SVN_ERR (svn_repos_get_fs_build_parser2 (&parser, &parse_baton,
                                           repos,
                                           TRUE, /* look for copyfrom revs */
                                           uuid_action,
                                           feedback_stream,
                                           parent_dir,
                                           pool));

  SVN_ERR (svn_repos_parse_dumpstream2 (dumpstream, parser, parse_baton,
                                        cancel_func, cancel_baton, pool));

  return SVN_NO_ERROR;
}

⌨️ 快捷键说明

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