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

Re: Error when creating tags from working copy

From: David Weintraub <qazwart_at_gmail.com>
Date: Thu, 27 Nov 2008 14:36:28 -0500

What if you do an "svn update" before you do your copy?

--
David Weintraub
qazwart_at_gmail.com
On Thu, Nov 27, 2008 at 2:43 AM, Michael Susser <hdmlist_at_googlemail.com>wrote:
> I have read that Karl has retired ;-) Is there anybody else who can help
> me?
>
> Regards,
> Michael
>
>
> 2008/10/26 Karl Fogel <kfogel_at_red-bean.com>
>
>  "Michael Susser" <hdmlist_at_googlemail.com> writes:
>> > do you have any news?
>>
>> Not yet, but I've been traveling for more than a week now and haven't
>> had time to dig further yet.  I will post here as soon as I know more.
>>
>> -Karl
>>
>> > Greetings,
>> > Michael
>> >
>> > 2008/10/12 Karl Fogel <kfogel_at_red-bean.com>
>> >
>> >     This is a deep one.  I'm posting what I've learned so far in case
>> anyone
>> >     has any hunches.  On the client, the problem is that in
>> >
>> >       libsvn_ra_neon/commit.c:commit_add_file()
>> >
>> >     the following code should get a "file not found" error (i.e., an
>> HTTP
>> >     404) when it probes for the existence of the file we're about to
>> add,
>> >     but doesn't -- instead, it's as though the file already exists:
>> >
>> >          svn_ra_neon__resource_t *res;
>> >          svn_error_t *err = svn_ra_neon__get_starting_props(&res,
>> >
>> file->cc->ras,
>> >
>> file->rsrc->wr_url,
>> >                                                             NULL,
>> workpool);
>> >          if (!err)
>> >            {
>> >              /* If the PROPFIND succeeds the file already exists */
>> >              return svn_error_createf(SVN_ERR_RA_DAV_ALREADY_EXISTS,
>> NULL,
>> >                                       _("File '%s' already exists"),
>> >                                       file->rsrc->url);
>> >            }
>> >
>> >     Here's what happens on the server side.  Let's shortcut directly to
>> >     mod_dav_svn/repos.c:get_resource().  Before the call to
>> >     prep_resource()...
>> >
>> >      /* prepare the resource for operation */
>> >      if ((err = prep_resource(comb)) != NULL)
>> >        return err;
>> >
>> >     ...comb->exists is 0, as we would want (so is comb->res.exists, for
>> that
>> >     matter).  But after prep_resource(), comb->exists is 1!
>> >
>> >     prep_resource() is just a dispatch function; the real stuff happens
>> in
>> >     prep_working() (because comb->res.type ==
>> DAV_RESOURCE_TYPE_WORKING).
>> >     In prep_working(), we get all the way to this code near the end:
>> >
>> >      derr = fs_check_path(&kind, comb->priv.root.root,
>> >                           comb->priv.repos_path, pool);
>> >
>> >      if (derr != NULL)
>> >        return derr;
>> >
>> >      comb->res.exists = (kind == svn_node_none) ? FALSE : TRUE;
>> >      comb->res.collection = (kind == svn_node_dir) ? TRUE : FALSE;
>> >
>> >     So that's where comb->res.exists gets set to 1.  (I'm not sure where
>> >     comb->exists gets set to 1, which might be important, but see
>> below.)
>> >
>> >     Anyway, that call to fs_check_path() sets kind to svn_node_file,
>> even
>> >     though the file shouldn't be present in this txn yet (that's why
>> we're
>> >     adding it).
>> >
>> >     Tracing fs_check_path --> svn_fs_fs__check_path() --> node_kind()
>> -->
>> >     fs_node_id() --> get_dag() --> open_path() -->
>> svn_fs_fs__dag_open(),
>> >     shows that, somehow, the file is actually there, according to the
>> FS.
>> >     (It does not appear to be a dag node caching problem; the node isn't
>> >     found in the cache, instead we find it the old-fashioned way, right
>> >     there in the filesystem.)
>> >
>> >     Back up in
>> http-2.2.9/modules/dav/main/mod_dav.c:dav_method_propfind(),
>> >     this all matters because of this code:
>> >
>> >        /* Ask repository module to resolve the resource */
>> >        err = dav_get_resource(r, 1 /* label_allowed */, 0 /*
>> use_checked_in */,
>> >                               &resource);
>> >        if (err != NULL)
>> >            return dav_handle_err(r, err, NULL);
>> >
>> >        if (dav_get_resource_state(r, resource) == DAV_RESOURCE_NULL) {
>> >            /* Apache will supply a default error for this. */
>> >            return HTTP_NOT_FOUND;
>> >        }
>> >
>> >     Not only does dav_get_resource() not get an error, but the call to
>> >     dav_get_resource_state() will not return DAV_RESOURCE_NULL, because
>> that
>> >     code (in httpd-2.2.9/modules/dav/main/util_lock.c) says:
>> >
>> >        if (resource->exists)
>> >            return DAV_RESOURCE_EXISTS;
>> >
>> >     Boom.  If it weren't for that, the function would return
>> >     DAV_RESOURCE_NULL and we'd be fine.
>> >
>> >     Note that in the reproduction recipe, if you insert an "svn up
>> Data/wc"
>> >     right before the final svn cp in the reproduction recipe, then none
>> of
>> >     this weirdness happens, and the bug doesn't reproduce.
>> >
>> >     So why does the file claim to be present in the txn already?  And
>> why
>> >     does updating the whole working copy to r2 (instead of having a
>> mixed
>> >     r1/r2 working copy) cause the repository filesystem to correctly
>> answer
>> >     that the file is not there?
>> >
>> >     I don't know.  I will continue to debug, but if anyone has any
>> inspired
>> >     ideas, please post.
>> >
>> >     -Karl
>> >
>> >     Karl Fogel <kfogel_at_red-bean.com> writes:
>> >     > "Michael Susser" <hdmlist_at_googlemail.com> writes:
>> >     >> i have found a bug when creating tags from working copy in svn
>> 1.5.2
>> >     >> (and also 1.5.3). Here is a recipe how to reproduce the error:
>> (my
>> >     >> apache is configured to host the repositories in E:\SVNRep)
>> >     >>
>> >     >> [...]
>> >     >>
>> >     >> svn copy -m"tagging" E:\Data\wc\trunk
>> http://myserver/svn/repo/tags/
>> >     V1.0.0
>> >     >>>svn: Commit failed (details follow):
>> >     >>>svn: File '/svn/repo/tags/V1.0.0/dir/file.cpp' already exists
>> >     >
>> >     > Thank you for the excellent recipe.  I can reproduce this, and
>> have
>> >     > written a Unix Bourne shell reproduction script (see below).  Note
>> that
>> >     > this only reproduces over http://.  If you try it with svn:// or
>> >     > file://, the tagging works fine.
>> >     >
>> >     >> This error message is absolutely wrong! I investigated what went
>> wrong
>> >     and
>> >     >> found the following: after the commit action the working copy is
>> not
>> >     updated
>> >     >> correctly(?). The changed file "file.cpp" gets a new revision
>> (2), but
>> >     its
>> >     >> parent directory "dir" stays at revision 1. Is this ok?
>> >     >
>> >     > Well, that part is okay.  When you commit, only the committed
>> items get
>> >     > their revisions bumped locally -- in other words, a commit does
>> not do
>> >     > an update on the items that are not part of the commit.  However,
>> >     > Subversion is supposed to transparently handle the resultant mixed
>> >     > revisions.  They shouldn't matter here.
>> >     >
>> >     > This bug seems familiar, like we've either fixed it before or
>> filed an
>> >     > issue for it.  I'll check the logs and the issue tracker.  But we
>> have a
>> >     > reproduction recipe, so that means we can fix it or re-fix it :-).
>> >     >
>> >     >
>> >
>> ----------------------------------------------------------------------------
>> >     > #!/bin/sh
>> >     >
>> >     > # The next line is the only line you should need to adjust.
>> >     > SVNDIR=/home/kfogel/src/subversion
>> >     >
>> >     > SVN=${SVNDIR}/subversion/svn/svn
>> >     > SVNSERVE=${SVNDIR}/subversion/svnserve/svnserve
>> >     > SVNADMIN=${SVNDIR}/subversion/svnadmin/svnadmin
>> >     >
>> >     > # Select an access method.  If svn://, the svnserve setup is
>> >     > # handled automagically by this script; but if http://, then
>> >     > # you'll have to configure it yourself first.
>> >     > #
>> >     > URL=http://localhost/ms/repos
>> >     > # URL=svn://localhost/repos
>> >     > # URL=file:///`pwd`/repos
>> >     >
>> >     > rm -rf repos wc Data import-me
>> >     >
>> >     > ${SVNADMIN} create repos
>> >     >
>> >     > # These are for svnserve only.
>> >     > echo "[general]" > repos/conf/svnserve.conf
>> >     > echo "anon-access = write" >> repos/conf/svnserve.conf
>> >     > echo "auth-access = write" >> repos/conf/svnserve.conf
>> >     >
>> >     > # The server will only be contacted if $URL is svn://foo, of
>> course.
>> >     > ${SVNSERVE} --pid-file svnserve-pid -d -r `pwd`
>> >     > # And put the kill command in a file, in case need to run it
>> manually.
>> >     > echo "kill -9 `cat svnserve-pid`" > k
>> >     > chmod a+rwx k
>> >     >
>> >     > mkdir Data
>> >     > svn co ${URL} Data/wc
>> >     > mkdir Data/wc/tags
>> >     > mkdir Data/wc/trunk
>> >     > mkdir Data/wc/trunk/dir
>> >     > cp /dev/null Data/wc/trunk/dir/file.cpp
>> >     > ${SVN} add Data/wc/t*
>> >     > ${SVN} ci -m"test" Data/wc
>> >     >
>> >     > echo "ABC" >> Data/wc/trunk/dir/file.cpp
>> >     >
>> >     > ${SVN} ci -m"test" Data/wc
>> >     >
>> >     > # Using http:// only, the next command fails with this error:
>> >     > #
>> >     > #    subversion/libsvn_client/copy.c:1319: (apr_err=175005)
>> >     > #    svn: Commit failed (details follow):
>> >     > #    subversion/libsvn_ra_neon/commit.c:1036: (apr_err=175005)
>> >     > #    svn: File '/ms/repos/tags/V1.0.0/dir/file.cpp' already exists
>> >     > #
>> >     > ${SVN} copy -m"tagging" Data/wc/trunk ${URL}/tags/V1.0.0
>> >     >
>> >     > ./k
>> >
>> >
>> ---------------------------------------------------------------------
>> >     To unsubscribe, e-mail: users-unsubscribe_at_subversion.tigris.org
>> >     For additional commands, e-mail: users-help_at_subversion.tigris.org
>>
>
>
Received on 2008-11-27 20:36:56 CET

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

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