[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: Bert Huijben <rhuijben_at_sharpsvn.net>
Date: Sat, 27 Dec 2008 12:29:17 +0100

> -----Original Message-----
> From: Daniel Shahaf [mailto:d.s_at_daniel.shahaf.name]
> Sent: Saturday, December 27, 2008 11:27 AM
> To: Karl Fogel
> Cc: users_at_subversion.tigris.org; dev_at_subversion.tigris.org
> Subject: Re: Error when creating tags from working copy
>
> [ CCing dev@ ]
>
> Karl, is this bug still open? And how many bugs are there here (bug in
> mod_dav_svn? bug in the fs layer?)?
>
> I'd like to file an issue for it, at least, but I'm not sure I'll
> describe
> it correctly. Could you do that?

I tried to reopen this issue on the developer list in the
"Issue #3119 - File '...' already exists" (Regression since 1.5.0)" thread
on the development list.
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=985
284

We did some research but the thread died on the major problem that we can't
reproduce it at will.

To fully resolve this issue we really need a script that can reproduce the
issue every (or at least some of the) time.

I'm just guessing but maybe the following factors might help us:
* Which server versions have the issue? (1.5.x?) (1.4.x?)
* The issue was reported only to client versions after 1.5.0. Did somebody
reproduce it with a trunk build?

Original reporters, please fill in the missing details... we need your help
to resolve this issue.

Thanks,
        Bert

>
> Thanks,
>
> Daniel
>
>
> Karl Fogel wrote on Sat, 11 Oct 2008 at 18:25 -0400:
> > 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
>
> ------------------------------------------------------
> http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageI
> d=993658

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=993666

To unsubscribe from this discussion, e-mail: [users-unsubscribe_at_subversion.tigris.org].
Received on 2009-01-28 18:15:53 CET

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