From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, me@ttaylorr.com,
Derrick Stolee <derrickstolee@github.com>,
Derrick Stolee <derrickstolee@github.com>
Subject: [PATCH] object-file: reprepare alternates when necessary
Date: Mon, 06 Mar 2023 20:59:29 +0000 [thread overview]
Message-ID: <pull.1490.git.1678136369387.gitgitgadget@gmail.com> (raw)
From: Derrick Stolee <derrickstolee@github.com>
When an object is not found in a repository's object store, we sometimes
call reprepare_packed_git() to see if the object was temporarily moved
into a new pack-file (and its old pack-file or loose object was
deleted). This process does a scan of each pack directory within each
odb, but does not reevaluate if the odb list needs updating.
Create a new reprepare_alt_odb() method that is a similar wrapper around
prepare_alt_odb(). Call it from reprepare_packed_git() under the object
read lock to avoid readers from interacting with a potentially
incomplete odb being added to the odb list.
prepare_alt_odb() already avoids adding duplicate odbs to the list
during its progress, so it is safe to call it again from
reprepare_alt_odb() without worrying about duplicate odbs.
This change is specifically for concurrent changes to the repository, so
it is difficult to create a test that guarantees this behavior is
correct. I manually verified by introducing a reprepare_packed_git() call
into get_revision() and stepped into that call in a debugger with a
parent 'git log' process. Multiple runs of reprepare_alt_odb() kept
the_repository->objects->odb as a single-item chain until I added a
.git/objects/info/alternates file in a different process. The next run
added the new odb to the chain and subsequent runs did not add to the
chain.
Signed-off-by: Derrick Stolee <derrickstolee@github.com>
---
object-file: reprepare alternates when necessary
This subtlety was notice by Michael Haggerty due to how alternates are
used server-side at $DAYJOB. Moving pack-files from a repository to the
alternate occasionally causes failures because processes that start
before the alternate exists don't know how to find that alternate at
run-time.
Thanks,
* Stolee
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1490%2Fderrickstolee%2Fstolee%2Freprepare-alternates-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1490/derrickstolee/stolee/reprepare-alternates-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1490
object-file.c | 6 ++++++
object-store.h | 1 +
packfile.c | 1 +
3 files changed, 8 insertions(+)
diff --git a/object-file.c b/object-file.c
index 939865c1ae0..22acc7fd8e9 100644
--- a/object-file.c
+++ b/object-file.c
@@ -944,6 +944,12 @@ void prepare_alt_odb(struct repository *r)
r->objects->loaded_alternates = 1;
}
+void reprepare_alt_odb(struct repository *r)
+{
+ r->objects->loaded_alternates = 0;
+ prepare_alt_odb(r);
+}
+
/* Returns 1 if we have successfully freshened the file, 0 otherwise. */
static int freshen_file(const char *fn)
{
diff --git a/object-store.h b/object-store.h
index 1a713d89d7c..750c29daa54 100644
--- a/object-store.h
+++ b/object-store.h
@@ -56,6 +56,7 @@ KHASH_INIT(odb_path_map, const char * /* key: odb_path */,
struct object_directory *, 1, fspathhash, fspatheq)
void prepare_alt_odb(struct repository *r);
+void reprepare_alt_odb(struct repository *r);
char *compute_alternate_path(const char *path, struct strbuf *err);
struct object_directory *find_odb(struct repository *r, const char *obj_dir);
typedef int alt_odb_fn(struct object_directory *, void *);
diff --git a/packfile.c b/packfile.c
index 79e21ab18e7..2b28918a05e 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1008,6 +1008,7 @@ void reprepare_packed_git(struct repository *r)
struct object_directory *odb;
obj_read_lock();
+ reprepare_alt_odb(r);
for (odb = r->objects->odb; odb; odb = odb->next)
odb_clear_loose_cache(odb);
base-commit: d15644fe0226af7ffc874572d968598564a230dd
--
gitgitgadget
next reply other threads:[~2023-03-06 20:59 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-06 20:59 Derrick Stolee via GitGitGadget [this message]
2023-03-06 22:54 ` [PATCH] object-file: reprepare alternates when necessary Junio C Hamano
2023-03-07 0:28 ` Taylor Blau
2023-03-07 14:52 ` Derrick Stolee
2023-03-07 17:16 ` Junio C Hamano
2023-03-08 15:55 ` Taylor Blau
2023-03-08 17:13 ` Derrick Stolee
2023-03-07 11:28 ` Ævar Arnfjörð Bjarmason
2023-03-07 17:29 ` Junio C Hamano
2023-03-07 18:18 ` Junio C Hamano
2023-03-08 13:29 ` Derrick Stolee
2023-03-08 18:47 ` [PATCH v2] " Derrick Stolee via GitGitGadget
2023-03-08 19:35 ` Junio C Hamano
2023-03-08 20:47 ` Taylor Blau
2023-03-09 7:24 ` Jeff King
2023-03-09 9:06 ` Eric Wong
2023-03-10 21:29 ` Jonathan Tan
2023-03-11 0:01 ` Junio C Hamano
2023-03-11 3:09 ` Jonathan Tan
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1490.git.1678136369387.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=derrickstolee@github.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=me@ttaylorr.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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.