gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnu-arch-users] [BUG] feature plan -- Selected overlay


From: Tom Lord
Subject: [Gnu-arch-users] [BUG] feature plan -- Selected overlay
Date: Mon, 24 May 2004 16:57:17 -0700 (PDT)


Selections identify a subset of a tree.

Deleting by selection removes from a tree anything that might
have been modified by a selective commit using that same
selection.

The next idea is "overlaying a selection" --- replacing just the stuff
that matches a selection in one tree, taking it from the stuff that
matches a selection in another tree.

Earlier we decided on a requirement:

  Let's suppose that I do a partial commit in some directory using
  selection called SELECTION.  I would expect that to have a specific meaning
  in terms of "deleting a selection":

     Given ORIG (the revision before my commit)
     and   MOD  (the revision after my selected commit)

     Deleting SELECTION from both ORIG and MOD should leave 
     identical trees (i.e., nothing outside the selection is
     effected by the changes).


We can strengthen that requirement:

  Let's suppose that I do a partial commit in some directory using
  selection called SELECTION.  I would expect that to have a specific meaning
  in terms of "deleting a selection" and "overlaying a selection":

     Given ORIG (the revision before my commit)
     and   MOD  (the revision after my selected commit)

     Overlay the SELECTION parts of MOD onto ORIG.

     Now MOD and ORIG should be identical trees.


So, how is "overlaying" defined?  Overlaying has three arguments, an
ORIG tree, a MOD tree, and a SELECTION.   It's goal is to produce a TARGET
tree which contains ORIG with just some of the changes from MOD.
Below is an algorithm and I claim it has these properties (on cases
where it doesn't terminate with an error):


    1) TARGET will contain all items from ORIG which do not
       match the selection, none with modifications.

    2) Beyond those, TARGET will contain _only_ all items from
       MOD which match the selection.

    3) If an item "n"-matches MOD, then the contents of the file
       (target of symlink, permissions of any kind of file) will
       be copied from ORIG.   If it "b" or "c" matches, those things
       are copied from MOD.

    4) If an item "n"-matches or "b"-matches in MOD, then the tail
       of its location in TARGET will be the same as in MOD and the
       inventory id of its containing directory in TARGET will be 
       the same as the id of its containing directory in MOD.

    5) Similarly, if an item "c"-matches in MOD, then the tail
       of its location in TARGET will be the same as its tail in
       ORIG and the containing dir ids will also match.

I think those sum up pretty well everything one would want from a
selective commit.


1) Initialize TARGET to be a copy of ORIG

2) Delete SELECTION from TARGET

3) Let TO_COPY be the set of all inventory items in MOD that match
   the selection.

4) While TO_COPY is not empty

   {

      Let A_ROOT be a least-deep (path-wise) element of TO_COPY.

      If a file or symlink with the same inventory id already
      exists in TARGET, then report an error ("there was
      (most likely) a rename from outside the selection to inside
      the selection"). 


    if (A_ROOT matched in mod in class "c" ("changes only"))
      {
        if A_ROOT did not exist in ORIG, then report an error
         ("(most likely an) attempt to commit changes to a file
         not yet added") 

        DESIRED_HOMEDIR_ID = id of dir containing A_ROOT in ORIG
        DESIRED_TAIL = tail of location of A_ROOT in ORIG
      }
    else
      {
        DESIRED_HOMEDIR_ID = id of dir containing A_ROOT in MOD
        DESIRED_TAIL = tail of location of A_ROOT in MOD
      }

    if DESIRED_HOMEDIR_ID already exists in TARGET
      {
        DESIRED_HOMDIR = location of DESIRED_HOMEDIR_ID in TARGET
        DESIRED_PATH = DESIRED_HOMEDIR "/" DESIRED_TAIL

        if (DESIRED_PATH already exists in TARGET)
          report an error ("attempt to selection to a conflicting
          rename")

        copy A_ROOT (non-recursively) to TARGET at DESIRED_PATH.

        remove A_ROOT from TO_COPY
      }
    else if DESIRED_HOMEDIR_ID exists in TO_COPY
      {
        modify TO_COPY by rewriting all items at or below
        A_ROOT to reflect a rename into the path of DESIRED_HOMEDIR_ID

        If this results in duplicated locations or names, signal
          an error ("renames would conflict")

        Ensure that all of the renamed items in TO_COPY would still
        pass selections and produce the same result.   If not, signal
        an error ("unreported rename").
      }
   } /* while */


5) Sanity check deletions:

   Compare the set of files deleted in TARGET and in MOD relative to
   ORIG.

   If a file is deleted in TARGET but not in MOD, then report an error
   ("rename to outside of SELECTION")


-t

----

Like my work on GNU arch, Pika Scheme, and other technical contributions 
to the public sphere?   Show your support!

https://www.paypal.com/xclick/business=lord%40emf.net&item_name=support+for+arch+and+other+free+software+efforts+by+tom+lord&no_note=1&tax=0&currency_code=USD

and

address@hidden for www.moneybookers.com payments.


-----

        The cause of death is birth.
                        -- George Harrison





reply via email to

[Prev in Thread] Current Thread [Next in Thread]