You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Johan Corveleyn <jo...@uz.kuleuven.ac.be> on 2009/08/28 15:14:34 UTC

Cannot commit moved directory after adding (and committing) a child

I think I've seen this being discussed before (on the list or in the issue tracker), but can't find it again. So if anyone remembers, or can shed any light on this, I would very much appreciate it.

Following up on "tree changes that cause problems for wc-1 (and that I would like to verify if wc-ng will fix)", as in http://svn.haxx.se/users/archive-2009-08/0630.shtml, I saw some other strange behavior. I'm not sure whether this is a bug or "as designed":

Short description (recipe below): 
- Do some "tree action" (e.g. adding a file) in a directory. Commit it. 
- Then move the directory. Commit. 
- Error:
svn: Commit failed (details follow):
svn: Item '/trunk/test/test_moves/clean3/dir' is out of date

Going further:
- svn up: Tree conflict:
D     C dir
      >   local delete, incoming edit upon update
- svn resolve. Changes are now committed correctly.

I guess the basic explanation is that this is caused by the mixed revision thing (i.e. the directory is a revision number behind, after committing the new file). So it thinks it is out of date, although it obviously isn't (also, "svn st -u" reports nothing, so it too thinks the directory is really up to date). I would consider this a bug.


------------
Now in CLI speak (assuming wc with versioned directory "dir"):
$ echo test > dir/test.txt
$ svn add dir/test.txt
A         dir\test.txt

$ svn ci -m"test"
Adding         clean3\dir\test.txt
Transmitting file data .
Committed revision 96274.

$ svn info dir
...
Revision: 96273
...
Last Changed Rev: 96273
...

$ svn st -u
Status against revision:  96274

$ svn mv dir dir2
A         dir2
D         dir\test.txt
D         dir

$ svn ci -m"dir move mixed rev"
Deleting       clean3\dir
svn: Commit failed (details follow):
svn: Item '/trunk/test/test_moves/clean3/dir' is out of date

$ svn up
   C dir
At revision 96274.
Summary of conflicts:
  Tree conflicts: 1

$ svn st
A  +    dir2
D     C dir
      >   local delete, incoming edit upon update
D       dir\test.txt

$ svn resolve --accept=working dir
Resolved conflicted state of 'dir'

$ svn ci -m"dir move mixed rev"
Deleting       clean3\dir
Adding         clean3\dir2
Adding         clean3\dir2\test.txt

Committed revision 96275.

$ svn log -v dir2/test.txt
------------------------------------------------------------------------
r96275 | xxxxxx | 2009-08-28 16:45:10 +0200 (vr, 28 aug 2009) | 1 line
Changed paths:
   D /trunk/test/test_moves/clean3/dir
   A /trunk/test/test_moves/clean3/dir2 (from /trunk/test/test_moves/clean3/dir:96273)
   A /trunk/test/test_moves/clean3/dir2/test.txt (from /trunk/test/test_moves/clean3/dir/test.txt:96274)

dir move mixed rev
------------------------------------------------------------------------
r96274 | xxxxxx | 2009-08-28 16:42:10 +0200 (vr, 28 aug 2009) | 1 line
Changed paths:
   A /trunk/test/test_moves/clean3/dir/test.txt

test
------------------------------------------------------------------------

Regards,
Johan

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

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].


RE: Cannot commit moved directory after adding (and committing) a child

Posted by Johan Corveleyn <jo...@uz.kuleuven.ac.be>.
Ping - final call for feedback :). 
If I hear no objections within a couple of days, I'll file this as an issue.

In the meantime, I've noticed that http://subversion.tigris.org/issues/show_bug.cgi?id=1539 is similar to this issue. But it's not quite the same if I understand correctly.

Johan

