tg: avoid tree turds
commitd6c26a541af59ac0a68c5160a99d84d1efab2976
authorKyle J. McKay <mackyle@gmail.com>
Mon, 20 Mar 2017 10:24:31 +0000 (20 03:24 -0700)
committerKyle J. McKay <mackyle@gmail.com>
Mon, 20 Mar 2017 10:24:31 +0000 (20 03:24 -0700)
treeedf4c0c24eadf2e95b874276b982c4f731e09147
parent2b3f9fe944bca713e7d1df3324aa9cb8759b9ddb
tg: avoid tree turds

Because TopGit stores its "meta" information (the .topmsg and
.topdeps files) in the repository alongside the TopGit-managed
changes, it's necessary to create "pretty" trees from time to
time in order to do proper diffs, check for empty branches,
export patches, etc.

There are two issues with this behavior:

 1) if a background gc is running it could potentially gc
    the temporary tree(s) out from under us before we've
    had a chance to use them

 2) if one of the TopGit "read-only" operations is run on
    a freshly gc'd repository with no loose objects, suddenly
    it will have loose, unreferenced objects and won't be as
    pristine as it was just after the "gc"

In practice though (1) is only a problem when expiring unreachable
objects immediately although there remains the potential for an
old enough loose object to be around that's the same temporary
tree from a previous check and it loses the "freshen" race against
the gc operation and still gets gc'd out from under us, but the
window of opportunity for that is very small.

On the other hand, (2) is just ugly and unfriendly and should be
avoided if possible.

To avoid the problem of leaving behind unreferenced temporary
trees in the object database, use the Git alternates mechanism
and create them in the temporary directory that "tg" creates for
its own use and automatically removes when it exits.

Only do this for "read-only" operations though as it's quite
possible that one of the temporary trees could end up being
referenced by a newly created commit by the non-read-only
operations and that would corrupt the database when those
objects just disappeared.

The other "gotcha" is that there are quoting issues with certain
characters in pathnames when used in the alternates environment
variable.  Those are checked for and, if present, inhibit the
use of an alternates location to avoid problems so you still end
up with tree turds in that case, but those problem characters
are not all that common in git repository path names.

Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
hooks/pre-commit.sh
tg-files.sh
tg-patch.sh
tg.sh