Skip to content

Support reftable ref backend for Git#1054

Closed
hanwen wants to merge 25 commits intogit:masterfrom
hanwen:libreftable
Closed

Support reftable ref backend for Git#1054
hanwen wants to merge 25 commits intogit:masterfrom
hanwen:libreftable

Conversation

@hanwen
Copy link
Contributor

@hanwen hanwen commented Jul 19, 2021

This continues the work in #847, which the gitgitgadget erroneously closed.

Changes relative to last series (version 17 Aug 2021, tip: 3110d6e)

  • drop FUNCTION use
  • use REALLOC_ARRAY; remove informational errno
  • avarab's comments on tests
  • fix assert failure in worktree reflog expiry.

For the 'seen' branch, the following should be applied:

diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index d7137d1213..9323931eeb 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -108,7 +108,7 @@ static const char *bare_ref_name(const char *ref)
 static int git_reftable_read_raw_ref(struct ref_store *ref_store,
 				     const char *refname, struct object_id *oid,
 				     struct strbuf *referent,
-				     unsigned int *type);
+				     unsigned int *type, int *failure_errno);
 
 static void clear_reftable_log_record(struct reftable_log_record *log)
 {
@@ -425,13 +424,14 @@ static int fixup_symrefs(struct ref_store *ref_store,
 	for (i = 0; i < transaction->nr; i++) {
 		struct ref_update *update = transaction->updates[i];
 		struct object_id old_oid;
+		int failure_errno;
 
 		err = git_reftable_read_raw_ref(ref_store, update->refname,
 						&old_oid, &referent,
 						/* mutate input, like
 						   files-backend.c */
-						&update->type);
-		if (err < 0 && errno == ENOENT &&
+						&update->type, &failure_errno);
+		if (err < 0 && failure_errno == ENOENT &&
 		    is_null_oid(&update->old_oid)) {
 			err = 0;
 		}
@@ -1602,7 +1603,7 @@ static int reftable_error_to_errno(int err)
 static int git_reftable_read_raw_ref(struct ref_store *ref_store,
 				     const char *refname, struct object_id *oid,
 				     struct strbuf *referent,
-				     unsigned int *type)
+				     unsigned int *type, int *failure_errno)
 {
 	struct git_reftable_ref_store *refs =
 		(struct git_reftable_ref_store *)ref_store;
@@ -1626,13 +1627,11 @@ static int git_reftable_read_raw_ref(struct ref_store *ref_store,
 
 	err = reftable_stack_read_ref(stack, refname, &ref);
 	if (err > 0) {
-		errno = ENOENT;
+		*failure_errno = ENOENT;
 		err = -1;
 		goto done;
 	}
 	if (err < 0) {
-		errno = reftable_error_to_errno(err);
-		err = -1;
 		goto done;
 	}

cc: Carlo Marcelo Arenas Belón carenas@gmail.com
cc: Han-Wen Nienhuys hanwen@google.com
cc: Philip Oakley philipoakley@iee.email
cc: Ævar Arnfjörð Bjarmason avarab@gmail.com
cc: Carlo Arenas carenas@gmail.com

cc: Han-Wen Nienhuys hanwen@google.com
cc: Ævar Arnfjörð Bjarmason avarab@gmail.com

@hanwen hanwen changed the title Libreftable Support reftable ref backend for Git Jul 19, 2021
@hanwen
Copy link
Contributor Author

hanwen commented Jul 20, 2021

/submit

@gitgitgadget-git
Copy link

Submitted as pull.1054.git.git.1626800686.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git pr-git-1054/hanwen/libreftable-v1

To fetch this version to local tag pr-git-1054/hanwen/libreftable-v1:

git fetch --no-tags https://github.com/gitgitgadget/git tag pr-git-1054/hanwen/libreftable-v1

@gitgitgadget-git
Copy link

This branch is now known as hn/reftable.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via f55539d.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 57102f2.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via bd46e67.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 45f92dd.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 1871e2f.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 7cfeb34.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via d80dfcd.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via bdce115.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via dbf640e.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via e5c19a9.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 94646ba.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

Seems to break CI jobs in 'seen'.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via fad749e.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 13ec157.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 2d869d8.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

Seems to break CI jobs in 'seen'.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via c40aa07.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 3a7adf1.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

Seems to break CI jobs in 'seen'.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 22ab9da.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

Seems to break CI jobs in 'seen'.
cf. https://github.com/git/git/runs/3257622953?check_suite_focus=3Dtrue#=
step:4:1685

@gitgitgadget-git
Copy link

This patch series was integrated into seen via a15fa07.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

Seems to break CI jobs in 'seen'.
cf. https://github.com/git/git/runs/3257622953?check_suite_focus=3Dtrue#=
step:4:1685

hanwen added 4 commits August 30, 2021 16:00
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
provide a command-line utility for inspecting individual tables, and
inspecting a complete ref database

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Helped-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
This command dumps individual tables or a stack of of tables.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
The reftable backend needs to know the hash algorithm for writing the
initialization hash table.

The initial reftable contains a symref HEAD => "main" (or "master"), which is
agnostic to the size of hash value, but this is an exceptional circumstance, and
the reftable library does not cater to this exception. It insists that all
tables in the stack have a consistent format ID for the hash algorithm.

Call set_repo_hash_algo directly after calling validate_hash_algorithm() (which
reads $GIT_DEFAULT_HASH).

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
@gitgitgadget-git
Copy link

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):


On Mon, Aug 30 2021, Han-Wen Nienhuys wrote:

> On Mon, Aug 30, 2021 at 3:22 PM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>> But we will need at least the optimistic locking of code like
>> builtin/reflog.c wanting to do an expiry, and deciding whether to do
>> that expiry based on a given state of the ref/reflog. I.e. we don't
>> want:
>>
>>     1. Start reflog expiry
>>     2. Code in builtin/reflog.c looks up the OID
>>     3. Code in builtin/reflog.c decides whether expire the reflog
>>     4. Concurrent with #4, another writer updates the ref/reflog pair
>>     5. Code in builtin/reflog.c says "OK, expire it!"
>>     6. Reftable queues a delete/prune of the reflog per #5.
>>
>> This would be a sequente of updates to the ref/reflog, none of whom were
>> racy as far as the reftable semantics itself are concerneb, but where
>> we'd do the wrong thing because the writer thought we had A when we
>> really had B. So we need the equivalent of an "git update-ref" with the
>> "<oldvalue>".
>>
>> Is there a better way to do that in this case that I'm missing?
>
> I spent some more time looking at builtin/reflog.c, but I am still not
> 100% sure what the locking is used for.
>
> From a quick glance, the OID goes into tip_commit, and tip_commit goes
> into a reachable list (?). The reachable list is then for something,
> but I can't really tell what.
>
> In your example with 1.-6., it's still not clear to me what the
> undesired behavior is precisely. If the reflog is pruned in #6, is the
> worry that the update in #4 is pruned immediately after being
> effected?

Yes, I think so. But I'm not sure. I skimmed the code quickly today, and
when I wrote the referenced series didn't focus much on the nitty-gritty
of the builtin/reflog.c behavior other than assuring myself that I was
doing the exact same thing as before as far as its logic was concerned.

I.e. it always locked at a given OID. Before my in-flight "reflog
expire: don't lock reflogs using previously seen OI" it might not lock
but get this error:

    error: cannot lock ref '<refname>': ref '<refname>' is at <OID-A> but expected <OID-B>

But at least it wouldn't do anything, but the current code does require
the passed-in OID. See the code that needs "unreachable_expire_kind" and
"tip_commit".

Perhaps that whole thing can also be refactored somehow. If I change the
"commit = lookup_commit(the_repository, oid);" in
"reflog_expiry_prepare()" to just "commit = NULL" all tests pass, but
that might just be missing test coverage in the face of same race...

@gitgitgadget-git
Copy link

User Ævar Arnfjörð Bjarmason <avarab@gmail.com> has been added to the cc: list.

hanwen and others added 5 commits August 30, 2021 16:27
For background, see Documentation/technical/reftable.txt.

This introduces the file refs/reftable-backend.c containing a reftable-powered
ref storage backend.

It can be activated by setting GIT_TEST_REFTABLE in the environment. When
GIT_TEST_REFTABLE is set, the test prerequisite !REFFILES is set.

There is no option to git-init for now, as the test suite still shows failures
with GIT_TEST_REFTABLE=1.

Example use: see t/t0031-reftable.sh

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio Hamano <gitster@pobox.com>
Helped-by: Patrick Steinhardt <patrick.steinhardt@elego.de>
Co-authored-by: Jeff King <peff@peff.net>
In our git-prompt script we strive to use Bash builtins wherever
possible, because fork()-ing subshells for command substitutions and
fork()+exec()-ing Git commands are expensive on some platforms.  We
even read and parse '.git/HEAD' using Bash builtins to get the name of
the current branch [1].  However, the upcoming reftable refs backend
won't use '.git/HEAD' at all, but will write an invalid refname as
placeholder for backwards compatibility instead, which will break our
git-prompt script.

Update the git-prompt script to recognize the placeholder '.git/HEAD'
written by the reftable backend (its content is specified in the
reftable specs), and then fall back to use 'git symbolic-ref' to get
the name of the current branch.

[1] 3a43c4b (bash prompt: use bash builtins to find out current
    branch, 2011-03-31)

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
* Reftable for now lacks detailed error messages for directory/file conflicts.
  Skip message comparisons.

* Mark tests that muck with .git directly as REFFILES.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
@gitgitgadget-git
Copy link

This patch series was integrated into seen via 364cf33.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via fa30190.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via ee9e84b.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 8a94a63.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 3d89fcd.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via d1bad54.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 11bad4c.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via 4e18755.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via d009cb5.

@gitgitgadget-git
Copy link

There was a status update in the "Cooking" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via c5d5360.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via abe2dc2.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via a2ede59.

@gitgitgadget-git
Copy link

This patch series was integrated into seen via d4f001f.

@gitgitgadget-git
Copy link

There was a status update in the "Graduated to 'master'" section about the branch hn/reftable on the Git mailing list:

The "reftable" backend for the refs API, without integrating into
the refs subsystem, has been added.
source: <pull.1081.v4.git.git.1633638315.gitgitgadget@gmail.com>

@dscho dscho removed the seen label Feb 15, 2022
@hanwen
Copy link
Contributor Author

hanwen commented Oct 24, 2022

closing this; the library has been merged, support in Git itself is tracked in PR #1215

@hanwen hanwen closed this Oct 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants