the inventory must be updated as merge proceeds, not at the end
John A Meinel
john at arbash-meinel.com
Wed Dec 28 17:11:23 GMT 2005
Denys Duchier wrote:
...
> Unfortunately, none of the filesystem surgery performed during merge
> is, at that point, reflected in the inventory. So, when the conflict
> handler attempts to fix the inventory, the latter may no longer be in
> synch with the tree.
>
> As a consequence of the desynchronization between inventory and
> filesystem, the following 2 kinds of incoherent situations may arise:
>
> 1. name conflicts in the filesystem not attested in the inventory
> 2. name conflicts in the inventory not attested in the filesystem
>
> I believe I have devised examples of both kinds. Btw, before I start
> with the examples, I'd like to say that I find it a little annoying
> that the following should fail:
>
> $ bzr init A
> $ bzr branch A B
> bzr: ERROR: exceptions.AssertionError: <type 'NoneType'>
> at /mnt/kubuntu/home/duchier/src/bzr.dev/bzrlib/branch.py line 928
> in get_inventory_xml
I think the particular failure (AssertionError) is bogus, I'm not sure
that trying to branch an empty branch is something which should succeed.
(but we could).
>
> 1. NAME CONFLICT IN THE FILESYSTEM NOT ATTESTED IN THE INVENTORY
...
> 2. NAME CONFLICT IN THE INVENTORY NOT ATTESTED IN THE FILESYSTEM
...
Thanks for the test cases. These look valid.
> My conclusion is that the surgical operations performed on the tree
> during merge ought to be made into "tree" operations, i.e. that affect
> both the filesystem and the inventory so that both remain accurately
> in synch at all times.
I think Aaron Bentley and myself agree with you here. I think the only
thing we were concerned with is if you actually write out the entire
inventory after every change. As this gets very expensive. My idea was
to write the .bzr/inventory in a try/finally, so that you can move files
around, and if you get an exception, you write out so that you represent
as many of the changes as possible.
> To this end, it becomes necessary to give
> official standing to the idea of "moving things into and out of temp".
> The idea that I started to explore is to extend the workingtree
> abstraction with a notion of limbo mediated by the following two
> operations:
>
> limbo_put(self, file_id)
>
> excise the subtree rooted at the entry identified by file_id
> and stash it away in limbo
>
> limbo_get(self, file_id, parent_id, name, conflict_handler)
>
> take the subtree stashed away in limbo and identified by
> file_id, and splice it into the working tree under the entry
> identified by parent_id, and the given name
>
> In my prototype, the tmp directory associated with limbo resides in
> .bzr/limbo and I use file_ids as filenames in that directory.
>
> Comments?
>
I'm not convinced of limbo_put/limbo_get. The merge code already has a
working temp directory 'bzr-tree-change'. My solution was to actually
make that directory versioned for the time that it exists. By adding it
temporarily, you don't violate any constraints about duplicate paths, etc.
Now, you can't name things by just their filename, since filenames can
conflict from different directories. And it is a little ugly to add
multiple directories in there. So it might be nicest to name them by
file-id.
Because an inventory has the concept that no 2 files can have the same
path or the same file-id, I think we would prevent conflicts inside the
temp directory.
> Cheers,
>
> --Denys
Oh, and one other thing. I have a small problem with your second test
case. Specifically, you are merging into a tree which has uncommitted
changes, which shouldn't even start without --force.
Second, you are assuming that 'rm foo' means that the file should be
removed from the inventory. Right now we have implicit delete on commit,
if the file is missing. But I thought the last discussion came up with
that this *shouldn't* happen, because a bad move can also make a file
look like it is deleted, rather than just renamed. So it is better to
require an explicit delete.
Which means that your test would become:
cd ../A
rm file
bzr rm file
bzr merge --force ../B
Without the 'bzr rm file' we should only think that the file is missing,
not truly removed. Because we can't tell difference between
rm file1
touch file2
and
mv file1 file2
Without informing bzr of what you are doing (with bzr mv or bzr rm),
both of these will give you an unknown file2 and a deleted file1.
John
=:->
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 249 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20051228/fc9c8573/attachment.pgp
More information about the bazaar
mailing list