> Van: Johan Corveleyn [mailto:johan.corveleyn@uz.kuleuven.ac.be]
> 
> Ping
> 
> Is there anyone who agrees or disagrees with the ideas explained
> below? Or is this totally naive or just plain stupid :) ?
> 
> Summary: after a tree change directly below a directory (e.g. file
> added/removed), I think SVN should bring the revision number of
> that directory up to date with the committed revision (like it does
> with a file after committing a modification to that file).
> 
> Rationale: I think a tree change below a directory is very similar
> to a content change of a file. I.e. the "contents" of the directory
> are modified. I think it should be handled as such. This would
> avoid the "self-inflicted tree conflict" described below (which is
> ultimately caused by the wc not being fully aware of the change it
> just committed).
> 
> Consequence: If the repository contains already another tree change
> in that directory (e.g. another file added), you will not be able
> to commit the addition of a file into it, until you update (merge)
> the directory. This is again exactly analogous to committing a file
> modification for a file that has been changed in the meantime (->
> out-of-date error).
> 
> Any feedback appreciated, even if it's only to point out any
> obvious flaws I'm overlooking ...
> 
> Regards,
> Johan
> 
> > Van: Johan Corveleyn [mailto:johan.corveleyn@uz.kuleuven.ac.be]
> > > Van: Stefan Sperling [mailto:stsp@elego.de]
> > > > Short description (recipe below):
> > > > - Do some "tree action" (e.g. adding a file) in a directory.
> > > Commit it.
> > > > - Then move the directory. Commit.
> > >
> > > Remember that in Subversion, a move equals copy+delete, which
> > > equals
> > > add-with-history+delete. I don't think that's particularly
> great,
> > > but it's the way it is.
> >
> > Yeah I know :). But that's not really the problem I think. I
> > suppose the same problem would occur if I just wanted to delete
> the
> > directory.
> >
> > >
> > > > - Error:
> > > > svn: Commit failed (details follow):
> > > > svn: Item '/trunk/test/test_moves/clean3/dir' is out of date
> > > >
> > [snip]
> >
> > > So to avoid your problem, you should update after committing
> the
> > > addition,
> > > and then do the move. Moving things around in mixed-revision
> > > working copies
> > > may work in some cases, but is a bad idea in general because of
> > > issues like
> > > this.
> > >
> > > WC-NG will really know what a "move" is, and the situation will
> > > gradually
> > > improve over time as the concept of "move" propagates through
> the
> > > system,
> > > from working copy to client->server interface to filesystem to
> > > server->client
> > > interface to working copy. There's a lot left to do before we
> get
> > > there.
> > >
> > > But the current behaviour is certainly intentional right now,
> and
> > > not a bug.
> >
> > Thanks for the explanation, Stefan. It made me understand better
> > and think harder (which is always a good thing :)). I understand
> > that this is currently the normal behavior (and I do believe you
> > that it will gradually improve with wc-ng, hopefully closely
> > followed by real move support and (better) tree conflict
> > resolution).
> >
> > However, all that aside, I still think there is something fishy
> > about the way this is handled. Theoretically speaking, it's
> really
> > a contradictory situation: I make a change, I commit that change,
> > and yet my WC is not fully up to date with the change I made (or
> at
> > least, it doesn't realize it is up to date).
> >
> > If I would consider a tree change directly under directory
> "mydir"
> > as a modification of its contents (just like editing a file is
> > modifying that file's contents), it seems logical to me that
> mydir
> > is brought fully up to date with the committed rev after
> committing
> > the addition of a file under it (just like committing a
> > modification to a file brings its revision number up to date in
> the
> > wc).
> >
> > This means that if, on committing the file addition, it's
> > discovered that the directory's lastChangeRev is higher that the
> > rev that had in my wc, I should then get an "out-of-date" error,
> > just like with committing files (someone else had modified the
> file
> > / dir in the meantime). On updating the dir, I could be lucky if
> > there is no conflict (e.g. someone else committed another file in
> > the dir, not conflicting with mine), so the "modified contents of
> > the directory" can be automatically merged. If I'm not so lucky,
> I
> > might have a tree conflict (which might in the future also be
> > automatically resolved). But at least, I can't be in conflict
> with
> > my own change...
> >
> > Does that make sense?
> >
> > I'm not saying SVN is totally wrong here, but I think the above
> > behavior would be better. Of course, I could just as well be
> > totally off base here, since I don't know SVN's internals nor the
> > details and trade-offs of its design.
> >
> > Thanks for your time.
> > Regards,
> > Johan
> >
> > ------------------------------------------------------
> >
> http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMes
> > sageId=2389575
> >
> > To unsubscribe from this discussion, e-mail: [users-
> > unsubscribe@subversion.tigris.org].
> 
> ------------------------------------------------------
> http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMes
> sageId=2392719
> 
> To unsubscribe from this discussion, e-mail: [users-
> unsubscribe@subversion.tigris.org].

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

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].

RE: Cannot commit moved directory after adding (and committing) a child

Posted by Johan Corveleyn <jo...@uz.kuleuven.ac.be>.
Ping
 
Is there anyone who agrees or disagrees with the ideas explained below? Or is this totally naive or just plain stupid :) ?

Summary: after a tree change directly below a directory (e.g. file added/removed), I think SVN should bring the revision number of that directory up to date with the committed revision (like it does with a file after committing a modification to that file).

Rationale: I think a tree change below a directory is very similar to a content change of a file. I.e. the "contents" of the directory are modified. I think it should be handled as such. This would avoid the "self-inflicted tree conflict" described below (which is ultimately caused by the wc not being fully aware of the change it just committed).

Consequence: If the repository contains already another tree change in that directory (e.g. another file added), you will not be able to commit the addition of a file into it, until you update (merge) the directory. This is again exactly analogous to committing a file modification for a file that has been changed in the meantime (-> out-of-date error).

