svn-3728

Version:

1.6.x

Bug Link:

http://subversion.tigris.org/issues/show_bug.cgi?id=3728

Patch Link:

source code patch: http://svn.apache.org/viewvc?diff_format=h&view=revision&revision=1033508

Dump file: http://svn.apache.org/viewvc?diff_format=h&view=revision&revision=1021493

Symptom:

background: (the tool ‘svnsync’ makes a mirror repository from the source repository.)

The subcommand ‘svnsync copy-revprops’ copies the properties of the specific revision from the source to the mirror repository, but it doesn’t work when the property of source repository is deleted. That is, deleted properties from source repository still remain in the mirror repository.

How it is diagnosed:

reproduced.

 

How to reproduce:

1. Set up source/mirror repositories with the property name of “issue” with the value of “123”.

1-1. Set property “issue:123” into source repository in revision 1.

                svn propset issue --revprop -r 1 123 svn://127.0.0.1/alpha

  -Output property name & value

svn proplist -v --revprop -r 1 svn://127.0.0.1/alpha

1-2. Sync with the mirror repository

                svnsync copy-revprops svn://127.0.0.1/alpha-mirror 1

-Output property name & value

svn proplist -v --revprop -r1 svn://127.0.0.1/alpha-mirror

 

2. Delete the property “issue” in the source repository & synchronize with the mirror repository.

2-1. Delete the property “issue” in the source repository

                svn propdel issue --revprop -r 1 svn://127.0.0.1/alpha

 -Output the deleted value

                svn proplist -v --revprop -r 1 svn://127.0.0.1/alpha

2-2. Synchronize with the mirror repository and output the properties in the mirror repository

                svnsync copy-revprops svn://127.0.0.1/alpha-mirror 1

-Output the properties

svn proplist -v --revprop -r1 svn://127.0.0.1/alpha-mirror

 

*Result: the property “issue” still remains in the mirror repository.

 

 

Root Cause:

Brief:

“synsync copy-revprops” command doesn’t update the deleted properties of the source repository into the mirror repository. The patched code makes the SYNC flag to TRUE.

Detail:

Function call hierarchy:

“svnsync copy-revprops” command

=> calls ‘copy_revprops_cmd’

=> calls ‘do_copy_revprops’

=> calls ‘copy_revprops’

=> calls ‘remove_props_not_in_source’

 

Function remove_props_not_in_source: removes the properties in TARGET_PROPS but not in SOURCE_PROPS.

 

--- subversion/trunk/subversion/svnsync/main.c          2010/11/10 15:17:25            1033507

+++ subversion/trunk/subversion/svnsync/main.c   2010/11/10 15:17:47            1033508

@@ -530,6 +530,8 @@ check_if_session_is_at_repos_root(svn_ra

 /* Remove the properties in TARGET_PROPS but not in SOURCE_PROPS from

  * revision REV of the repository associated with RA session SESSION.

  *

+ * For REV zero, don't remove properties with the "svn:sync-" prefix.

+ *

  * All allocations will be done in a subpool of POOL.

  */

 static svn_error_t *

@@ -550,6 +552,10 @@ remove_props_not_in_source(svn_ra_sessio

 

       svn_pool_clear(subpool);

 

+          if (rev == 0 && !strncmp(propname, SVNSYNC_PROP_PREFIX,

+                               sizeof(SVNSYNC_PROP_PREFIX) - 1))

+            continue;

+

// Don't remove the properties with prefix "svn:sync-" when Revision is 0.

 

           /* Delete property if the name can't be found in SOURCE_PROPS. */

           if (! apr_hash_get(source_props, propname, APR_HASH_KEY_STRING))

         SVN_ERR(svn_ra_change_rev_prop2(session, rev, propname, NULL,

@@ -1487,7 +1493,7 @@ do_copy_revprops(svn_ra_session_t *to_se

         {

           int normalized_count;

       SVN_ERR(check_cancel(NULL));

-          SVN_ERR(copy_revprops(from_session, to_session, i, FALSE,

+          SVN_ERR(copy_revprops(from_session, to_session, i, TRUE,

                             baton->quiet, &normalized_count, pool));

// the third argument is SYNC flag. If the SYNC is TRUE, then properties on the destination revision that do not exist on the source revision will be removed.

 

       normalized_rev_props_count += normalized_count;

         }

 

static svn_error_t *

copy_revprops(svn_ra_session_t *from_session,

              svn_ra_session_t *to_session,

                  svn_revnum_t rev,

                  svn_boolean_t sync, // the third argument ‘SYNC’

                  svn_boolean_t quiet,

                  int *normalized_count,

                  apr_pool_t *pool)

{

 

  /* Delete those properties that were in TARGET but not in SOURCE */

  if (sync)

    SVN_ERR(remove_props_not_in_source(to_session, rev,

                                       rev_props, existing_props, pool));

}

==========SOYEON

test_bed/subversion/tags/1.6.1/subversion/libsvn_ra_svn/client.c

static const svn_ra__vtable_t ra_svn_vtable = {

  svn_ra_svn_version,

  ra_svn_get_description,

  ra_svn_get_schemes,

  ra_svn_open,

  ra_svn_reparent,

  ra_svn_get_session_url,

  ra_svn_get_latest_rev,

  ra_svn_get_dated_rev,

  ra_svn_change_rev_prop,

  ra_svn_rev_proplist,

  ra_svn_rev_prop,

  ra_svn_commit,

   ….

}

svn_ra_svn__init(const svn_version_t *loader_version,..){

       *vtable = &ra_svn_vtable;

}

================

static const struct ra_lib_defn {

  /* the name of this RA library (e.g. "neon" or "local") */

  const char *ra_name;

  const char * const *schemes;

  /* the initialization function if linked in; otherwise, NULL */

  svn_ra__init_func_t initfunc;

  svn_ra_init_func_t compat_initfunc;

} ra_libraries[] = {

  {

    "neon",

    dav_schemes,

#ifdef SVN_LIBSVN_CLIENT_LINKS_RA_NEON

    svn_ra_neon__init,

    svn_ra_dav_init

#endif

  },

  {

    "svn",

    svn_schemes,

#ifdef SVN_LIBSVN_CLIENT_LINKS_RA_SVN

    svn_ra_svn__init,

    svn_ra_svn_init

#endif

====================

svn_error_t *svn_ra_open3(svn_ra_session_t **session_p, …){

    for (defn = ra_libraries; defn->ra_name != NULL; ++defn)

             svn_ra__init_func_t initfunc = defn->initfunc;

             SVN_ERR(initfunc(svn_ra_version(), &vtable, pool));

      }

 session->vtable = vtable;

  *session_p = session;

}

copy_revprops_cmd {

SVN_ERR(svn_ra_open3(&to_session, baton->to_url, NULL,
                      &(
baton->sync_callbacks), baton, baton->config, pool));
 SVN_ERR(check_if_session_is_at_repos_root(to_session, baton->to_url, pool));
 SVN_ERR(with_locked(to_session, do_copy_revprops, baton, pool));

}

 --->  do_copy_revprops ….....

use to_session

Failure type

Incomplete execution

Is there any log message?

No

Can ErrLog insert a log message?

No