git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Michael Haggerty <mhagger@alum.mit.edu>
To: David Turner <dturner@twopensource.com>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH v2 38/43] refs: make some files backend functions public
Date: Thu, 08 Oct 2015 00:47:19 +0200	[thread overview]
Message-ID: <5615A0F7.9090401@alum.mit.edu> (raw)
In-Reply-To: <1444251311.8836.22.camel@twopensource.com>

On 10/07/2015 10:55 PM, David Turner wrote:
> On Wed, 2015-10-07 at 18:00 +0200, Michael Haggerty wrote:
>>
>> That's a really good point.
>>
>> I hate to break it to you, but the handling of symrefs in Git is already
>> a mess. HEAD is the only symref that I would really trust to work
>> correctly all the time. So I think that changes needn't be judged on
>> whether they handle symrefs perfectly. They should just not break them
>> in any dramatic new ways.
>>
>> So, you pointed out the problem that HEAD (a per-worktree reference) can
>> be a symref that points at a shared reference. In fact, I think when
>> HEAD is symbolic it is only allowed to point at a branch under
>> refs/heads, so this particular problem is pretty well-constrained.
>>
>> Are there other cases of cross-backend writes? I suppose there could be
>> a symref elsewhere among the per-worktree references that points at a
>> shared reference. But I can't think of any cases where this is done by
>> standard Git. Not that it is forbidden; I just don't think it is done by
>> any of the standard tools.
> 
> Another case would be an update-ref command that updates both
> refs/bisect/something and refs/heads/something.  
> 
> I don't think git ever does this by default, but anyone can issue a
> weird update-ref command if they feel like it.

Oh I was mostly worried about symbolic refs reaching across the divide.
If a transaction includes *non-symbolic* refs from both sides I think
all you have to do is sort them into two piles and do one transaction
for each pile. You would probably have to sacrifice atomicity across the
dividing line, but it's a bit unfair to expect atomic updates that span
two possibly completely different backends.

OK, you don't know for 100% sure that a reference is a symref before you
have locked it. But we've agreed that cross-repo symref support doesn't
have to be perfect (except for HEAD).

