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

Re: ancestor path / revision

From: Greg Stein <gstein_at_lyra.org>
Date: 2000-12-19 02:59:09 CET

On Mon, Dec 18, 2000 at 04:27:52PM -0800, Greg Stein wrote:
>...
> In the checkout case, it appears (again) only the revision is needed.
>
> It seems the path is only important on the commit side of things, as a way
> of tracking the ancestry of a change.
>
> It is non-orthogonal (the client doesn't need the path) because the client
> is a snapshot of state. It doesn't care *where* it came from. It is only
> concerned with changes made to it. (the client uses "svn log" to discover
> history information)
>
> [think think think]
>
> We have four "main" editor processes, and in all cases, the revision *must*
> be supplied to the editor:
>
> 1) report revision status [to determine what must be updated]
> - definitely need the revision; don't need the path, though
>
> 2) apply updates to the WC
> - need the revision so the WC knows what rev is now in the WC
>
> 3) commit WC changes to the server
> - need the path/revision pair to describe ancestry from a move/copy
> - need the revision to specify what a diff was built against
> - add file/dir: revision is N/A
>
> 4) checkout fresh source from the server
> - need the revision so the WC knows what rev is now in the WC
>
>
> How about if we upgrade revision to generally "required", and the "start
> from scratch" case allows a NULL/INVALID_REVNUM pair if there is no
> ancestor? And the path element is typically NULL.

[ thought more on the problem while running errands ]

We aren't supplying enough information in the editor callbacks.

Consider the case of "svn copy" (replacing a file) and then a commit. This
will map into a replace_file() call. We need to tell the system three pieces
of information:

1) the revision of the file we're replacing (was it the latest?)
2) the path of the file we copied
3) the revision of the file we copied

If we enumerate the different types of editor processes, and the add/replace
file/dir callbacks:

1) report revision status:
   a) add: old_revision=N/A, copyfrom_path=PATH|NULL,
           copyfrom_revision=REV|INVALID
   b) replace: old_revision=REV, copyfrom_path=PATH|NULL,
               copyfrom_revision=REV|INVALID

   [ these are the raw calls involved; the report editor will probably
     collapse these into "I have a file/dir here, possibly from <path>, with
     revision <rev>, possibly with local changes" ]

2) apply update to the WC:
   a) add: old_revision=N/A, copyfrom_path=NULL, copyfrom_rev=THIS_REV
   b) replace: old_revision=DIFF_BASE_REV, copyfrom_path=NULL,
               copyfrom_rev=THIS_REV

   path=NULL, rev=REV implies "this isn't copied from anywhere, and it
   refers to revision REV." Contrast with (1) which can say, "it was copied
   from revision REV of path PATH." In both cases, REV is the stated
   revision for the resource.

3) commit WC changes: same as (1)

   If the replace() copied from somewhere, then old_revision describes what
   revision was replaced. If there is no copy, then old_revision specifies
   the base for a "diff".

4) checkout:
   a) add: old_revision=N/A, copyfrom_path=NULL, copyfrom_rev=THIS_REV
   b) replace: not used
   
   This is the same as (2), but replace_*() is not used.

This gives us the two behaviors that we want to track:

1) specify the base revision that we are replacing
2) specify the ancestry when copying from another resource

Now, for some simpliciation. Note that the "add" case never specifies an
old_revision, so we're back to just the copyfrom_* parameters (although we
use them in two different ways). Here is a description of the semantics for
each combination of parameters:

ADD semantics:
  *) 1a, 3a: added a file, which may be a copy of COPYFROM, possibly with
             additional changes against that PATH/REV.
             (PATH, REV) or (NULL, INVALID)

  *) 2a, 4a: here is rev THIS_REV of the file
             (THIS_REV)

REPLACE semantics:
  *) 1b: replaced revision REV of a file with new content, which may be a
         copy of COPYFROM
         (OLD_REV, PATH, REV) or (OLD_REV, NULL, INVALID)

  *) 2b: here is a diff against DIFF_BASE_REV of this file, it will be
         called THIS_REV after the update.
         (DIFF_BASE_REV, THIS_REV)

  *) 3b: here is a diff against DIFF_BASE_REV of this file
         (DIFF_BASE_REV, NULL, INVALID)

  *) 3b: revision REV of this file was replaced with COPYFROM, possibly with
         additional changes against that PATH/REV.
         (OLD_REV, PATH, REV)

[ hmm.... where to go with this... trying to find the "right" semantics ]

Okay. Let's do the ballon treatment and expand completely:

    add_* (void)
    set_revision (THIS_REV)
    replace_* (OLD_REV)
    copy_*_from (PATH, REV)
    apply_txdelta (void)

[ parameters not relevant to this discussion omitted ]

And then rejigger the process a bit:

1a) add_*(), maybe followed by copy_*_from(), maybe followed by
    apply_txdelta (the txdelta is optional cuz there may be no changes to
    the copied resource)

1b) replace_*(OLD_REV), maybed followed by copy_*_from()
    [ on status reporting, we may not need the copyfrom information; the
      server will not issue an update against the copied resource, but it
      could issue a conflict if OLD_REV < LATEST_REV ]

2a) add_*(), followed by apply_txdelta(), followed by set_revision(THIS_REV)

2b) replace_*(OLD_REV), followed by apply_txdelta(), followed by
    set_revision(THIS_REV)

3a) add_*(), maybe followed by copy_*_from(), maybe followed by
    apply_txdelta()

3b) replace_*(OLD_REV), maybe followed by copy_*_from(), maybe followed by
    apply_txdelta()

4a) same as (2a): add_*(), followed by apply_txdelta(), followed by
    set_revision(THIS_REV)

Okay... enough stream of consciousness for now :-)

Thoughts on the direction? Basically, I think that I'm proposing to rejigger
the editor callbacks' params, and to add set_revision() and copy_*_from().
There could very well be some simplification / collapsing of the interface;
this has all been pretty much on the fly and still needs to settle a bit in
my head.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/
Received on Sat Oct 21 14:36:17 2006

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