Subject: Re: [PATCH v8 41/44] refs.c: add a new flag for transaction delete for refs we know are packed only

From: Jonathan Nieder <[email-masked]>
Date: Thu, 22 May 2014 16:44:40 -0700

Ronnie Sahlberg wrote:

> I hate rename_ref :-)
>
> I have reworked the transaction code to special case the deletion of
> the old ref for n/n -> n  and n -> n/n renames
> so that we can carefully avoid n/n.lock files to exist or prevent the
> directory <-> file transition for n during these renames.

Thanks.

I suspect the REF_ISRENAME flag shouldn't be needed.  Wouldn't
something like the following work (in _commit)?

	Allocate work space
	Copy sort, and reject duplicate refs
	Acquire all locks while verifying old values
		This calls is_refname_available.
		If a refname is unavailable, goto slowpath.
	Perform updates first so live commits remain referenced.
	Perform deletes now that updates are safely completed.
	Done.

 slowpath:
	Acquire locks, telling is_refname_available not to worry
		about deleted refs.
	Lock packed-refs.
	Add all relevant refs to packed-refs (pack_if_possible_fn).
	Commit packed-refs.
	Unlink the corresponding loose refs so packed-refs
		becomes authoritative for them.
	Lock packed-refs.
	Perform updates and removals in the packed-refs cache.
	Commit packed-refs.
	Release locks.
	Done.

This wouldn't be any slower for the case without D/F conflicts, and in
the D/F conflict case, it should work for arbitrary transactions
that want to remove one ref to make room for another.