FreeBSD/contrib/subversion/subversion/libsvn_repos/replay.c
/* Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
   the appropriate editor calls to add it and its children without any
   history.  This is meant to be used when either a subset of the tree
   has been ignored and we need to copy something from that subset to
   the part of the tree we do care about, or if a subset of the tree is
   unavailable because of authz and we need to use it as the source of
   a copy. */
Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
the appropriate editor calls to add it and its children without any
history.  This is meant to be used when either a subset of the tree
has been ignored and we need to copy something from that subset to
the part of the tree we do care about, or if a subset of the tree is
unavailable because of authz and we need to use it as the source of
a copy.
Recursively traverse EDIT_PATH ( as it exists under SOURCE_ROOT ) emitting the appropriate editor calls to add it and its children without any history . This is meant to be used when either a subset of the tree has been ignored and we need to copy something from that subset to the part of the tree we do care about or if a subset of the tree is unavailable because of authz and we need to use it as the source of a copy .
static svn_error_t *
add_subdir_ev2(svn_fs_root_t *source_root,
               svn_fs_root_t *target_root,
               svn_editor_t *editor,
               const char *repos_relpath,
               const char *source_fspath,
               svn_repos_authz_func_t authz_read_func,
               void *authz_read_baton,
               apr_hash_t *changed_paths,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_hash_index_t *hi;
  apr_hash_t *dirents;
  apr_hash_t *props = NULL;
  apr_array_header_t *children = NULL;
  SVN_ERR(svn_fs_node_proplist(&props, target_root, repos_relpath,
                               scratch_pool));
  SVN_ERR(svn_editor_add_directory(editor, repos_relpath, children,
                                   props, SVN_INVALID_REVNUM));
  SVN_ERR(svn_fs_dir_entries(&dirents, source_root, source_fspath,
                             scratch_pool));
  for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
    {
      svn_fs_path_change2_t *change;
      svn_boolean_t readable = TRUE;
      svn_fs_dirent_t *dent = apr_hash_this_val(hi);
      const char *copyfrom_path = NULL;
      svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
      const char *child_relpath;
      svn_pool_clear(iterpool);
      child_relpath = svn_relpath_join(repos_relpath, dent->name, iterpool);
      change = svn_hash_gets(changed_paths, child_relpath);
      if (change)
        {
          svn_hash_sets(changed_paths, child_relpath, NULL);
          if (change->change_kind == svn_fs_path_change_delete)
            continue;
          if (change->change_kind == svn_fs_path_change_replace)
            {
              if (! change->copyfrom_known)
                {
                  SVN_ERR(svn_fs_copied_from(&change->copyfrom_rev,
                                             &change->copyfrom_path,
                                             target_root, child_relpath,
                                             result_pool));
                  change->copyfrom_known = TRUE;
                }
              copyfrom_path = change->copyfrom_path;
              copyfrom_rev = change->copyfrom_rev;
            }
        }
      if (authz_read_func)
        SVN_ERR(authz_read_func(&readable, target_root, child_relpath,
                                authz_read_baton, iterpool));
      if (! readable)
        continue;
      if (dent->kind == svn_node_dir)
        {
          svn_fs_root_t *new_source_root;
          const char *new_source_fspath;
          if (copyfrom_path)
            {
              svn_fs_t *fs = svn_fs_root_fs(source_root);
              SVN_ERR(svn_fs_revision_root(&new_source_root, fs,
                                           copyfrom_rev, result_pool));
              new_source_fspath = copyfrom_path;
            }
          else
            {
              new_source_root = source_root;
              new_source_fspath = svn_fspath__join(source_fspath, dent->name,
                                                   iterpool);
            }
          if (change && change->change_kind == svn_fs_path_change_replace
              && copyfrom_path == NULL)
            {
              SVN_ERR(svn_editor_add_directory(editor, child_relpath,
                                               children, props,
                                               SVN_INVALID_REVNUM));
            }
          else
            {
              SVN_ERR(add_subdir_ev2(new_source_root, target_root,
                                     editor, child_relpath,
                                     new_source_fspath,
                                     authz_read_func, authz_read_baton,
                                     changed_paths, result_pool, iterpool));
            }
        }
      else if (dent->kind == svn_node_file)
        {
          svn_checksum_t *checksum;
          svn_stream_t *contents;
          SVN_ERR(svn_fs_node_proplist(&props, target_root,
                                       child_relpath, iterpool));
          SVN_ERR(svn_fs_file_contents(&contents, target_root,
                                       child_relpath, iterpool));
          SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
                                       target_root,
                                       child_relpath, TRUE, iterpool));
          SVN_ERR(svn_editor_add_file(editor, child_relpath, checksum,
                                      contents, props, SVN_INVALID_REVNUM));
        }
      else
        SVN_ERR_MALFUNCTION();
    }
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}
static svn_error_t * add_subdir_ev2 ( svn_fs_root_t * source_root , svn_fs_root_t * target_root , svn_editor_t * editor , const char * repos_relpath , const char * source_fspath , svn_repos_authz_func_t authz_read_func , void * authz_read_baton , apr_hash_t * changed_paths , apr_pool_t * result_pool , apr_pool_t * scratch_pool ) { apr_pool_t * iterpool = svn_pool_create ( scratch_pool ) ; apr_hash_index_t * hi ; apr_hash_t * dirents ; apr_hash_t * props = NULL ; apr_array_header_t * children = NULL ; SVN_ERR ( svn_fs_node_proplist ( & props , target_root , repos_relpath , scratch_pool ) ) ; SVN_ERR ( svn_editor_add_directory ( editor , repos_relpath , children , props , SVN_INVALID_REVNUM ) ) ; SVN_ERR ( svn_fs_dir_entries ( & dirents , source_root , source_fspath , scratch_pool ) ) ; for ( hi = apr_hash_first ( scratch_pool , dirents ) ; hi ; hi = apr_hash_next ( hi ) ) { svn_fs_path_change2_t * change ; svn_boolean_t readable = TRUE ; svn_fs_dirent_t * dent = apr_hash_this_val ( hi ) ; const char * copyfrom_path = NULL ; svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM ; const char * child_relpath ; svn_pool_clear ( iterpool ) ; child_relpath = svn_relpath_join ( repos_relpath , dent -> name , iterpool ) ; change = svn_hash_gets ( changed_paths , child_relpath ) ; if ( change ) { svn_hash_sets ( changed_paths , child_relpath , NULL ) ; if ( change -> change_kind == svn_fs_path_change_delete ) continue ; if ( change -> change_kind == svn_fs_path_change_replace ) { if ( ! change -> copyfrom_known ) { SVN_ERR ( svn_fs_copied_from ( & change -> copyfrom_rev , & change -> copyfrom_path , target_root , child_relpath , result_pool ) ) ; change -> copyfrom_known = TRUE ; } copyfrom_path = change -> copyfrom_path ; copyfrom_rev = change -> copyfrom_rev ; } } if ( authz_read_func ) SVN_ERR ( authz_read_func ( & readable , target_root , child_relpath , authz_read_baton , iterpool ) ) ; if ( ! readable ) continue ; if ( dent -> kind == svn_node_dir ) { svn_fs_root_t * new_source_root ; const char * new_source_fspath ; if ( copyfrom_path ) { svn_fs_t * fs = svn_fs_root_fs ( source_root ) ; SVN_ERR ( svn_fs_revision_root ( & new_source_root , fs , copyfrom_rev , result_pool ) ) ; new_source_fspath = copyfrom_path ; } else { new_source_root = source_root ; new_source_fspath = svn_fspath__join ( source_fspath , dent -> name , iterpool ) ; } if ( change && change -> change_kind == svn_fs_path_change_replace && copyfrom_path == NULL ) { SVN_ERR ( svn_editor_add_directory ( editor , child_relpath , children , props , SVN_INVALID_REVNUM ) ) ; } else { SVN_ERR ( add_subdir_ev2 ( new_source_root , target_root , editor , child_relpath , new_source_fspath , authz_read_func , authz_read_baton , changed_paths , result_pool , iterpool ) ) ; } } else if ( dent -> kind == svn_node_file ) { svn_checksum_t * checksum ; svn_stream_t * contents ; SVN_ERR ( svn_fs_node_proplist ( & props , target_root , child_relpath , iterpool ) ) ; SVN_ERR ( svn_fs_file_contents ( & contents , target_root , child_relpath , iterpool ) ) ; SVN_ERR ( svn_fs_file_checksum ( & checksum , svn_checksum_sha1 , target_root , child_relpath , TRUE , iterpool ) ) ; SVN_ERR ( svn_editor_add_file ( editor , child_relpath , checksum , contents , props , SVN_INVALID_REVNUM ) ) ; } else SVN_ERR_MALFUNCTION ( ) ; } svn_pool_destroy ( iterpool ) ; return SVN_NO_ERROR ; }
Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
the appropriate editor calls to add it and its children without any
history.
Recursively traverse EDIT_PATH ( as it exists under SOURCE_ROOT ) emitting the appropriate editor calls to add it and its children without any history .
/* We have to get the dirents from the source path, not the target,
     because we want nested copies from *readable* paths to be handled by
     path_driver_cb_func, not add_subdir (in order to preserve history). */ /* If a file or subdirectory of the copied directory is listed as a
         changed path (because it was modified after the copy but before the
         commit), we remove it from the changed_paths hash so that future
         calls to path_driver_cb_func will ignore it. */ /* If it's a delete, skip this entry. */ /* If it's a replacement, check for copyfrom info (if we
             don't have it already. */ /* ### authz considerations?
           *
           * I think not; when path_driver_cb_func() calls add_subdir(), it
           * passes SOURCE_ROOT and SOURCE_FSPATH that are unreadable.
           */