A lot of the error handling in Darcs.Repository.PatchIndex is wrong. For
instance, canUsePatchIndex will crash with an error call if the patch
index exists and is disabled. OTOH, if _darcs/no_patch_index is not
writable then exactly that is the situation created by ignoring IO
errors. deletePatchIndex also calls "error" when there is an IO
exception instead of "fail" which is our de-facto convention.
It is usually not a good idea to catch IO exceptions without re-raising
them. Even if a failure may not be fatal immediately, as in the case of
_darcs/no_patch_index, this tends to cause problems later when the state
on disk doesn't meet our expectations. There are a few special
situations where this is okay, mostly composite actions like "remove
file unless it isn't there". We should strive to factor them to
Darcs.Util.File or a related module.
However, the PatchIndex has more fundamental problems. For instance, it
doesn't store all the touch information: if a tree item is touched, then
we regard all its parent directories as touched, too, but this
information is not stored in the PatchIndex, so we must re-construct it
afterwards. This is inefficient, it takes time quadratic in number of
children of a directory. Also, the representation it uses is too
complicated IMO. It would be simpler and more efficient to track tree
item identities directly i.e. assign them Int keys and track their
"current path" together with the informationa about which patch touches
which tree item.
|