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

📄 dump.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:

          /* definitely need to dump all content for a replace. */
          if (kind == svn_node_file)
            must_dump_text = TRUE;
          must_dump_props = TRUE;
        }
      else
        {
          /* more complex:  delete original, then add-with-history.  */

          /* the path & kind headers have already been printed;  just
             add a delete action, and end the current record.*/
          if (eb->stream)
            SVN_ERR (svn_stream_printf (eb->stream, pool,
                                        SVN_REPOS_DUMPFILE_NODE_ACTION
                                        ": delete\n\n"));  

          /* recurse:  print an additional add-with-history record. */
          SVN_ERR (dump_node (eb, path, kind, svn_node_action_add,
                              is_copy, compare_path, compare_rev, pool));

          /* we can leave this routine quietly now, don't need to dump
             any content;  that was already done in the second record. */
          must_dump_text = FALSE;
          must_dump_props = FALSE;
        }
    }
  else if (action == svn_node_action_delete)
    {
      if (eb->stream)
        SVN_ERR (svn_stream_printf (eb->stream, pool,
                                    SVN_REPOS_DUMPFILE_NODE_ACTION
                                    ": delete\n"));  

      /* we can leave this routine quietly now, don't need to dump
         any content. */
      must_dump_text = FALSE;
      must_dump_props = FALSE;
    }
  else if (action == svn_node_action_add)
    {
      if (eb->stream)
        SVN_ERR (svn_stream_printf (eb->stream, pool,
                                    SVN_REPOS_DUMPFILE_NODE_ACTION ": add\n"));

      if (! is_copy)
        {
          /* Dump all contents for a simple 'add'. */
          if (kind == svn_node_file)
            must_dump_text = TRUE;
          must_dump_props = TRUE;
        }
      else
        {
          if ((cmp_rev < eb->oldest_dumped_rev)
              && eb->feedback_stream)
            svn_stream_printf 
              (eb->feedback_stream, pool,
               _("WARNING: Referencing data in revision %ld" 
                 ", which is older than the oldest\nWARNING: dumped revision "
                 "(%ld).  Loading this dump into an empty "
                 "repository\nWARNING: will fail.\n"),
               cmp_rev, eb->oldest_dumped_rev);

          if (eb->stream)
            SVN_ERR (svn_stream_printf (eb->stream, pool,
                                        SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV 
                                        ": %ld\n"
                                        SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH
                                        ": %s\n",
                                        cmp_rev, cmp_path));

          SVN_ERR (svn_fs_revision_root (&compare_root, 
                                         svn_fs_root_fs (eb->fs_root),
                                         compare_rev, pool));

          /* Need to decide if the copied node had any extra textual or
             property mods as well.  */
          SVN_ERR (svn_fs_props_changed (&must_dump_props,
                                         compare_root, compare_path,
                                         eb->fs_root, path, pool));
          if (kind == svn_node_file)
            SVN_ERR (svn_fs_contents_changed (&must_dump_text,
                                              compare_root, compare_path,
                                              eb->fs_root, path, pool));
          
          /* ### someday write a node-copyfrom-source-checksum. */
        }
    }

  if ((! must_dump_text) && (! must_dump_props))
    {
      /* If we're not supposed to dump text or props, so be it, we can
         just go home.  However, if either one needs to be dumped,
         then our dumpstream format demands that at a *minimum*, we
         see a lone "PROPS-END" as a divider between text and props
         content within the content-block. */
      if (eb->stream)
        {
          len = 2;
          return svn_stream_write (eb->stream, "\n\n", &len); /* ### needed? */
        }
      return SVN_NO_ERROR;
    }

  /*** Start prepping content to dump... ***/

  /* If we are supposed to dump properties, write out a property
     length header and generate a stringbuf that contains those
     property values here. */
  if (must_dump_props)
    {
      apr_hash_t *prophash, *oldhash = NULL;
      apr_size_t proplen;

      SVN_ERR (svn_fs_node_proplist (&prophash, eb->fs_root, path, pool));
      if (eb->use_deltas && compare_root)
        {
          /* Fetch the old property hash to diff against and output a header
             saying that our property contents are a delta. */
          SVN_ERR (svn_fs_node_proplist (&oldhash, compare_root, compare_path,
                                         pool));
          if (eb->stream)
            SVN_ERR (svn_stream_printf (eb->stream, pool,
                                        SVN_REPOS_DUMPFILE_PROP_DELTA 
                                        ": true\n"));
        }
      write_hash_to_stringbuf (prophash, oldhash, &propstring, pool);
      proplen = propstring->len;
      content_length += proplen;
      if (eb->stream)
        SVN_ERR (svn_stream_printf (eb->stream, pool,
                                    SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH 
                                    ": %" APR_SIZE_T_FMT "\n", proplen));
    }

  /* If we are supposed to dump text, write out a text length header
     here, and a md5 checksum (if available.) */
  if (must_dump_text && (kind == svn_node_file))
    {
      unsigned char md5_digest[APR_MD5_DIGESTSIZE];
      const char *hex_digest;
      svn_filesize_t textlen;

      if (eb->use_deltas)
        {
          /* Compute the text delta now and write it into a temporary
             file, so that we can find its length.  Output a header
             saying our text contents are a delta. */
          SVN_ERR (store_delta (&delta_file, &textlen, compare_root,
                                compare_path, eb->fs_root, path, pool));
          if (eb->stream)
            SVN_ERR (svn_stream_printf (eb->stream, pool,
                                        SVN_REPOS_DUMPFILE_TEXT_DELTA
                                        ": true\n"));
        }
      else
        {
          /* Just fetch the length of the file. */
          SVN_ERR (svn_fs_file_length (&textlen, eb->fs_root, path, pool));
        }

      content_length += textlen;
      if (eb->stream)
        SVN_ERR (svn_stream_printf (eb->stream, pool,
                                    SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH 
                                    ": %" SVN_FILESIZE_T_FMT "\n", textlen));

      SVN_ERR (svn_fs_file_md5_checksum (md5_digest, eb->fs_root, path, pool));
      hex_digest = svn_md5_digest_to_cstring (md5_digest, pool);
      if (hex_digest && eb->stream)
        SVN_ERR (svn_stream_printf (eb->stream, pool,
                                    SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM 
                                    ": %s\n", hex_digest));
    }

  /* 'Content-length:' is the last header before we dump the content,
     and is the summation of the text and prop contents lengths.  We
     write this only for the benefit of non-Subversion RFC-822
     parsers. */
  if (eb->stream)
    SVN_ERR (svn_stream_printf (eb->stream, pool,
                                SVN_REPOS_DUMPFILE_CONTENT_LENGTH 
                                ": %" SVN_FILESIZE_T_FMT "\n\n",
                                content_length));

  /* Dump property content if we're supposed to do so. */
  if (must_dump_props && eb->stream)
    {
      len = propstring->len;
      SVN_ERR (svn_stream_write (eb->stream, propstring->data, &len));
    }

  /* Dump text content */
  if (must_dump_text && (kind == svn_node_file) && eb->stream)
    {
      svn_stream_t *contents;

      if (delta_file)
        contents = svn_stream_from_aprfile (delta_file, pool);
      else
        SVN_ERR (svn_fs_file_contents (&contents, eb->fs_root, path, pool));

      SVN_ERR (svn_stream_copy (contents, eb->stream, pool));
    }
  
  if (eb->stream)
    {
      len = 2;
      SVN_ERR (svn_stream_write (eb->stream, "\n\n", &len)); /* ### needed? */
    }
  
  return SVN_NO_ERROR;
}


