svn-3552

Version:

1.6.6 (patched on 1.6.10)

Bug Link:

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

Patch Link:

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

reproduction: http://subversion.tigris.org/nonav/issues/showattachment.cgi/1076/issue3552.sh

Symptom:

*background: ‘externals definition’ is a mapping of a local directory to the URL using the propery ‘svn:externals’. Conceptually it is like a symbolic link to a physical file located in another repository. It enables files to be fetched from multiple repositories using one ‘virtual’ name instead of the working repository.

 

When copying external file using

                    ‘svn cp –ignore-externals trunk/dir2 file://repos/tags/1.0 -m ‘creating tag’’

External file is physically copied into our own repository -- this is wrong! we should not physically copy, but instead create another external file link (symbolic link).

As consequence, later when users are updating, the will print the following error message:

vn up’

 

*Result: svn: warning: The file external from 'file:///home/yyzhou/mmlee/LOG-project/svn/                                                                                                                                   3552/repos/trunk/dir1/file1.txt' cannot overwrite the existing versioned item at                                                                                                                                    '/home/yyzhou/mmlee/LOG-project/svn/3552/wc1/tags/1.0/file1.txt'

File external from URL cannot overwrite the existing versioned item. 

How it is diagnosed:

reproduced

 

How to reproduce:

Run http://subversion.tigris.org/nonav/issues/showattachment.cgi/1076/issue3552.sh

 

Step1) set the external file ‘file1.txt’ on ‘/trunk/dir2’ from ‘/trunk/dir1’.

                    ‘svn pset svn:externals ‘^/trunk/dir1/file1.tsxt file1.txt’ ‘trunk/dir2’

Step2) commit the changes including setting external file.

                    ‘svn ci –m ‘adding file and externals’’

Step3) make a tag of current ‘trunk/dir2’ including externals definition

                    ‘svn cp –ignore-externals trunk/dir2 file://repos/tags/1.0 -m ‘creating tag’’

Step4) update the working copy

                    ‘svn up’

 

*Result: svn: warning: The file external from 'file:///home/yyzhou/mmlee/LOG-project/svn/                                                                                                                                   3552/repos/trunk/dir1/file1.txt' cannot overwrite the existing versioned item at                                                                                                                                    '/home/yyzhou/mmlee/LOG-project/svn/3552/wc1/tags/1.0/file1.txt'

Root Cause:

Brief:

Do not commit a file externals during a ‘svn copy’

Detail:

Where the error message is printed:

 static svn_error_t *

switch_file_external(... ...)

{

  SVN_ERR(svn_wc_entry(&entry, path, target_adm_access, FALSE, subpool));

  /* Check the return value of svn_wc_entry: */

  if (entry)

        {

          if (! entry->file_external_path)

            {

              if (close_adm_access)

            SVN_ERR(svn_wc_adm_close2(target_adm_access, subpool));

 

              return svn_error_createf

                (SVN_ERR_CLIENT_FILE_EXTERNAL_OVERWRITE_VERSIONED, 0,

             _("The file external from '%s' cannot overwrite the existing "

               "versioned item at '%s'"),

                 url, path);

            }

}

/* Here is how “svn_wc_entry” returned error entry->file_external_path. */

svn_error_t *

svn_wc_entry(const svn_wc_entry_t **entry, ...) {

 

  if (dir_access)

    {

      apr_hash_t *entries;

      SVN_ERR(svn_wc_entries_read(&entries, dir_access, show_hidden, pool));

      *entry = apr_hash_get(entries, entry_name, APR_HASH_KEY_STRING);

    }

  else

    *entry = NULL;

  return SVN_NO_ERROR;

}

Patch:

if the file is ‘externals’ and command is ‘svn copy’ then, we just skip to commit that file to avoid the error message.

 

--- subversion/trunk/subversion/libsvn_client/commit_util.c           2009/12/17 12:29:04            891671

+++ subversion/trunk/subversion/libsvn_client/commit_util.c        2009/12/17 12:30:43            891672

@@ -430,6 +430,9 @@ harvest_committables(apr_hash_t *committ

              svn_dirent_local_style(path, scratch_pool));

         }

 

+  if (entry->file_external_path && copy_mode)

+        return SVN_NO_ERROR;

+

// just skip to commit the file with ‘externals definition’ during ‘svn copy’

 

   if (entry->kind == svn_node_dir)

         {

           /* Read the dir's own entries for use when recursing. */

Failure symptom category

refuse valid input, early termination

Is there any log message?

Yes

Can it be automatically inserted?

Yes -- function return value.