[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Moving/copying added files and dirs

From: Paul Burba <paulb_at_softlanding.com>
Date: 2006-08-21 18:17:56 CEST

"Ivan Zhakov" <chemodax@gmail.com> wrote on 08/19/2006 03:07:15 AM:

> There are some small glitches, see my comments inside.
>
> Index: subversion/libsvn_wc/copy.c
> ===================================================================
> --- subversion/libsvn_wc/copy.c (revision 21115)
> +++ subversion/libsvn_wc/copy.c (working copy)
> @@ -39,6 +39,242 @@
>
> /*** Code. ***/
>
> +/* Helper function for svn_wc_copy2() which handles WC->WC copying of
> + files which are scheduled for addition or unversioned.
> +
> + Copy SRC_PATH to DST_PATH.
> +
> + DST_PATH is a non-existant path, but it's parent must exist
> + and be in the same WC as SRC_PATH.
> +
> + If SRC_IS_ADDED is true then SRC_PATH is scheduled for addition and
> + DST_PATH will also be scheduled for addition.
> +
> + If SRC_IS_ADDED is false then SRC_PATH is the unversioned child
> + file of a versioned or added parent and DST_PATH is simply copied.
> +
> + DST_PARENT_ACCESS is a 0 depth locked access for the
> + versioned parent dir of DST_PATH.
> +
> + Use POOL for all necessary allocations.
> +*/
> +static svn_error_t *
> +copy_added_file_administratively(const char *src_path,
> + const char *dst_path,
> + svn_boolean_t src_is_added,
> + svn_wc_adm_access_t
*dst_parent_access,
> + svn_cancel_func_t cancel_func,
> + void *cancel_baton,
> + svn_wc_notify_func2_t notify_func,
> + void *notify_baton,
> + apr_pool_t *pool)
> +{
> + char *src_parent = svn_path_dirname(src_path, pool);
>
> Btw, what do you think about split dst_path parameter to dst_parent
> and dst_basename in parameters in
> copy_added_file_administratively/copy_added_dir_administratively?
> Because you are joining it when calling function and further splitting
> it function body. It also will be more coordinated with
> copy_file_administratively/copy_dir_administratively.
 
I changed dst_path to dst_basename as you suggested to avoid the redundant
join/split. But adding dst_parent seems unecessary, since
dst_parent_access already has the path dst_parent readily
available...Unless you meant that svn_wc_adm_access_t *dst_parent_access
should instead be named dst_parent(?). If so I really prefer the name
with the "_access" suffix as it makes the code easier to read when
variables representing path names are easily distinguished from
svn_wc_adm_access_t pointers. Or possibly I'm misundertanding you
completely :-(

I also added the argument svn_wc_adm_access_t *src_access to
copy_added_dir_administratively() since svn_wc_copy2() already has a -1
unlocked access and there is no reason for me to open/close another
access, we can simply retrieve the access out of src_access.

Comments for both helper functions updated.

> + /* Copy this file and possibly put it under version control. */
> + SVN_ERR(svn_io_copy_file(src_path, dst_path, TRUE, pool));
> +
> Trailing spaces.

Removed.

> + if (src_is_added)
> + {
> + SVN_ERR(svn_wc_add2(dst_path, dst_parent_access, NULL,
> + SVN_INVALID_REVNUM, cancel_func,
> + cancel_baton, notify_func,
> + notify_baton, pool));
> + }
> +
> + return SVN_NO_ERROR;
> +}
> +
> +
> +/* Helper function for svn_wc_copy2() which handles WC->WC copying of
> + directories which are scheduled for addition or unversioned.
> +
> + Copy SRC_PATH to DST_PATH.
> +
> + DST_PATH is a non-existant path, but it's parent must exist
> + and be in the same WC as SRC_PATH.
> +
> + If SRC_IS_ADDED is true then SRC_PATH is scheduled for addition and
> + DST_PATH will also be scheduled for addition.
> +
> + If SRC_IS_ADDED is false then SRC_PATH is the unversioned child
> + directory of a versioned or added parent and DST_PATH is simply
copied.
> +
> + DST_PARENT_ACCESS is a 0 depth locked access for the
> + versioned parent dir of DST_PATH.
> +
> + Use POOL for all necessary allocations.
> +*/
> +static svn_error_t *
> +copy_added_dir_administratively(const char *src_path,
> + const char *dst_path,
> + svn_boolean_t src_is_added,
> + svn_wc_adm_access_t *dst_parent_access,
> + svn_cancel_func_t cancel_func,
> + void *cancel_baton,
> + svn_wc_notify_func2_t notify_func,
> + void *notify_baton,
> + apr_pool_t *pool)
> +{
> + if (! src_is_added)
> + {
> + /* src_path is the top of an unversioned tree, just copy
> + the whole thing and we are done. */
> + SVN_ERR(svn_io_copy_dir_recursively(src_path,
> + svn_path_dirname(dst_path,
pool),
> + svn_path_basename(dst_path,
pool),
> + TRUE, cancel_func,
cancel_baton,
> + pool));
> + }
> + else
> + {
> + char *src_parent, *dst_parent;
> + const svn_wc_entry_t *entry;
> + svn_wc_adm_access_t *src_access;
> + svn_wc_adm_access_t *dst_child_dir_access;
> + svn_wc_adm_access_t *src_child_dir_access;
> + apr_dir_t *dir;
> + apr_finfo_t this_entry;
> + svn_error_t *err;
> + apr_pool_t *subpool;
> + apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
> +
> + /* Check cancellation; note that this catches recursive calls
too. */
> + if (cancel_func)
> + SVN_ERR(cancel_func(cancel_baton));
> +
> + src_parent = svn_path_dirname(src_path, pool);
> + dst_parent = svn_path_dirname(dst_path, pool);
> +
> + /* Get a svn_wc_adm_access_t for src_path. */
> + if (strcmp(src_parent, dst_parent) == 0)
> + {
> + src_access = dst_parent_access;
> + }
> + else
> + {
> + SVN_ERR(svn_wc_adm_open3(&src_access, NULL, src_parent,
FALSE, 0,
> + cancel_func, cancel_baton,pool));
> + }
> +
> + /* "Copy" the dir dst_path and schedule it, and possibly
> + it's children, for addition. */
> + SVN_ERR(svn_io_dir_make(dst_path, APR_OS_DEFAULT, pool));
> +
> Trailing spaces. (I hate this stuff too :)

Removed.
 
> + SVN_ERR(svn_wc_adm_open3(&src_child_dir_access, NULL, src_path,
FALSE,
> + 0, cancel_func, cancel_baton, pool));
> +
> + /* Add the directory, adding locking access for dst_path
> + to dst_parent_access at the same time. */
> + SVN_ERR(svn_wc_add2(dst_path, dst_parent_access, NULL,
> + SVN_INVALID_REVNUM, cancel_func,
cancel_baton,
> + notify_func, notify_baton, pool));
> +
> + /* Get the access for the newly added dir, we'll need it if we
> + recurse or call copy_added_file_administratively(). */
> + SVN_ERR(svn_wc_adm_retrieve(&dst_child_dir_access,
dst_parent_access,
> + dst_path, pool));
> Formatting glitch.

Fixed.
 
> +
> + /* Create a subpool for iterative memory control. */
> + subpool = svn_pool_create(pool);
> +
> + /* Read src_path's entries one by one. */
> + SVN_ERR(svn_io_dir_open(&dir, src_path, pool));
> + for (err = svn_io_dir_read(&this_entry, flags, dir, subpool);
> + err == SVN_NO_ERROR;
> + err = svn_io_dir_read(&this_entry, flags, dir, subpool))
> + {
> + const char *src_fullpath, *dst_fullpath;
> +
> + /* Skip entries for this dir and its parent. */
> + if (this_entry.name[0] == '.'
> + && (this_entry.name[1] == '\0'
> + || (this_entry.name[1] == '.'
> + && this_entry.name[2] == '\0')))
> + continue;
> +
> + /* Check cancellation so you can cancel during an
> + * add of a directory with lots of files. */
> + if (cancel_func)
> + SVN_ERR(cancel_func(cancel_baton));
> +
> + /* Skip over SVN admin directories. */
> + if (svn_wc_is_adm_dir(this_entry.name, subpool))
> + continue;
> +
> + /* Construct the full path of the entry. */
> + src_fullpath = svn_path_join(src_path, this_entry.name,
subpool);
> + dst_fullpath = svn_path_join(dst_path, this_entry.name,
subpool);
> +
> + SVN_ERR(svn_wc_entry(&entry, src_fullpath,
src_child_dir_access,
> + TRUE, subpool));
> + src_is_added = entry ? TRUE : FALSE;
> I think this should be deleted, because it's never used further.

Removed.
 
Ok, I think this is about ready if you think these latest changes look ok.

Paul B.

[[[
Support copy and move of paths scheduled for addition.

Follow-up to r20811.

Suggested by: zhakov

* subversion/libsvn_wc/copy.c
  (copy_added_file_administratively, copy_added_dir_administratively):
  New recursive helper functions for copying added paths and unversioned
  children within added directories.
  (svn_wc_copy2): Use new helper functions when copying added paths.

* subversion/tests/cmdline/copy_tests.py
  (copy_move_added_paths, copy_added_paths_to_URL,): New tests.
  (test_list): Run new tests.
]]]

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Received on Mon Aug 21 18:46:27 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.