'bzr checkout transform conflict policy'

Aaron Bentley aaron.bentley at utoronto.ca
Tue Aug 1 14:29:19 BST 2006


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

Robert Collins wrote:
> Aaron - this is the description of behaviour I'd like to see for
> checkouts when a file exists...

Great.  Should this be in play every time we produce a working tree, or
just when creating a checkout?

You'll want a function something like this:

def resolve_checkout_conflicts(tt):
    conflicts = tt.find_conflicts()
    new_conflicts = set()
    for c_type, conflict in ((c[0], c) for c in conflicts):
        # Anything but a 'duplicate' would indicate programmer error
        assert c_type == 'duplicate'
        # Now figure out which is new and which is old
        if tt.path_changed(conflict[1]):
            new_file = conflict[1]
            old_file = conflict[2]
        else:
            new_file = conflict[2]
            old_file = conflict[1]
        if tt.final_kind(old_file) == "file":
            # handle files here, continue if resolved
        if tt.final_kind(old_file) == "symlink":
            # handle symlinks here, continue if resolved
        if tt.final_kind(old_file) == "directory":
            # handle directories here, continue if resolved

        # We should only get here if the conflict wasn't completely
        # resolved
        final_parent = tt.final_parent(old_file)
        new_name = tt.final_name(old_file)+'.moved'
        tt.adjust_path(new_name, final_parent, old_file)
        new_conflicts.add((c_type, 'Moved existing file to',
                           old_file, new_file))

> So the behaviour I'd like is (in order of checks):
>  * if a path being made is contained by a sub-branch raise an error.
>  * when a directory already exists on disk its ok - no conflict needed.

We have not needed to expose a way to convert a trans_id to a tree path
until now.  The dict with this data is TreeTransform._tree_id_paths.

If you decide not to create the new directory, then you can call
cancel_creation and cancel_versioning on it.  You must then call
version_file() on the old directory.

Next call adjust_path() on every child of the new directory, to
re-parent them into the old directory.  This will frequently produce new
file conflicts.  You can add them to the 'conflicts' list now, or do
another pass.

>  * when a file or symlink already exists on disk, move it to path.moved
> if and only if the content differs.

To compare the content, you'll probably need to call _limbo_name() on
the new file.  There's clearly room for some API improvement here.

I don't know if you noticed, but your rules include cases where the
files on disk have different types from the files to be created.

I think there should be a rule that if the file on disk is a directory,
and the conflicting file is not a directory, the directory is renamed to
path.moved.

Otherwise, I think the rules are okay, even considering different types,
because directories can't have the same contents as files or symlinks,
and vice versa.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEz1cv0F+nu1YWqI0RAu48AJ9vye9Hgpiu9erIrTouAK7YlIfv1ACfVcDG
Z2Qv0KHZyrDgaLZzB2Rj3MQ=
=LKEU
-----END PGP SIGNATURE-----




More information about the bazaar mailing list