[RFC] Transactional Tree Transforms

Aaron Bentley aaron.bentley at utoronto.ca
Mon Dec 12 15:46:59 GMT 2005


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,

I've been musing about a better way to handle tree transformations for a
while now.  What we currently have is based on the Arch technique of
manipulating the tree by changesets, but I think this is not quite
general or reliable enough.

Here are some requirements that seem important to me:
1. should be robust in the face of filesystem inconsitencies
2. scope should include both versioned and unversioned files
3. it would be very nice to support incremental construction
4. the intermediate forms should permit trees that violate POSIX or bzr
invariants

Here is the approach I've come up with.  There will be a new object
called a TreeTransform.  You'll call any number of filesystem-like
operations on it.  When you are done, you may check for conflicts and
resolve them.  Then you commit the transform.  If there are unresolved
conflicts at that point, an exception will be thrown.  Otherwise, the
transform will be applied.

Unfortunately, I believe it's necessary to introduce a new set of file
ids, because requirement 4 means that filenames may be ambiguous.  And
there may also be situations in which inventory ids are

Note that only filesystem and inventory conflicts are handled by this
interface.  I think the main conflict types are:
1. Two files with the same name
2. Two versioned files with the same inventory id
3. The parent of a file is not a directory
4. Filename is not POSIX-compliant.

As an API, this looks something like:
class TreeTransform(object):
    def __init__(working_tree):
    ...
    def create_versioned_file(self, parent, name, contents_iter,
                              inventory_id):
    ...
    def create_unversioned_file(self, parent, name, contents_iter):
    ...
    def replace_file(self, transaction_id, contents_iter):
    ...
    def replace_symlink(self, transaction_id, target):
    ...
    def rename(self, transaction_id, parent, name):
    ...
    def delete(self, transaction_id):
    ...
    def get_conflict(self)
    """Return the first conflict it finds."""
    ...
    def commit(self)
    ...
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDnZtz0F+nu1YWqI0RArIrAKCFtoL346fChtwkMWJJdt0SzehMngCfdJGj
qE2LqQgHxRgkd3yz7yAgIKU=
=Djdh
-----END PGP SIGNATURE-----




More information about the bazaar mailing list