>> Or there could be a symref among the shared references that points at a
>> per-worktree reference. But AFAIK the only other symrefs that are in
>> common use are the refs/remotes/*/HEAD symrefs, and they always point at
>> references within the same (shared) namespace.
>>
>> If everything that I've said is correct, then my opinion is that it
>> would be perfectly adequate if your code would handle the specific case
>> of HEAD (by hook or by crook), and if there are any other cross-backend
>> symrefs, just die with a message stating that such usage is unsupported.
>> Junio, do you think that would be acceptable?
> 
> Hm.  I don't think it's significantly  easier to handle just HEAD than
> it would be to handle all cases.  But I'll see what happens as I write
> the code.

I think the main simplification is having license not to worry about
shared symrefs that could theoretically point at per-worktree
references. Though I guess that's nonsensical anyway, so maybe it was
already obvious that you don't have to handle it.

>>> The simplest solution would be for the lmdb code to simply acquire
>>> locks, and write to lock files, and then commit those lock files just
>>> before the db transaction commits. Then the lmdb code would handle all
>>> of the orchestration without the files backend having to be rewritten to
>>> handle this case.
>>
>> Wouldn't that essentially be re-implementing the files backend? I must
>> be missing something.
> 
> There would be some amount of reimplementation, yes.  But if we assume
> that the number of per-worktree refs is relatively small, we could make
> some simplification.  But actually, see below.
> 
>>> [...]
>>
>> BTW I just realized that if one backend should delegate to another, then
>> the primary backend should be the per-worktree backend and it should
>> delegate to the common backend. I think I described things the other way
>> around in my earlier message. This makes more sense because it is
>> acceptable for per-worktree references to refer to common references but
>> not vice versa.
> 
> I think I might have a good way to deal with this:
> 
> If we're going to switch the lmdb transaction code over to accumulate
> updates and then do them as one batch, then probably all other
> backends will work the same way.  So maybe there is no need for all of
> these backend functions:
> 
> 	ref_transaction_begin_fn *transaction_begin;
> 	ref_transaction_update_fn *transaction_update;
> 	ref_transaction_create_fn *transaction_create;
> 	ref_transaction_delete_fn *transaction_delete;
> 	ref_transaction_verify_fn *transaction_verify;
> 
> Instead, the generic refs code will accumulate updates in a struct
> ref_update.  Instead of a lock, the ref_update struct will have a void
> pointer that backends can use for per-update data (such as the lock).
> The generic code can also handle rejecting duplicate ref updates.
> 
> The per-backend transaction_commit method will just take a struct
> ref_transaction (that is, what the current patchset calls a
> files_ref_transaction) -- basically, a list of ref_updates -- and
> attempt to apply it.
> 
> While we're doing this, the generic ref code can detect an update to
> HEAD, and replace it with an update to whatever HEAD points to (if HEAD
> is a symref).  Then it can call files_log_ref_write to write to HEAD's
> reflog, if the main transaction commits successfully.  If HEAD is not a
> symref, the generic code can just move the HEAD update over to the files
> backend.
> 
> Does this make sense?

That makes a lot of sense. I like it.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu

  reply	other threads:[~2015-10-07 22:48 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-28 22:01 [PATCH v2 00/43] lmdb ref backend David Turner
2015-09-28 22:01 ` [PATCH v2 01/43] refs.c: create a public version of verify_refname_available David Turner
2015-10-03  5:02   ` Torsten Bögershausen
2015-10-03 16:50     ` David Turner
2015-10-03 21:07       ` Torsten Bögershausen
2015-10-04  6:07       ` Torsten Bögershausen
2015-10-05  4:29   ` Michael Haggerty
2015-10-05 20:23     ` David Turner
2015-09-28 22:01 ` [PATCH v2 02/43] refs: make repack_without_refs and is_branch public David Turner
2015-10-05  4:34   ` Michael Haggerty
2015-10-05 20:26     ` David Turner
2015-09-28 22:01 ` [PATCH v2 03/43] refs-be-files.c: rename refs to refs-be-files David Turner
2015-09-28 22:01 ` [PATCH v2 04/43] refs.c: add a new refs.c file to hold all common refs code David Turner
2015-09-28 22:01 ` [PATCH v2 05/43] refs.c: move update_ref to refs.c David Turner
2015-09-28 22:01 ` [PATCH v2 06/43] refs.c: move delete_ref and delete_refs to the common code David Turner
2015-09-28 22:01 ` [PATCH v2 07/43] refs.c: move read_ref_at to the common refs file David Turner
2015-09-28 22:01 ` [PATCH v2 08/43] refs.c: move the hidden refs functions to the common code David Turner
2015-09-28 22:01 ` [PATCH v2 09/43] refs.c: move dwim and friend functions to the common refs code David Turner
2015-09-28 22:01 ` [PATCH v2 10/43] refs.c: move warn_if_dangling_symref* to the common code David Turner
2015-09-28 22:01 ` [PATCH v2 11/43] refs.c: move read_ref, read_ref_full and ref_exists " David Turner
2015-09-28 22:01 ` [PATCH v2 12/43] refs.c: move resolve_refdup to common David Turner
2015-09-28 22:01 ` [PATCH v2 13/43] refs.c: move check_refname_format to the common code David Turner
2015-09-28 22:01 ` [PATCH v2 14/43] refs.c: move is_branch " David Turner
2015-09-28 22:01 ` [PATCH v2 15/43] refs.c: move prettify_refname " David Turner
2015-09-28 22:01 ` [PATCH v2 16/43] refs.c: move ref iterators " David Turner
2015-09-28 22:01 ` [PATCH v2 17/43] refs.c: move head_ref_namespaced " David Turner
2015-09-28 22:01 ` [PATCH v2 18/43] refs-be-files.c: add a backend method structure with transaction functions David Turner
2015-10-05  8:03   ` Michael Haggerty
2015-10-05 17:25     ` Junio C Hamano
2015-10-06  0:20       ` David Turner
2015-09-28 22:01 ` [PATCH v2 19/43] refs-be-files.c: add methods for misc ref operations David Turner
2015-09-28 22:01 ` [PATCH v2 20/43] refs-be-files.c: add methods for the ref iterators David Turner
2015-09-28 22:01 ` [PATCH v2 21/43] refs-be-files.c: add method for for_each_reftype_ David Turner
2015-09-28 22:01 ` [PATCH v2 22/43] refs-be-files.c: add do_for_each_per_worktree_ref David Turner
2015-10-05  8:19   ` Michael Haggerty
2015-10-05 20:14     ` David Turner
2015-09-28 22:01 ` [PATCH v2 23/43] refs.c: move refname_is_safe to the common code David Turner
2015-09-28 22:01 ` [PATCH v2 24/43] refs.h: document make refname_is_safe and add it to header David Turner
2015-09-28 22:02 ` [PATCH v2 25/43] refs.c: move copy_msg to the common code David Turner
2015-09-28 22:02 ` [PATCH v2 26/43] refs.c: move peel_object " David Turner
2015-09-28 22:02 ` [PATCH v2 27/43] refs.c: move should_autocreate_reflog to " David Turner
2015-10-02 20:57   ` Junio C Hamano
2015-09-28 22:02 ` [PATCH v2 28/43] refs.c: add ref backend init function David Turner
2015-10-05  8:37   ` Michael Haggerty
2015-10-05 20:37     ` David Turner
2015-09-28 22:02 ` [PATCH v2 29/43] refs.c: add methods for reflog David Turner
2015-09-28 22:02 ` [PATCH v2 30/43] refs-be-files.c: add method to expire reflogs David Turner
2015-10-05  8:41   ` Michael Haggerty
2015-09-28 22:02 ` [PATCH v2 31/43] refs.c: add method for initial ref transaction commit David Turner
2015-09-28 22:02 ` [PATCH v2 32/43] initdb: move safe_create_dir into common code David Turner
2015-09-28 22:02 ` [PATCH v2 33/43] refs.c: add method for initializing refs db David Turner
2015-09-28 22:02 ` [PATCH v2 34/43] refs.c: make struct ref_transaction generic David Turner
2015-10-06 17:43   ` Michael Blume
2015-10-06 17:53     ` David Turner
2015-09-28 22:02 ` [PATCH v2 35/43] refs-be-files.c: add method to rename refs David Turner
2015-09-28 22:02 ` [PATCH v2 36/43] run-command: track total number of commands run David Turner
2015-09-28 22:02 ` [PATCH v2 37/43] refs: move some defines from refs-be-files.c to refs.h David Turner
2015-10-05  8:57   ` Michael Haggerty
2015-09-28 22:02 ` [PATCH v2 38/43] refs: make some files backend functions public David Turner
2015-10-05  9:03   ` Michael Haggerty
2015-10-06  1:24     ` David Turner
2015-10-07  1:25     ` David Turner
2015-10-07 16:00       ` Michael Haggerty
2015-10-07 17:20         ` Junio C Hamano
2015-10-07 20:55         ` David Turner
2015-10-07 22:47           ` Michael Haggerty [this message]
2015-09-28 22:02 ` [PATCH v2 39/43] refs: break out a ref conflict check David Turner
2015-10-05  9:06   ` Michael Haggerty
2015-10-06  0:28     ` David Turner
2015-09-28 22:02 ` [PATCH v2 40/43] refs: allow ref backend to be set for clone David Turner
2015-10-05  9:32   ` Michael Haggerty
2015-10-06  1:29     ` David Turner
2015-10-06  1:58       ` Jeff King
2015-10-06 18:09         ` David Turner
2015-10-12  9:00           ` Carlos Martín Nieto
2015-10-05 11:55   ` Michael Haggerty
2015-10-06  1:16     ` David Turner
2015-09-28 22:02 ` [PATCH v2 41/43] refs: add register_refs_backend David Turner
2015-09-28 22:02 ` [PATCH v2 42/43] refs: add LMDB refs backend David Turner
2015-10-02 21:35   ` Junio C Hamano
2015-10-05 15:47   ` Michael Haggerty
2015-10-07  1:51     ` David Turner
2015-10-07 18:31       ` Michael Haggerty
2015-10-07 19:08         ` Junio C Hamano
2015-10-07 19:20         ` David Turner
2015-10-07 22:13           ` Michael Haggerty
2015-09-28 22:02 ` [PATCH v2 43/43] refs: tests for db backend David Turner
2015-10-03 17:39   ` Dennis Kaarsemaker
2015-10-05 16:56     ` Junio C Hamano
2015-10-06  0:20       ` David Turner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5615A0F7.9090401@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=dturner@twopensource.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).