From: Justin Tobler <jltobler@gmail.com>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 04/17] odb: move reparenting logic into respective subsystems
Date: Wed, 4 Mar 2026 14:39:57 -0600 [thread overview]
Message-ID: <aaiSFpWY0YQ6XQcM@denethor> (raw)
In-Reply-To: <20260223-b4-pks-odb-source-pluggable-v1-4-253bac1db598@pks.im>
On 26/02/23 05:17PM, Patrick Steinhardt wrote:
> The primary object database source may be initialized with a relative
> path. When reparenting the process to a different working directory we
I find the wording here a bit confusing. Maybe something like this would
be a bit clearer:
When the process changes its current working directory...
> thus have to update this path and have it point to the same path, but
> relative to the new working directory.
>
> This logic is handled in the object database layer. It consists of three
> steps:
>
> 1. We undo any potential temporary object directory, which are used
> for transactions. This is done so that we don't end up modifying
> the temporary object database source that got applied for the
> transaction.
>
> 2. We then iterate through the non-transactional sources and reparent
> their respective paths.
>
> 3. We reapply the temporary object directory, but update its path.
>
> All of this logic is heavily tied to how the object database source
> handles paths in the first place. It's an internal implementation
> detail, and as sources may not even use an on-disk path at all it is not
> a mechanism that applies to all potential sources.
Indeed this mechanism is directly coupled to how the "files" backend
operates.
> Refactor the code so that the logic to reparent the sources is hosted by
> the "files" source and the temporary object directory subsystems,
> respectively. This logic is easier to reason about, but it also ensures
> that this logic is handled at the correct level.
Makes sense.
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
[snip]
> diff --git a/odb/source-files.c b/odb/source-files.c
> index a43a197157..df0ea9ee62 100644
> --- a/odb/source-files.c
> +++ b/odb/source-files.c
> @@ -1,13 +1,28 @@
> #include "git-compat-util.h"
> +#include "abspath.h"
> +#include "chdir-notify.h"
> #include "object-file.h"
> #include "odb/source.h"
> #include "odb/source-files.h"
> #include "packfile.h"
>
> +static void odb_source_files_reparent(const char *name UNUSED,
> + const char *old_cwd,
> + const char *new_cwd,
> + void *cb_data)
> +{
> + struct odb_source_files *files = cb_data;
> + char *path = reparent_relative_path(old_cwd, new_cwd,
> + files->base.path);
> + free(files->base.path);
> + files->base.path = path;
I do find it a bit curious that we consider the "path" to be specific to
the "files" backend, but still track it as part of the "base" ODB
source. I suspect this will eventually change though?
> +}
> +
> void odb_source_files_free(struct odb_source_files *files)
> {
> if (!files)
> return;
> + chdir_notify_unregister(NULL, odb_source_files_reparent, files);
> odb_source_loose_free(files->loose);
> packfile_store_free(files->packed);
> odb_source_release(&files->base);
> @@ -25,5 +40,13 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
> files->loose = odb_source_loose_new(&files->base);
> files->packed = packfile_store_new(&files->base);
>
> + /*
> + * Ideally, we would only ever store absolute paths in the source. This
> + * is not (yet) possible though because we access and assume relative
> + * paths in the primary ODB source in some user-facing functionality.
> + */
Should this be a NEEDSWORK comment? Or do we expect it to remain this
way for the forseeable future?
> + if (!is_absolute_path(path))
> + chdir_notify_register(NULL, odb_source_files_reparent, files);
Ok so now a callback to reparent the path is set up for the "files"
source when it is created. If there are multiple "files" sources
created, each source will be handled separately.
> +
> return files;
> }
> diff --git a/tmp-objdir.c b/tmp-objdir.c
> index 9f5a1788cd..e436eed07e 100644
> --- a/tmp-objdir.c
> +++ b/tmp-objdir.c
> @@ -36,6 +36,21 @@ static void tmp_objdir_free(struct tmp_objdir *t)
> free(t);
> }
>
> +static void tmp_objdir_reparent(const char *name UNUSED,
> + const char *old_cwd,
> + const char *new_cwd,
> + void *cb_data)
> +{
> + struct tmp_objdir *t = cb_data;
> + char *path;
> +
> + path = reparent_relative_path(old_cwd, new_cwd,
> + t->path.buf);
> + strbuf_reset(&t->path);
> + strbuf_addstr(&t->path, path);
> + free(path);
> +}
Ok, at first I was a bit confused as to why we needed this logic for the
tmpdir as well. I thought reparenting as only applied to the primary
ODB, but it looks like the tmpdir was also reparented via
tmp_objdir_reapply_primary_odb().
> +
> int tmp_objdir_destroy(struct tmp_objdir *t)
> {
> int err;
> @@ -51,6 +66,7 @@ int tmp_objdir_destroy(struct tmp_objdir *t)
>
> err = remove_dir_recursively(&t->path, 0);
>
> + chdir_notify_unregister(NULL, tmp_objdir_reparent, t);
> tmp_objdir_free(t);
>
> return err;
> @@ -137,6 +153,9 @@ struct tmp_objdir *tmp_objdir_create(struct repository *r,
> strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX",
> repo_get_object_directory(r), prefix);
>
> + if (!is_absolute_path(t->path.buf))
> + chdir_notify_register(NULL, tmp_objdir_reparent, t);
> +
> if (!mkdtemp(t->path.buf)) {
> /* free, not destroy, as we never touched the filesystem */
> tmp_objdir_free(t);
[snip]
> diff --git a/tmp-objdir.h b/tmp-objdir.h
> index fceda14979..ccf800faa7 100644
> --- a/tmp-objdir.h
> +++ b/tmp-objdir.h
> @@ -68,19 +68,4 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *);
> */
> void tmp_objdir_replace_primary_odb(struct tmp_objdir *, int will_destroy);
>
> -/*
> - * If the primary object database was replaced by a temporary object directory,
> - * restore it to its original value while keeping the directory contents around.
> - * Returns NULL if the primary object database was not replaced.
> - */
> -struct tmp_objdir *tmp_objdir_unapply_primary_odb(void);
> -
> -/*
> - * Reapplies the former primary temporary object database, after potentially
> - * changing its relative path.
> - */
> -void tmp_objdir_reapply_primary_odb(struct tmp_objdir *, const char *old_cwd,
> - const char *new_cwd);
These functions are no longer needed because each of the sources have
their paths updated directly via separate registered callbacks. Makes
sense.
-Justin
next prev parent reply other threads:[~2026-03-04 20:40 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-23 16:17 [PATCH 00/17] odb: make object database sources pluggable Patrick Steinhardt
2026-02-23 16:17 ` [PATCH 01/17] odb: split `struct odb_source` into separate header Patrick Steinhardt
2026-03-04 15:55 ` Justin Tobler
2026-03-05 13:23 ` Patrick Steinhardt
2026-03-05 16:57 ` Justin Tobler
2026-02-23 16:17 ` [PATCH 02/17] odb: introduce "files" source Patrick Steinhardt
2026-03-04 16:57 ` Justin Tobler
2026-03-05 13:23 ` Patrick Steinhardt
2026-03-05 10:20 ` Karthik Nayak
2026-02-23 16:17 ` [PATCH 03/17] odb: embed base source in the "files" backend Patrick Steinhardt
2026-03-04 17:40 ` Justin Tobler
2026-03-05 13:23 ` Patrick Steinhardt
2026-03-05 17:06 ` Justin Tobler
2026-03-05 10:45 ` Karthik Nayak
2026-03-05 13:23 ` Patrick Steinhardt
2026-02-23 16:17 ` [PATCH 04/17] odb: move reparenting logic into respective subsystems Patrick Steinhardt
2026-03-04 20:39 ` Justin Tobler [this message]
2026-03-05 13:23 ` Patrick Steinhardt
2026-02-23 16:17 ` [PATCH 05/17] odb/source: introduce source type for robustness Patrick Steinhardt
2026-03-04 20:46 ` Justin Tobler
2026-03-05 13:07 ` Patrick Steinhardt
2026-03-05 10:50 ` Karthik Nayak
2026-02-23 16:17 ` [PATCH 06/17] odb/source: make `free()` function pluggable Patrick Steinhardt
2026-03-04 20:54 ` Justin Tobler
2026-02-23 16:17 ` [PATCH 07/17] odb/source: make `reprepare()` " Patrick Steinhardt
2026-03-04 21:08 ` Justin Tobler
2026-03-05 13:23 ` Patrick Steinhardt
2026-02-23 16:17 ` [PATCH 08/17] odb/source: make `close()` " Patrick Steinhardt
2026-03-04 21:03 ` Justin Tobler
2026-03-05 13:23 ` Patrick Steinhardt
2026-03-05 17:11 ` Justin Tobler
2026-03-05 10:58 ` Karthik Nayak
2026-03-05 13:23 ` Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 09/17] odb/source: make `read_object_info()` " Patrick Steinhardt
2026-03-04 21:33 ` Justin Tobler
2026-02-23 16:18 ` [PATCH 10/17] odb/source: make `read_object_stream()` " Patrick Steinhardt
2026-03-05 11:13 ` Karthik Nayak
2026-03-05 13:23 ` Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 11/17] odb/source: make `for_each_object()` " Patrick Steinhardt
2026-03-05 12:40 ` Karthik Nayak
2026-03-05 13:07 ` Karthik Nayak
2026-03-05 13:30 ` Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 12/17] odb/source: make `freshen_object()` " Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 13/17] odb/source: make `write_object()` " Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 14/17] odb/source: make `write_object_stream()` " Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 15/17] odb/source: make `read_alternates()` " Patrick Steinhardt
2026-03-04 21:49 ` Justin Tobler
2026-03-05 13:23 ` Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 16/17] odb/source: make `write_alternate()` " Patrick Steinhardt
2026-02-23 16:18 ` [PATCH 17/17] odb/source: make `begin_transaction()` " Patrick Steinhardt
2026-03-04 22:01 ` Justin Tobler
2026-03-05 13:24 ` Patrick Steinhardt
2026-02-23 16:21 ` [PATCH 00/17] odb: make object database sources pluggable Patrick Steinhardt
2026-02-23 21:59 ` Junio C Hamano
2026-02-24 8:41 ` Patrick Steinhardt
2026-03-05 13:11 ` Karthik Nayak
2026-03-05 14:19 ` [PATCH v2 " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 01/17] odb: split `struct odb_source` into separate header Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 02/17] odb: introduce "files" source Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 03/17] odb: embed base source in the "files" backend Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 04/17] odb: move reparenting logic into respective subsystems Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 05/17] odb/source: introduce source type for robustness Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 06/17] odb/source: make `free()` function pluggable Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 07/17] odb/source: make `reprepare()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 08/17] odb/source: make `close()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 09/17] odb/source: make `read_object_info()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 10/17] odb/source: make `read_object_stream()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 11/17] odb/source: make `for_each_object()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 12/17] odb/source: make `freshen_object()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 13/17] odb/source: make `write_object()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 14/17] odb/source: make `write_object_stream()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 15/17] odb/source: make `read_alternates()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 16/17] odb/source: make `write_alternate()` " Patrick Steinhardt
2026-03-05 14:19 ` [PATCH v2 17/17] odb/source: make `begin_transaction()` " Patrick Steinhardt
2026-03-05 17:42 ` [PATCH v2 00/17] odb: make object database sources pluggable Justin Tobler
2026-03-05 20:42 ` Junio C Hamano
2026-03-10 12:19 ` Patrick Steinhardt
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=aaiSFpWY0YQ6XQcM@denethor \
--to=jltobler@gmail.com \
--cc=git@vger.kernel.org \
--cc=ps@pks.im \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox