Re: [PATCH v3 1/6] odb: introduce interface to generate packfiles

Junio C Hamano <[email protected]>
Newsgroups org.kernel.vger.git
Message-ID <[email protected]>
Patrick Steinhardt <[email protected]> writes:

> Packfiles have two primary use cases:
>
>   - They are used to store objects at rest in a Git repository.
>
>   - They are used on the transport layer to transfer objects between two
>     repositories.
>
> The first class is closely tied to a given object database backend, and
> as such this use is highly specific to how such a backend decides to
> store its data. This shows in git-pack-objects(1), which is used by
> git-repack(1) et al to optimize the object database, which supports lots
> of options that are closely coupled with how data is stored.
>
> But the second class is quite a lot more generic: we don't care about
> specifics of how the object database stores its objects, but to generate
> the packfiles we only care about the object graph itself. Still, this
> use case is also coupled with git-pack-objects(1).
>
> Unfortunately, because git-pack-objects(1) covers both classes, the
> result is that it is very hard to port the whole command to properly
> support pluggable object databases. There are simply way too many
> options that an alternative implementation will have a very hard time to
> support in the first place.
>
> And despite being hard to implement, it's also quite unnecessary to
> implement those backend-specific options. Optimizing the object database
> has already been made pluggable, and an alternative implementation is
> unlikely to care about cruft packs, unpacked objects, keep packs and the
> like. But we still need to make at least _parts_ of the packfile
> generation pluggable so that backends can generate packfiles for the
> transport layer itself.
>
> Introduce a new interface that lets backends generate a new packfile and
> implement that interface for the "files" backend. The options supported
> by the callback are exactly the set of options that are required for the
> transport layer, but nothing more.
>
> This means that git-pack-objects(1) itself cannot be ported over to this
> new interface, but as explained above that's a hard feat to pull off due
> to the backend-specific features. Ideally though, we should expose the
> ability to generate arbitrary packfiles using this interface. The intent
> of this is to eventually introduce a git-objects(1) subcommand (similar
> to git-refs(1)) that exposes generic interfaces for accessing everything
> related to the object database. In that case, we are able to expose only
> those options that are generic.
>
> Subsequent commits will convert git-upload-pack(1), git-send-pack(1) and
> git-bundle(1) to use this interface.
>
> Signed-off-by: Patrick Steinhardt <[email protected]>
> ---
>  odb.c              |  21 ++++++++
>  odb.h              | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  odb/source-files.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  odb/source.h       |  33 ++++++++++++
>  4 files changed, 355 insertions(+)
>
> diff --git a/odb.c b/odb.c
> index caf1d0f542..cd9d5b48bc 100644
> --- a/odb.c
> +++ b/odb.c
> @@ -1046,6 +1046,27 @@ bool odb_optimize_required(struct object_database *odb,
>  	return odb_source_optimize_required(odb->sources, opts);
>  }
>  
> +void odb_generate_pack_options_release(struct odb_generate_pack_options *opts)
> +{
> +	oid_array_clear(&opts->wants);
> +	oid_array_clear(&opts->haves);
> +	oid_array_clear(&opts->shallows);
> +}
> +
> +int odb_generate_pack(struct object_database *odb,
> +		      struct odb_pack_generator **out,
> +		      const struct odb_generate_pack_options *opts)
> +{
> +	if (!odb->sources->generate_pack)
> +		return error(_("primary object source does not support generating packfiles"));
> +	return odb_source_generate_pack(odb->sources, out, opts);
> +}

Perhaps a stupid question but the opts->pack_fd is documented:

> +struct odb_generate_pack_options {
> ...
> +	/*
> +	 * File descriptor that the generated pack shall be written to. If set
> +	 * to `-1`, a pipe will be created and exposed via the pack generator's
> +	 * `out` field. If set to `0`, the pack will be written to the standard
> +	 * output stream. Otherwise, the provided descriptor will be written to
> +	 * and is consumed by the generator.
> +	 */
> +	int pack_fd;
> +

Here I assume that "and is consumed by" refers to "generator writes
into it and then closes it when it is done"?

odb_source_generate_pack() delegate to source->generate_pack(),
which I presume goes to odb_source_files_generate_pack(), which in
turn assigns opts->pack_fd to cp->out and calls start_command(cp) to
run pack-objects.  The file descriptor is closed when the process
finishes.

What happens if the odb->sources[0] does not support .generate_pack?
Should opts->pack_fd be "consumed" here to avoid leaking it, or we
do not have to worry about it because the caller will soon exit
itself?
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.