Any feedback appreciated, even if it's only to point out any obvious flaws I'm overlooking ...

Regards,
Johan

> Van: Johan Corveleyn [mailto:johan.corveleyn@uz.kuleuven.ac.be]
> > Van: Stefan Sperling [mailto:stsp@elego.de]
> > > Short description (recipe below):
> > > - Do some "tree action" (e.g. adding a file) in a directory.
> > Commit it.
> > > - Then move the directory. Commit.
> >
> > Remember that in Subversion, a move equals copy+delete, which
> > equals
> > add-with-history+delete. I don't think that's particularly great,
> > but it's the way it is.
> 
> Yeah I know :). But that's not really the problem I think. I
> suppose the same problem would occur if I just wanted to delete the
> directory.
> 
> >
> > > - Error:
> > > svn: Commit failed (details follow):
> > > svn: Item '/trunk/test/test_moves/clean3/dir' is out of date
> > >
> [snip]
> 
> > So to avoid your problem, you should update after committing the
> > addition,
> > and then do the move. Moving things around in mixed-revision
> > working copies
> > may work in some cases, but is a bad idea in general because of
> > issues like
> > this.
> >
> > WC-NG will really know what a "move" is, and the situation will
> > gradually
> > improve over time as the concept of "move" propagates through the
> > system,
> > from working copy to client->server interface to filesystem to
> > server->client
> > interface to working copy. There's a lot left to do before we get
> > there.
> >
> > But the current behaviour is certainly intentional right now, and
> > not a bug.
> 
> Thanks for the explanation, Stefan. It made me understand better
> and think harder (which is always a good thing :)). I understand
> that this is currently the normal behavior (and I do believe you
> that it will gradually improve with wc-ng, hopefully closely
> followed by real move support and (better) tree conflict
> resolution).
> 
> However, all that aside, I still think there is something fishy
> about the way this is handled. Theoretically speaking, it's really
> a contradictory situation: I make a change, I commit that change,
> and yet my WC is not fully up to date with the change I made (or at
> least, it doesn't realize it is up to date).
> 
> If I would consider a tree change directly under directory "mydir"
> as a modification of its contents (just like editing a file is
> modifying that file's contents), it seems logical to me that mydir
> is brought fully up to date with the committed rev after committing
> the addition of a file under it (just like committing a
> modification to a file brings its revision number up to date in the
> wc).
> 
> This means that if, on committing the file addition, it's
> discovered that the directory's lastChangeRev is higher that the
> rev that had in my wc, I should then get an "out-of-date" error,
> just like with committing files (someone else had modified the file
> / dir in the meantime). On updating the dir, I could be lucky if
> there is no conflict (e.g. someone else committed another file in
> the dir, not conflicting with mine), so the "modified contents of
> the directory" can be automatically merged. If I'm not so lucky, I
> might have a tree conflict (which might in the future also be
> automatically resolved). But at least, I can't be in conflict with
> my own change...
> 
> Does that make sense?
> 
> I'm not saying SVN is totally wrong here, but I think the above
> behavior would be better. Of course, I could just as well be
> totally off base here, since I don't know SVN's internals nor the
> details and trade-offs of its design.
> 
> Thanks for your time.
> Regards,
> Johan
> 
> ------------------------------------------------------
> http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMes
> sageId=2389575
> 
> To unsubscribe from this discussion, e-mail: [users-
> unsubscribe@subversion.tigris.org].

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

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].


RE: Cannot commit moved directory after adding (and committing) a child

Posted by Johan Corveleyn <jo...@uz.kuleuven.ac.be>.
> Van: Stefan Sperling [mailto:stsp@elego.de]
> > Short description (recipe below):
> > - Do some "tree action" (e.g. adding a file) in a directory.
> Commit it.
> > - Then move the directory. Commit.
> 
> Remember that in Subversion, a move equals copy+delete, which
> equals
> add-with-history+delete. I don't think that's particularly great,
> but it's the way it is.

Yeah I know :). But that's not really the problem I think. I suppose the same problem would occur if I just wanted to delete the directory.

> 
> > - Error:
> > svn: Commit failed (details follow):
> > svn: Item '/trunk/test/test_moves/clean3/dir' is out of date
> > 
[snip]
 
> So to avoid your problem, you should update after committing the
> addition,
> and then do the move. Moving things around in mixed-revision
> working copies
> may work in some cases, but is a bad idea in general because of
> issues like
> this.
> 
> WC-NG will really know what a "move" is, and the situation will
> gradually
> improve over time as the concept of "move" propagates through the
> system,
> from working copy to client->server interface to filesystem to
> server->client
> interface to working copy. There's a lot left to do before we get
> there.
> 
> But the current behaviour is certainly intentional right now, and
> not a bug.