static svn_error_t *
open_root (void *edit_baton, 
           svn_revnum_t base_revision, 
           apr_pool_t *pool,
           void **root_baton)
{
  *root_baton = make_dir_baton (NULL, NULL, SVN_INVALID_REVNUM, 
                                edit_baton, NULL, FALSE, pool);
  return SVN_NO_ERROR;
}


static svn_error_t *
delete_entry (const char *path,
              svn_revnum_t revision, 
              void *parent_baton,
              apr_pool_t *pool)
{
  struct dir_baton *pb = parent_baton;
  const char *mypath = apr_pstrdup (pb->pool, path);

  /* remember this path needs to be deleted. */
  apr_hash_set (pb->deleted_entries, mypath, APR_HASH_KEY_STRING, pb);

  return SVN_NO_ERROR;
}


static svn_error_t *
add_directory (const char *path,
               void *parent_baton,
               const char *copyfrom_path,
               svn_revnum_t copyfrom_rev,
               apr_pool_t *pool,
               void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  void *val;
  svn_boolean_t is_copy = FALSE;
  struct dir_baton *new_db 
    = make_dir_baton (path, copyfrom_path, copyfrom_rev, eb, pb, TRUE, pool);

  /* This might be a replacement -- is the path already deleted? */
  val = apr_hash_get (pb->deleted_entries, path, APR_HASH_KEY_STRING);

  /* Detect an add-with-history. */
  is_copy = ARE_VALID_COPY_ARGS (copyfrom_path, copyfrom_rev) ? TRUE : FALSE;

  /* Dump the node. */
  SVN_ERR (dump_node (eb, path, 
                      svn_node_dir,
                      val ? svn_node_action_replace : svn_node_action_add,
                      is_copy,
                      is_copy ? copyfrom_path : NULL, 
                      is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
                      pool));

  if (val)
    /* Delete the path, it's now been dumped. */
    apr_hash_set (pb->deleted_entries, path, APR_HASH_KEY_STRING, NULL);
  
  new_db->written_out = TRUE;

  *child_baton = new_db;
  return SVN_NO_ERROR;
}


