Subject: Re: [PATCH v3 00/14] ref-transactions-reflog

From: Jonathan Nieder <[email-masked]>
Date: Wed, 19 Nov 2014 19:24:53 -0800

Hi,

Stefan Beller wrote:

> Sorry for the long delay.
> Thanks for the explanation and discussion.
>
> So do I understand it right, that you are not opposing
> the introduction of "everything should go through transactions"
> but rather the detail and abstraction level of the API?

For what it's worth, I don't personally think it makes sense to put
the options supported by 'git reflog expire' into the transaction API
as top-level functions.

Instead, I think it makes sense, to start off, to support the same
building block operations that are used in the current file-based
code.  That may mean having an API that can't express tricks that e.g.
an SQL-based backend would be able to optimize (removing some items
from a reflog without copying the rest, filtering based on conditions
that can be expressed in SQL such as date, etc) but I think it's fine
as a starting point.  Later we can add new operations, change existing
ones, and so on, based on experience with real backends.

The write operations for file-based reflog handling are simple:

	- create a new reflog with a single reflog entry

	- add an entry to an existing reflog

	- (optional) copy a reflog wholesale --- this can be
	  implemented in terms of "add an entry", but copying in
	  blocks (or making a reflink, on filesystems that support
	  that) can make this faster

	- remove a reflog

The reflog bookkeeping involved in renaming a ref can be implemented
as copy + delete.

I also have some thoughts about how those operations can be
implemented without such a performance hit (reading the whole reflog
into memory as part of the transaction seems problematic to me), but
that should probably wait for a separate message (and I've talked
about it a bit in person).

[...]
> 4. Configure a reference to be reflogged.
> 5. Configure a reference to not be reflogged anymore and delete any
>    existing reflog.
>
> Why do we need 4 and 5 here? Wouldn't all refs be reflog by default and
> why do I want to exclude some?

See --create-reflog in git-branch(1) and core.logallrefupdates in
git-config(1).

Reflogs are disabled by default in bare repositories, which makes it
easier for unnecessary objects on a server to be more promptly removed
by gcs after a non-fast-forward push.  I prefer to turn on reflogs
when setting up a git server for my personal use.  It might be worth
flipping that default (as an orthogonal change).

> 6. Selectively expire old reflog entries, e.g., based on their age.
>
> This is the maintenance operation, which you were talking about.
> In my vision, this also should go into one transaction. So you have the
> business logic figuring out all the changes ("drop reflog entry a b and d")
> and within one transaction we can perform all of the changes.

Makes sense.

Thanks,
Jonathan