Thanks for the explanation, Stefan. It made me understand better and think harder (which is always a good thing :)). I understand that this is currently the normal behavior (and I do believe you that it will gradually improve with wc-ng, hopefully closely followed by real move support and (better) tree conflict resolution).

However, all that aside, I still think there is something fishy about the way this is handled. Theoretically speaking, it's really a contradictory situation: I make a change, I commit that change, and yet my WC is not fully up to date with the change I made (or at least, it doesn't realize it is up to date).

If I would consider a tree change directly under directory "mydir" as a modification of its contents (just like editing a file is modifying that file's contents), it seems logical to me that mydir is brought fully up to date with the committed rev after committing the addition of a file under it (just like committing a modification to a file brings its revision number up to date in the wc).

This means that if, on committing the file addition, it's discovered that the directory's lastChangeRev is higher that the rev that had in my wc, I should then get an "out-of-date" error, just like with committing files (someone else had modified the file / dir in the meantime). On updating the dir, I could be lucky if there is no conflict (e.g. someone else committed another file in the dir, not conflicting with mine), so the "modified contents of the directory" can be automatically merged. If I'm not so lucky, I might have a tree conflict (which might in the future also be automatically resolved). But at least, I can't be in conflict with my own change...

Does that make sense? 

I'm not saying SVN is totally wrong here, but I think the above behavior would be better. Of course, I could just as well be totally off base here, since I don't know SVN's internals nor the details and trade-offs of its design.

Thanks for your time.
Regards,
Johan

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

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].


Re: Cannot commit moved directory after adding (and committing) a child

Posted by Stefan Sperling <st...@elego.de>.
On Fri, Aug 28, 2009 at 05:14:34PM +0200, Johan Corveleyn wrote:
> I think I've seen this being discussed before (on the list or in the issue tracker), but can't find it again. So if anyone remembers, or can shed any light on this, I would very much appreciate it.
> 
> Following up on "tree changes that cause problems for wc-1 (and that I would like to verify if wc-ng will fix)", as in http://svn.haxx.se/users/archive-2009-08/0630.shtml, I saw some other strange behavior. I'm not sure whether this is a bug or "as designed":
> 
> Short description (recipe below): 
> - Do some "tree action" (e.g. adding a file) in a directory. Commit it. 
> - Then move the directory. Commit. 

Remember that in Subversion, a move equals copy+delete, which equals
add-with-history+delete. I don't think that's particularly great,
but it's the way it is.

> - Error:
> svn: Commit failed (details follow):
> svn: Item '/trunk/test/test_moves/clean3/dir' is out of date
> 
> Going further:
> - svn up: Tree conflict:
> D     C dir
>       >   local delete, incoming edit upon update
> - svn resolve. Changes are now committed correctly.
> 
> I guess the basic explanation is that this is caused by the mixed revision thing (i.e. the directory is a revision number behind, after committing the new file). So it thinks it is out of date, although it obviously isn't (also, "svn st -u" reports nothing, so it too thinks the directory is really up to date). I would consider this a bug.
> 

This is by design. When you commit, only the files/directories that
are actually changed by the commit ("commit targets") get their base
revisions bumped in the working copy. The other files/directories
(possibly including the directory you committed from) don't get
their base revisions bumped.
See also http://subversion.tigris.org/faq.html#hidden-log

'svn status -u' is right saying that there are no incoming changes.
What matters here is the base revision of the directory, as shown
by 'svn info'. If it isn't at HEAD, svn update will try to update
the directory to HEAD. Any local changes you have can then conflict
with this update.

I know this can be confusing, in particular because of tree conflicts
you can inflict upon yourself. But svn has no way of knowing that you
yourself just comitted the file addition which caused the directory
to be out-of-date during the second commit. And allowing an out-of-date
directory to be committed may cause certain tree conflicts not to be
detected, so svn can't allow you to do this.

E.g. committer_1 commits the result of "svn move a b", and committer_2
does "move a to c" and tries to commit this in the next revision.
This is clearly a tree conflict and needs to be detected. Committer_2's
commit needs to fail, to require an update which then shows the tree
conflict.
Note that, currently, this conflict is really flagged as "svn rm a"
vs. "svn rm a", which is a false positive in case both comitters really
deleted 'a' instead of moving it -- but there is no way to tell the
difference with the current design :(

So to avoid your problem, you should update after committing the addition,
and then do the move. Moving things around in mixed-revision working copies
may work in some cases, but is a bad idea in general because of issues like
this.

WC-NG will really know what a "move" is, and the situation will gradually
improve over time as the concept of "move" propagates through the system,
from working copy to client->server interface to filesystem to server->client
interface to working copy. There's a lot left to do before we get there.

But the current behaviour is certainly intentional right now, and not a bug.

Stefan

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

To unsubscribe from this discussion, e-mail: [users-unsubscribe@subversion.tigris.org].