Well, your pseudo-code is as much about implementation as any other post
I've seen. "user-level abstraction" should only deal with externally
visible effects. I also have some issues with the algorithm you present...
What you end up with if you follow this procedure is rather odd. What
happens when "revision" becomes > "torev"? In your pseudo-code, you will
stop obliterating. But what does that mean? It means I have foo.c in
revisions <= "fromrev", then it vanishes, and then ANOTHER foo.c appears
by magic in revisions >= "torev". These two foo.c files will not be
related in the repository, which seems to me to be very odd.
I'm going to re-iterate what I've already said in this thread (and then
shut-up). I think the real need here is for a PRUNE command. That is,
given a file or folder and a rev number, remove that file in all
revisions up to the HEAD revision, following all branches from the
revision number onwards. That is, do a forward prune "up" the branch
tree. I think this is best because (a) it avoids orphaned files and
other oddities and (b) it handles pretty much all the real-world
scenarios mentioned in this thread, with the possible exception of
reclaiming disk space by eliminating older revisions, which IMHO should
be handled by "vertically" removing entire revisions and is not the job
of a prune/obliterate command anyway.
Anders J. Munch wrote:
>From: Tim Hill [mailto:firstname.lastname@example.org]
>>Basically, what obliterate has to do is kill *all* revisions of
>>foo.c, regardless of renames, throughout the entire branch tree.
>>Note that this will include tags also, which means that tags are no
>>longer invariant. Now *that* I find scary -- which is what puts me
>>off having this feature.
>Quite scary. I think that comes from specifying behaviour in terms of
>the implementation, not in terms of the user-level abstraction.
>In terms of the user-level abstraction, where a repo is an array of
>filesystem trees, obliterate could be defined as a rm on a range of
>virtual trees. Something like this pseudocode:
>def obliterate(obliteratepath, fromrev, torev):
> create a new, empty repository and check out to wcnew
> for each revision in the old repository:
> check out the full tree of that revision to wcold
> comment = the commit comment for the revision
> if fromrev<=revision<=torev:
> modify wcnew to match wcold
> rm obliteratepath in wcnew
> if obliteratepath existed:
> comment = patchcomment(comment, obliteratepath)
> commit wcnew -m comment
> optionally patch the GUID of newrepo
> replace sourcerepo with newrepo
>def patchcomment(comment, obliteratepath):
> if there is a obliteration-comment hook:
> return delegate-to-hook(comment, obliteratepath)
> return comment + '\nObliterated: ' + obliteratepath
>This is just for specification purposes, obviously a concrete
>implementation following this approach would be much, much slower than
>an implementation mucking with the DB directly could be, and use
>inordinate amounts of temporary disk space too.
Received on Tue Apr 19 19:17:35 2005