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

Re: RFC: How should Subversion handle OS-deleted paths?

From: Julian Foad <julian.foad_at_wandisco.com>
Date: Tue, 24 Aug 2010 12:25:08 +0100

On Fri, 2010-08-20, Paul Burba wrote:
> I think we can all agree that when a user deletes part of their WC via
> the OS they have made a mistake of some sort. But which mistake
> exactly? The obvious answer is that they really intended 'svn del
> dirX/foo.c'. But possibly they intended something more akin to 'svn
> up --set-depth empty dirX'. Or maybe it was just a true mistake, and
> nothing was intended; they expect foo.c to be there!

Or maybe the user *renamed* or *moved* the item to a different path,
where it still exists complete with its local mods, and when the user
realizes they should have used "svn mv" instead, they will want to issue
the as-yet-unavailable "svn mv --retrospectively" command [1], or,
failing that, they will want to move the item back into place and then
issue the correct "svn mv".

So there are several courses of action that the user might want. Is
there an obvious, simple and "safe" default action that Subversion could
take in order to resolve each missing item it encounters? I think there
isn't.

> I originally came to this question when dealing with merge tracking
> and paths missing because they were deleted outside of Subversion, see
> http://svn.haxx.se/dev/archive-2010-08/0156.shtml.
>
> Somewhat tardily I realized the *first* question to be answered is not
> how merge tracking should deal with such paths, but how should
> Subversion in general deal with them.
>
> I see a few basic approaches:
>
> 1) Consistent Approach -- Restore the Missing Paths (unless there is
> really a compelling reason not too, but the default approach is to
> restore)
>
> WCNG's single DB allows us to simply restore these missing paths as we
> encounter them (the notable exception being 'svn st' of course, which
> just reports the missing state).

For a file, the working properties (stored in ACTUAL_NODE table) are
still known to Subversion, whereas its working text is NOT known to
Subversion. So Subversion could "restore" the item by:

  * reverting the file text and keeping the working properties, or

  * reverting the file text and reverting the properties.

For a directory, that applies to each versioned file inside it, as well
as to the properties on the directories themselves. (Any unversioned
items inside it would of course be lost.)

Is either of those ways obviously the "right" way to restore? I would
suggest neither is obviously the right one.

> Exhibit A of this behavior: In 1.6.x and 1.7 in multiple DB mode, svn
> revert skips missing directories. In single-DB mode they are
> restored.

Here, they are "restored" in the second sense above - i.e. "reverted".

> 2) Consistent Approach: Error out
>
> If we detect missing paths, simply throw an error asking that the user
> restore them before proceeding. Obviously for svn st/up/revert, the
> current behavior is fine, but for svn ci/sw/merge we could follow this
> route.

I think this is a good approach for ci/sw/merge and in fact most
commands. It is the simplest approach and that counts for a lot.

> 3) Case-by-Case Approach:
>
> Maybe there is *no* consistent approach, and sometimes we will want to
> restore, but other times we'll do something else. I'll leave what
> "something else" is as an open question for the moment.

I think consistency is important, but I'm not seeing a single behaviour
that's suitable for all commands. Let me see...

"svn revert" should of course restore any missing thing back to its last
versioned state, because that's it's job. (In 1.6 and earlier, it was
unable to restore missing directories, which was always known as a
deficiency.)

"svn status" should of course report the problem, because that's its
job.

"svn delete" could throw an error, or it could ignore the inconsistency
and just schedule the thing for deletion anyway. (I suppose we could
consider the latter behaviour to be first restoring and then deleting,
in one operation.) Same for any other UI that's able to make the node
go away such as "svn up --set-depth empty PARENT_PATH".

"svn diff" and "svn blame" I think should throw an error if trying to
access the missing text of the node. (Same for "svn cat -rWORKING" if
we ever support that.) I don't see any good reason for read-only
commands such as these to attempt to "fix" a problem.

"svn copy" and "svn move" where the source is missing: throw an error.
They could perhaps alternatively perform a copy or move in which the
target working file/dir is still missing, but that's greater complexity
and I see no benefit.

"svn export": throw an error. It could perhaps alternatively skip the
missing node, on the basis that its job is to re-create the current
working state of the WC, but I think we can define 'missing' as an
invalid (unacceptable) state.

"svn cleanup": throw an error if it needs to access the missing working
version, else no effect.

I would say "update"'s auto-restoring behaviour is a historical wart. I
think it was for compatibility with CVS. I won't try to argue that we
should change it now.

The pattern that's emerging from my thoughts is: throw an error if
logically we need to access the missing working version of the node. If
we don't need to access it, just let it be. Never "restore" it unless
the user specifically requests so and says what kind of restoration is
required.

For these reasons I think "merge" should also throw an error if it needs
to merge changes into a missing node. (If instead it needs to delete
it, then it has the options I mentioned for "svn delete".)

But I suspect part of the reason why "restore" seems an attractive
option is because Subversion isn't very friendly when "merge" stops with
an error. We don't provide any way to resume the same merge, and we
don't make it particularly easy to roll back the merge (although that's
getting better now that "revert" is, I hope, going to remove nodes that
it created by copying), and we don't have any way at all to roll back a
merge performed in a non-clean WC. So we're trying to avoid erroring
out.

Long term, those difficult problems are are the problems we should be
looking to solve. Short term, I suppose it's useful to avoid erroring
out as much as we can. If that's the important issue, and we recognize
it as such, then I could support the idea of "merge" doing this
"restore" while other commands don't.

> Any ideas as to the best approach? I suspect that some of the wcng
> folks have given some thought to this.

(It's a UI question rather than a WC layer question, so perhaps not.)

- Julian

[1] A "--retrospectively" flag for operations such as "move" and "copy"
is an enhancement that's been requested and that some other VCS's have a
way to do.
Received on 2010-08-24 13:25:50 CEST

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