static svn_error_t *
open_directory (const char *path,
                void *parent_baton,
                svn_revnum_t base_revision,
                apr_pool_t *pool,
                void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct dir_baton *new_db;
  const char *cmp_path = NULL;
  svn_revnum_t cmp_rev = SVN_INVALID_REVNUM;

  /* If the parent directory has explicit comparison path and rev,
     record the same for this one. */
  if (pb && ARE_VALID_COPY_ARGS (pb->cmp_path, pb->cmp_rev))
    {
      cmp_path = svn_path_join (pb->cmp_path, 
                                svn_path_basename (path, pool), pool);
      cmp_rev = pb->cmp_rev;
    }
        
  new_db = make_dir_baton (path, cmp_path, cmp_rev, eb, pb, FALSE, pool);
  *child_baton = new_db;
  return SVN_NO_ERROR;
}


static svn_error_t *
close_directory (void *dir_baton,
                 apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  struct edit_baton *eb = db->edit_baton;
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create (pool);
  
  for (hi = apr_hash_first (pool, db->deleted_entries);
       hi;
       hi = apr_hash_next (hi))
    {
      const void *key;
      const char *path;
      apr_hash_this (hi, &key, NULL, NULL);
      path = key;

      /* By sending 'svn_node_unknown', the Node-kind: header simply won't
         be written out.  No big deal at all, really.  The loader
         shouldn't care.  */
      SVN_ERR (dump_node (eb, path,
                          svn_node_unknown, svn_node_action_delete,
                          FALSE, NULL, SVN_INVALID_REVNUM, subpool));

      svn_pool_clear (subpool);
    }

  svn_pool_destroy (subpool);
  return SVN_NO_ERROR;
}


static svn_error_t *
add_file (const char *path,
          void *parent_baton,
          const char *copyfrom_path,
          svn_revnum_t copyfrom_rev,
          apr_pool_t *pool,
          void **file_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  void *val;
  svn_boolean_t is_copy = FALSE;

  /* This might be a replacement -- is the path already deleted? */
  val = apr_hash_get (pb->deleted_entries, path, APR_HASH_KEY_STRING);

  /* Detect add-with-history. */
  is_copy = ARE_VALID_COPY_ARGS (copyfrom_path, copyfrom_rev) ? TRUE : FALSE;

  /* Dump the node. */

⌨️ 快捷键说明

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