summaryrefslogtreecommitdiff
path: root/builtin/cat-file.c
AgeCommit message (Collapse)AuthorFilesLines
2026-08-23Merge branch 'ps/cat-file-remote-object-info-type'Junio C Hamano1-53/+20
The 'remote-object-info' command for 'git cat-file --batch-command' has been extended to support the '%(objecttype)' placeholder. * ps/cat-file-remote-object-info-type: cat-file: unify default format serve: advertise type capability fetch-object-info: parse type from server response protocol-caps: add type support to object-info transport: drop remote object-info fields from transport struct fetch-object-info: die() on the remaining error path fetch-object-info: use dedicated struct for the results fetch-object-info: pass arguments directly instead of a struct fetch-object-info: detect malformed server responses t5701: use test_file_size() to get the size of a file
2026-08-07cat-file: unify default formatPablo Sabater1-7/+0
%(objecttype) is supported both by the client and by the server. Change the temporary default format to the unified version that the other commands use. Update documentation to remove %(objecttype) from the caveats of remote-object-info and show %(objecttype) support. Now that type is supported and the default format unified, update the tests to expect the new default format. Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07fetch-object-info: parse type from server responsePablo Sabater1-0/+7
The server can handle type requests but does not advertise the capability yet. Prepare the client to know how to parse the server response once the server advertises the type capability. Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07transport: drop remote object-info fields from transport structJeff King1-4/+2
A remote object-info request needs three things: the transport for contacting the remote, the list of oids to request, and a place to store the output. Rather than take these as function parameters, we take only the transport object, and expect the caller to have placed the other two into special fields in the transport struct. But this doesn't make much sense. The set of oids and results are really only valid for one request. There is no reason the transport would need to hang on to them outside of the single function call. Even though we save a few lines passing the parameters around through the various vtable functions, the result is harder to understand (for example, who is responsible for cleaning up results, and when should it happen?). It also opens up the possibility of a subtle bug. A caller is likely to point those fields to stack variables which could go out of scope, and the transport struct would be left holding invalid pointers. This is mostly harmless now, as we disconnect the transport immediately after the sole caller of transport_fetch_object_info(). But conceptually we could keep the transport open and make multiple fetch calls (and reuse the same connection to the helper, to a remote HTTP server, and so on). So let's pull these out of the struct and pass them as function parameters. It's a little more verbose, but I think more clearly illustrates the intent. I've also tweaked a few function signatures to mark the input oid array as const, since it is purely an input to the function. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07fetch-object-info: use dedicated struct for the resultsPablo Sabater1-45/+14
fetch_object_info() collects information about N objects, but it stores the results in an array of object_info. That struct holds the extended parameters of read_object_info() (The optional outputs the caller wants filled). Its pointers tell that function where to write the answers for a single object. object_info is not meant to be the final storage, and since fetch_object_info() does not call read_object_info(), there is no reason to use it. Using it means allocating one scalar per object per attribute just to have those pointers somewhere to point at. Add struct fetch_object_info_results. The caller sets the wants_* flags to say what it is interested in, and fetch_object_info() allocates one array per attribute. A set wants_* flag means "asked for", while a non-NULL array means "available". The caller releases the arrays with free_fetch_object_info_results(). The object_info_options string list is no longer needed. Filtering against the server's advertisement now sets local ask_* flags, and send_object_info_request() turns those into the v2 protocol option strings. remote_atom_map[] existed only to map those strings back into atom names, so drop it and build remote_allowed_atoms from the result arrays. Currently for wants_* and ask_* there is only the 'size' variant but a subsequent commit will add '*_type'. free_object_info_contents() loses its only caller and is dropped. Dropping the allow-list check makes the final else reachable from the wire, so die() instead of BUG(): an unknown attribute is the server's error, not ours. Helped-by: Jeff King <peff@peff.net> Helped-by: Junio C Hamano <gitster@pobox.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07Merge branch 'jk/cat-file-batch-wo-type-fix'Junio C Hamano1-0/+3
'git cat-file --batch-command' that asked for 'contents' without 'type' segfaults, which has been corrected. * jk/cat-file-batch-wo-type-fix: cat-file: handle content request for --batch-command without type
2026-07-30Merge branch 'ps/cat-file-remote-object-info'Junio C Hamano1-14/+210
The 'remote-object-info' command has been added to 'git cat-file --batch-command', allowing clients to request object metadata (currently size) from a remote server via protocol v2 without downloading the entire object. Format placeholders are dynamically filtered on the client based on server-advertised capabilities, returning empty strings for inapplicable or unsupported fields. * ps/cat-file-remote-object-info: cat-file: make remote-object-info allow-list adapt to the server cat-file: add remote-object-info to batch-command transport: add client support for object-info serve: advertise object-info feature protocol-caps: check object existence regardless of the attributes requested fetch-pack: move fetch initialization connect: make write_fetch_command_and_capabilities() more generic fetch-pack: move write_fetch_command_and_capabilities() to connect.c fetch-pack: use unsigned int for hash_algo variable fetch-pack: drop the static advertise_sid variable t1006: extract helper functions into new 'lib-cat-file.sh' cat-file: declare loop counter inside for() transport-helper: fix memory leak of helper on disconnect
2026-07-28cat-file: handle content request for --batch-command without typeJeff King1-0/+3
The batch mode of cat-file needs to know the object's type in order to print the contents (because it decides whether to stream or not based on object type). The default batch output contains %(objecttype), so we get the type info automatically. But when it doesn't, we have to ask for it explicitly. In the --batch code path, we check while setting up the object_info struct whether we will print the contents, and if so set "typep" to get the value. This comes from 6554dfa97a (cat-file: handle --batch format with missing type/size, 2013-12-12). But later we added a --batch-command mode, which does not do the same trick. The decision about whether to retrieve the contents is made per-command (a "contents" vs "info" command), so we can't decide when building the object_info originally. As a result, asking for: echo "contents HEAD" | git cat-file --batch-command="%(objectname)" will fail the assertion in print_object_or_die() that the type was actually filled in. We can fix it by tweaking the object_info on the fly as we receive each command. But we should be careful to restore it afterwards; otherwise a sequence of commands like: contents $one info $two info $three will pay the type-lookup price for $two and $three when it does not need to. This wouldn't be incorrect, but just slightly inefficient (and hence there are no tests for that part, because the externally-visible behavior is the same). Reported-by: Alan Stokes <alan@source.dev> Helped-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-25Merge branch 'ps/cat-file-remote-object-info' into ↵Junio C Hamano1-14/+210
ps/cat-file-remote-object-info-type * ps/cat-file-remote-object-info: cat-file: make remote-object-info allow-list adapt to the server cat-file: add remote-object-info to batch-command transport: add client support for object-info serve: advertise object-info feature protocol-caps: check object existence regardless of the attributes requested fetch-pack: move fetch initialization connect: make write_fetch_command_and_capabilities() more generic fetch-pack: move write_fetch_command_and_capabilities() to connect.c fetch-pack: use unsigned int for hash_algo variable fetch-pack: drop the static advertise_sid variable t1006: extract helper functions into new 'lib-cat-file.sh' cat-file: declare loop counter inside for() transport-helper: fix memory leak of helper on disconnect
2026-07-24cat-file: make remote-object-info allow-list adapt to the serverPablo Sabater1-33/+63
The static allow-list in expand_atom() is hardcoded to allow only "objectname" and "objectsize" for remote queries. This works because, up to this point, servers will either support object-info with name and size or they do not support them at all. As object-info gains new capabilities, we cannot expect different servers with different Git versions to have the same object-info capabilities. Therefore, the client needs to adapt its allow-list to what the server advertises. The client now: 1. Requests the protocol option that the placeholder refers to (i.e. "size" for "%(objectsize)"). 2. Drops any requested option that the server does not advertise in fetch_object_info(). 3. Maps the remaining advertised options back to their placeholders and populates remote_allowed_atoms. 4. Uses remote_allowed_atoms in expand_atom(), preserving the previous behavior for supported placeholders. For example, if the client requests "%(objectsize) %(objecttype)" and the server only supports 'size', then the client only requests 'size'. The server returns the size (i.e "42") "%(objectsize)" is expanded normally while "%(objecttype)" expands to an empty string: "42 " Note that the empty string expansion is only for known but unsupported placeholders. "%(objectcolor)" which doesn't exist would die(). This honors what for-each-ref does for known but inapplicable atoms (placeholders). Move object_info_options out of get_remote_info() so the caller which has data can select what options will be requested instead of requesting always size. Move batch_object_write() out so output is always produced. If there are no supported attributes, the output is a blank line. Include "type" in the object_info_options even though the client does not yet know how to parse the server's "type" capability. As a result, "type" is always filtered out, allowing the tests to verify that known but unsupported placeholders expand to an empty string. Since the filter removes options by swapping with the last element, the list is no longer kept sorted. Drop the pre-sort in fetch_object_info_via_pack() and use the unsorted string_list lookup for the response header. This has no effect in performance as the list can only be two entries long ('size' and 'type'). Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-24cat-file: add remote-object-info to batch-commandEric Ju1-5/+176
Since the info command in cat-file --batch-command prints object info for a given object, it is natural to add another command in cat-file --batch-command to print object info for a given object from a remote. Add remote-object-info command to cat-file --batch-command. While info takes object ids one at a time, this creates overhead when making requests to a server. So remote-object-info instead can take multiple object ids at once. The cat-file --batch-command command is generally implemented in the following manner: - Receive and parse input from user - Call respective function attached to command - Get object info, print object info In --buffer mode, this changes to: - Receive and parse input from user - Store respective function attached to command in a queue - After flush, loop through commands in queue - Call respective function attached to command - Get object info, print object info Notice how the getting and printing of object info is accomplished one at a time. As described above, this creates a problem for making requests to a server. Therefore, remote-object-info is implemented in the following manner: - Receive and parse input from user If command is remote-object-info: - Get object info from remote - Loop through and print each object info Else: - Call respective function attached to command - Parse input, get object info, print object info And finally for --buffer mode remote-object-info: - Receive and parse input from user - Store respective function attached to command in a queue - After flush, loop through commands in queue: If command is remote-object-info: - Get object info from remote - Loop through and print each object info Else: - Call respective function attached to command - Get object info, print object info To summarize, remote-object-info gets object info from the remote and then loops through the object info passed in, printing the info. In order for remote-object-info to avoid remote communication overhead in the non-buffer mode, the objects are passed in as such: remote-object-info <remote> <oid> <oid> ... <oid> rather than remote-object-info <remote> <oid> remote-object-info <remote> <oid> ... remote-object-info <remote> <oid> Placeholders in the format are validated against an allow-list of the atoms the remote path supports: "objectname" and "objectsize". Unsupported atoms expand to an empty string, honoring how for-each-ref handles known but inapplicable atoms. Without this, atoms like %(objecttype) would mark data->info.typep and because the server only sends size, type_name() would later crash. As extra safety, even outside of the remote path, initialize expand_data's type to OBJ_BAD and handle type_name() returning NULL. Helped-by: Jonathan Tan <jonathantanmy@google.com> Helped-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Eric Ju <eric.peijian@gmail.com> [pablo: added the atom allow-list validation] Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-24cat-file: declare loop counter inside for()Eric Ju1-9/+4
Declare loop counters in the for statement when they are only used within the loop body, limiting their scope and improving readability. While updating the loop counters, use size_t instead of int for counters that iterate over object counts. Update the 'nr' parameter of dispatch_calls() to size_t as all callers already pass a value of that type. Helped-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Eric Ju <eric.peijian@gmail.com> Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-15Merge branch 'ps/odb-drop-whence'Junio C Hamano1-4/+8
The 'whence' field in 'struct object_info' has been removed. The backend-specific object information retrieval has been refactored into an opt-in 'struct object_info_source' structure. * ps/odb-drop-whence: odb: document object info fields odb: drop `whence` field from object info treewide: convert users of `whence` to the new source field odb: add `source` field to struct object_info_source odb: make backend-specific fields optional packfile: thread odb_source_packed through packed_object_info()
2026-07-15builtin/cat-file: filter objects via object databasePatrick Steinhardt1-69/+7
When batching all objects, git-cat-file(1) reaches into the internals of the object database and manually manages bitmaps to apply object filters. This creates coupling between the command and the internals of the respective backend. Refactor git-cat-file(1) to use the new object filter option when batching all objects. This significantly simplifies the logic and ensures that we don't have to reach into internals of the "files" source anymore. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-09Merge branch 'ps/odb-drop-whence' into ps/odb-for-each-object-filterJunio C Hamano1-4/+8
* ps/odb-drop-whence: odb: document object info fields odb: drop `whence` field from object info treewide: convert users of `whence` to the new source field odb: add `source` field to struct object_info_source odb: make backend-specific fields optional packfile: thread odb_source_packed through packed_object_info()
2026-07-06Merge branch 'ps/odb-source-packed'Junio C Hamano1-2/+2
The packed object source has been refactored into a proper struct odb_source. * ps/odb-source-packed: odb/source-packed: drop pointer to "files" parent source midx: refactor interfaces to work on "packed" source odb/source-packed: stub out remaining functions odb/source-packed: wire up `freshen_object()` callback odb/source-packed: wire up `find_abbrev_len()` callback odb/source-packed: wire up `count_objects()` callback odb/source-packed: wire up `for_each_object()` callback odb/source-packed: wire up `read_object_stream()` callback odb/source-packed: wire up `read_object_info()` callback packfile: use higher-level interface to implement `has_object_pack()` odb/source-packed: wire up `reprepare()` callback odb/source-packed: wire up `close()` callback odb/source-packed: start converting to a proper `struct odb_source` odb/source-packed: store pointer to "files" instead of generic source packfile: move packed source into "odb/" subsystem packfile: split out packfile list logic packfile: rename `struct packfile_store` to `odb_source_packed`
2026-07-06Merge branch 'rs/cat-file-default-format-optim'Junio C Hamano1-3/+6
The default format path of git cat-file --batch has been optimized to use strbuf_add_oid_hex() and strbuf_add_uint() instead of strbuf_addf(), yielding a noticeable speedup. * rs/cat-file-default-format-optim: cat-file: speed up default format
2026-07-02treewide: convert users of `whence` to the new source fieldPatrick Steinhardt1-1/+1
The `whence` field has become redundant now that callers can learn about the exact source an object has been looked up from via the `struct object_info_source::source` field. Adapt callers to use the new field. Note that all callsites already set up the `info.sourcep` request pointer, so the conversion is rather straight-forward. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-02odb: add `source` field to struct object_info_sourcePatrick Steinhardt1-4/+4
The previous commit introduced `struct object_info_source` as an opt-in container for backend-specific information, but for now we only moved preexisting data into this structure. Most importantly, the caller has no way yet to learn about which source an object was actually looked up from. Instead, callers have to rely on the `whence` enum to distinguish the object type, but cannot use that enum to tell the object source. Add a `struct odb_source *source` field to the structure and populate it from each backend's lookup path. The `whence` enum is still set and used by callers; it will be removed in a subsequent commit now that `sourcep->source` can identify the backend on its own. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-02odb: make backend-specific fields optionalPatrick Steinhardt1-2/+6
The `struct object_info` carries two pieces of information about how an object was looked up: - The `whence` enum identifying the backend. - The backend-tagged union `u` exposing backend-specific details (currently only the packed-source case, which records the owning pack, offset and packed object type). The union is populated unconditionally, even though most callers don't care about provenance at all. Split the backend-specific union out into a new public type, `struct object_info_source`, and make the object info structure carry it via just another opt-in request pointer. As with all the other requestable information, callers that need source info allocate a `struct object_info_source` on the stack and point `sourcep` at it; callers that don't care about it simply leave the field as a `NULL` pointer. Adapt callers accordingly. Note that the `whence` enum is strictly-speaking also backend-specific information, so it would be another good candidate to be moved into the `struct object_info_source`. For now though it is left alone, as it will be replaced by a `struct odb_source` pointer in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-02packfile: thread odb_source_packed through packed_object_info()Patrick Steinhardt1-1/+1
Add an optional `struct odb_source_packed *source` parameter to `packed_object_info()` and `packed_object_info_with_index_pos()`. This parameter is unused at this point in time, but it will be used in a follow-up commit so that we can record the source of a specific object. Note that callers in "odb/source-packed.c" pass the already-available source, but all other callers pass `NULL` instead. This is fine though, as we only care about populating this info when called via the packed store. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-24Merge branch 'ps/odb-source-packed' into ps/odb-drop-whenceJunio C Hamano1-2/+2
* ps/odb-source-packed: odb/source-packed: drop pointer to "files" parent source midx: refactor interfaces to work on "packed" source odb/source-packed: stub out remaining functions odb/source-packed: wire up `freshen_object()` callback odb/source-packed: wire up `find_abbrev_len()` callback odb/source-packed: wire up `count_objects()` callback odb/source-packed: wire up `for_each_object()` callback odb/source-packed: wire up `read_object_stream()` callback odb/source-packed: wire up `read_object_info()` callback packfile: use higher-level interface to implement `has_object_pack()` odb/source-packed: wire up `reprepare()` callback odb/source-packed: wire up `close()` callback odb/source-packed: start converting to a proper `struct odb_source` odb/source-packed: store pointer to "files" instead of generic source packfile: move packed source into "odb/" subsystem packfile: split out packfile list logic packfile: rename `struct packfile_store` to `odb_source_packed`
2026-06-21Merge branch 'js/objects-larger-than-4gb-on-windows-more'Junio C Hamano1-33/+28
* js/objects-larger-than-4gb-on-windows-more: odb: use size_t for object_info.sizep and the size APIs packfile,delta: drop the `cast_size_t_to_ulong()` wrappers pack-objects: use size_t for in-core object sizes packfile: widen unpack_entry()'s size out-parameter to size_t pack-objects(check_pack_inflate()): use size_t instead of unsigned long patch-delta: use size_t for sizes compat/msvc: use _chsize_s for ftruncate
2026-06-17odb/source-packed: wire up `for_each_object()` callbackPatrick Steinhardt1-2/+2
Move `packfile_store_for_each_object()` and its associated helpers from "packfile.c" into "odb/source-packed.c" and wire it up as the `for_each_object()` callback of the "packed" source. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-15cat-file: speed up default formatRené Scharfe1-3/+6
eb54a3391b (cat-file: skip expanding default format, 2022-03-15) added special handling for the default batch format. In the meantime it has fallen behind the code path for handling arbitrary formats. Bring it up to speed by using the new and more efficient strbuf_add_oid_hex() and strbuf_add_uint() instead of strbuf_addf(): Benchmark 1: ./git_main cat-file --batch-all-objects --batch-check='%(objectname) %(objecttype) %(objectsize)' Time (mean ± σ): 1.051 s ± 0.003 s [User: 1.027 s, System: 0.023 s] Range (min … max): 1.049 s … 1.058 s 10 runs Benchmark 2: ./git_main cat-file --batch-all-objects --batch-check='%(objectname)-%(objecttype)-%(objectsize)' Time (mean ± σ): 1.012 s ± 0.002 s [User: 0.988 s, System: 0.023 s] Range (min … max): 1.010 s … 1.018 s 10 runs Benchmark 3: ./git cat-file --batch-all-objects --batch-check='%(objectname) %(objecttype) %(objectsize)' Time (mean ± σ): 979.0 ms ± 1.1 ms [User: 954.1 ms, System: 23.2 ms] Range (min … max): 977.7 ms … 980.8 ms 10 runs Summary ./git cat-file --batch-all-objects --batch-check='%(objectname) %(objecttype) %(objectsize)' ran 1.03 ± 0.00 times faster than ./git_main cat-file --batch-all-objects --batch-check='%(objectname)-%(objecttype)-%(objectsize)' 1.07 ± 0.00 times faster than ./git_main cat-file --batch-all-objects --batch-check='%(objectname) %(objecttype) %(objectsize)' Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-15odb: use size_t for object_info.sizep and the size APIsJohannes Schindelin1-33/+28
When `js/objects-larger-than-4gb-on-windows` widened the streaming, index-pack and unpack-objects code paths, in the interest of keeping the patches somewhat reasonably-sized, it left the public ODB API still typed in `unsigned long`. In particular `struct object_info::sizep` and the four wrappers built on top of it (`odb_read_object`, `odb_read_object_peeled`, `odb_read_object_info`, `odb_pretend_object`) still return the unpacked size through `unsigned long *`, so on Windows `cat-file -s` and the `git add` / `git status` paths for a >4 GiB blob silently cap at 4 GiB. Widen the field and the four wrappers. The previous commits already widened the `unpack_entry()` cascade and pack-objects' in-core size accessors, so most of the cascade arrives here with no further work: the temporary shims in `packed_object_info_with_index_pos()` and in `unpack_entry()`'s delta-base recovery path go away, the two `SET_SIZE(entry, cast_size_t_to_ulong(canonical_size))` calls in `check_object()` and the matching one in `drop_reused_delta()` collapse to plain `SET_SIZE`, and `oe_get_size_slow()`'s tail `cast_size_t_to_ulong()` is gone too. What remains narrow are the boundaries this series does not intend to touch: the diff, blame, textconv and fast-import machinery. Even so, this patch is unfortunately quite large. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-15Merge branch 'ob/more-repo-config-values'Junio C Hamano1-3/+4
Many core configuration variables have been migrated from global variables into 'repo_config_values' to tie them to a specific repository instance, avoiding cross-repository state leakage. * ob/more-repo-config-values: environment: move "warn_on_object_refname_ambiguity" into `struct repo_config_values` environment: move "sparse_expect_files_outside_of_patterns" into `struct repo_config_values` environment: move "core_sparse_checkout_cone" into `struct repo_config_values` environment: move "precomposed_unicode" into `struct repo_config_values` environment: move "pack_compression_level" into `struct repo_config_values` environment: move `zlib_compression_level` into `struct repo_config_values` environment: move "check_stat" into `struct repo_config_values` environment: move "trust_ctime" into `struct repo_config_values`
2026-06-11Merge branch 'ps/odb-source-loose'Junio C Hamano1-2/+3
The loose object source has been refactored into a proper `struct odb_source`. * ps/odb-source-loose: odb/source-loose: drop pointer to the "files" source odb/source-loose: stub out remaining callbacks odb/source-loose: wire up `write_object_stream()` callback object-file: refactor writing objects to use loose source odb/source-loose: wire up `write_object()` callback loose: refactor object map to operate on `struct odb_source_loose` odb/source-loose: wire up `freshen_object()` callback odb/source-loose: drop `odb_source_loose_has_object()` odb/source-loose: wire up `count_objects()` callback odb/source-loose: wire up `find_abbrev_len()` callback odb/source-loose: wire up `for_each_object()` callback odb/source-loose: wire up `read_object_stream()` callback odb/source-loose: wire up `read_object_info()` callback odb/source-loose: wire up `close()` callback odb/source-loose: wire up `reprepare()` callback odb/source-loose: start converting to a proper `struct odb_source` odb/source-loose: store pointer to "files" instead of generic source odb/source-loose: move loose source into "odb/" subsystem
2026-06-09Merge branch 'rs/strbuf-add-oid-hex'Junio C Hamano1-3/+2
Formatting object name in full hexadecimal form has been optimized by using a new strbuf_add_oid_hex() helper function. * rs/strbuf-add-oid-hex: hex: add and use strbuf_add_oid_hex()
2026-06-09Merge branch 'rs/strbuf-add-uint'Junio C Hamano1-2/+2
Adding a decimal integer with strbuf_addf("%u") appears commonly; they have been optimized by using a custom formatter. * rs/strbuf-add-uint: ls-tree: use strbuf_add_uint() ls-files: use strbuf_add_uint() cat-file: use strbuf_add_uint() strbuf: add strbuf_add_uint()
2026-06-05Merge branch 'ps/odb-source-loose' into ps/odb-source-packedJunio C Hamano1-2/+3
* ps/odb-source-loose: odb/source-loose: drop pointer to the "files" source odb/source-loose: stub out remaining callbacks odb/source-loose: wire up `write_object_stream()` callback object-file: refactor writing objects to use loose source odb/source-loose: wire up `write_object()` callback loose: refactor object map to operate on `struct odb_source_loose` odb/source-loose: wire up `freshen_object()` callback odb/source-loose: drop `odb_source_loose_has_object()` odb/source-loose: wire up `count_objects()` callback odb/source-loose: wire up `find_abbrev_len()` callback odb/source-loose: wire up `for_each_object()` callback odb/source-loose: wire up `read_object_stream()` callback odb/source-loose: wire up `read_object_info()` callback odb/source-loose: wire up `close()` callback odb/source-loose: wire up `reprepare()` callback odb/source-loose: start converting to a proper `struct odb_source` odb/source-loose: store pointer to "files" instead of generic source odb/source-loose: move loose source into "odb/" subsystem
2026-06-03environment: move "warn_on_object_refname_ambiguity" into `struct ↵Olamide Caleb Bello1-3/+4
repo_config_values` The `core.warnAmbiguousRefs` configuration was previously stored in a global `int` variable, making it shared across repository instances and risking cross‑repository state leakage. Store it instead in `repo_config_values`, where eagerly‑parsed repository configuration lives. This option is parsed eagerly because ambiguity warnings influence how users interpret object references in many commands; a lazy parse could cause these warnings to behave inconsistently or to appear for the wrong repository, confusing users and hindering libification. This preserves the existing behavior while tying the value to the repository from which it was read, avoiding cross‑repository state leakage and continuing the effort to reduce reliance on global configuration state. Update all references to use `repo_config_values()`. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-01odb/source-loose: wire up `for_each_object()` callbackPatrick Steinhardt1-2/+3
Move `odb_source_loose_for_each_object()` and its associated helpers from "object-file.c" into "odb/source-loose.c" and wire it up as the `for_each_object()` callback of the loose source. Again, as in the preceding commit, we are forced to expose a couple of functions from "object-file.c" that are now used by both subsystems. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-31Merge branch 'sa/cat-file-batch-mailmap-switch'Junio C Hamano1-4/+33
"git cat-file --batch" learns an in-line command "mailmap" that lets the user toggle use of mailmap. * sa/cat-file-batch-mailmap-switch: cat-file: add mailmap subcommand to --batch-command
2026-05-14hex: add and use strbuf_add_oid_hex()René Scharfe1-3/+2
Add a function for adding the full hexadecimal hash value of an object ID to a strbuf. It's thread-safe and slightly more efficient than using strbuf_addstr() with oid_to_hex() because it doesn't have to determine the length of the string or copy it from the intermediate static buffer. Add and apply a semantic patch to use it throughout the code base. I get a tiny speedup for git log showing a single hash per commit: Benchmark 1: ./git_main log --format=%H Time (mean ± σ): 91.2 ms ± 0.7 ms [User: 51.9 ms, System: 38.6 ms] Range (min … max): 89.8 ms … 92.6 ms 31 runs Benchmark 2: ./git log --format=%H Time (mean ± σ): 90.5 ms ± 0.7 ms [User: 51.0 ms, System: 38.8 ms] Range (min … max): 89.2 ms … 92.3 ms 32 runs Summary ./git log --format=%H ran 1.01 ± 0.01 times faster than ./git_main log --format=%H Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-13cat-file: use strbuf_add_uint()René Scharfe1-2/+2
Speed up printing of objectsize atoms by using the specialized function strbuf_add_uint() instead of the general-purpose function strbuf_addf(): Benchmark 1: ./git_main cat-file --batch-all-objects --batch-check='%(objectsize)' Time (mean ± σ): 751.7 ms ± 1.5 ms [User: 733.5 ms, System: 17.1 ms] Range (min … max): 750.5 ms … 755.0 ms 10 runs Benchmark 2: ./git cat-file --batch-all-objects --batch-check='%(objectsize)' Time (mean ± σ): 720.4 ms ± 0.4 ms [User: 701.9 ms, System: 16.7 ms] Range (min … max): 719.7 ms … 721.2 ms 10 runs Summary ./git cat-file --batch-all-objects --batch-check='%(objectsize)' ran 1.04 ± 0.00 times faster than ./git_main cat-file --batch-all-objects --batch-check='%(objectsize)' Benchmark 1: ./git_main cat-file --batch-all-objects --batch-check='%(objectsize:disk)' Time (mean ± σ): 404.6 ms ± 0.9 ms [User: 397.8 ms, System: 5.7 ms] Range (min … max): 403.3 ms … 405.9 ms 10 runs Benchmark 2: ./git cat-file --batch-all-objects --batch-check='%(objectsize:disk)' Time (mean ± σ): 378.3 ms ± 0.9 ms [User: 371.2 ms, System: 5.9 ms] Range (min … max): 376.8 ms … 380.2 ms 10 runs Summary ./git cat-file --batch-all-objects --batch-check='%(objectsize:disk)' ran 1.07 ± 0.00 times faster than ./git_main cat-file --batch-all-objects --batch-check='%(objectsize:disk)' Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15cat-file: add mailmap subcommand to --batch-commandSiddharth Asthana1-4/+33
git-cat-file(1)'s --batch-command works with the --use-mailmap option, but this option needs to be set when the process is created. This means we cannot change this option mid-operation. At GitLab, Gitaly keeps interacting with a long-lived git-cat-file process and it would be useful if --batch-command supported toggling mailmap dynamically on an existing process. Add a `mailmap` subcommand to --batch-command that takes a boolean argument (usual ways you can specify a boolean value like 'yes', 'true', etc., are supported). Mailmap data is loaded lazily and kept in memory, while a helper centralizes the one-time load path used both at startup and from the batch-command handler. Extend tests to cover runtime toggling, startup option interactions (`--mailmap`/`--no-mailmap`), accepted boolean forms, and invalid values. Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-31odb: rename `odb_has_object()` flagsPatrick Steinhardt1-1/+1
Rename `odb_has_object()` flags to be properly prefixed with the function name. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-20odb: introduce `struct odb_for_each_object_options`Patrick Steinhardt1-2/+5
The `odb_for_each_object()` function only accepts a bitset of flags. In a subsequent commit we'll want to change object iteration to also support iterating over only those objects that have a specific prefix. While we could of course add the prefix to the function signature, or alternatively introduce a new function, both of these options don't really seem to be that sensible. Instead, introduce a new `struct odb_for_each_object_options` that can be passed to a new `odb_for_each_object_ext()` function. Splice through the options structure into the respective object database sources. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-12Merge branch 'ps/odb-sources'Junio C Hamano1-1/+2
The object source API is getting restructured to allow plugging new backends. * ps/odb-sources: odb/source: make `begin_transaction()` function pluggable odb/source: make `write_alternate()` function pluggable odb/source: make `read_alternates()` function pluggable odb/source: make `write_object_stream()` function pluggable odb/source: make `write_object()` function pluggable odb/source: make `freshen_object()` function pluggable odb/source: make `for_each_object()` function pluggable odb/source: make `read_object_stream()` function pluggable odb/source: make `read_object_info()` function pluggable odb/source: make `close()` function pluggable odb/source: make `reprepare()` function pluggable odb/source: make `free()` function pluggable odb/source: introduce source type for robustness odb: move reparenting logic into respective subsystems odb: embed base source in the "files" backend odb: introduce "files" source odb: split `struct odb_source` into separate header
2026-03-05odb: embed base source in the "files" backendPatrick Steinhardt1-1/+2
The "files" backend is implemented as a pointer in the `struct odb_source`. This contradicts our typical pattern for pluggable backends like we use it for example in the ref store or for object database streams, where we typically embed the generic base structure in the specialized implementation. This pattern has a couple of small benefits: - We avoid an extra allocation. - We hide implementation details in the generic structure. - We can easily downcast from a generic backend to the specialized structure and vice versa because the offsets are known at compile time. - It becomes trivial to identify locations where we depend on backend specific logic because the cast needs to be explicit. Refactor our "files" object database source to do the same and embed the `struct odb_source` in the `struct odb_source_files`. There are still a bunch of sites in our code base where we do have to access internals of the "files" backend. The intent is that those will go away over time, but this will certainly take a while. Meanwhile, provide a `odb_source_files_downcast()` function that can convert a generic source into a "files" source. As we only have a single source the downcast succeeds unconditionally for now. Eventually though the intent is to make the cast `BUG()` in case the caller requests to downcast a non-"files" backend to a "files" backend. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-05odb: introduce "files" sourcePatrick Steinhardt1-1/+1
Introduce a new "files" object database source. This source encapsulates access to both loose object files and the packfile store, similar to how the "files" backend for refs encapsulates access to loose refs and the packed-refs file. Note that for now the "files" source is still a direct member of a `struct odb_source`. This architecture will be reversed in the next commit so that the files source contains a `struct odb_source`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-04Merge branch 'bk/mailmap-wo-the-repository'Junio C Hamano1-1/+1
Wean the mailmap code off of the_repository dependency. * bk/mailmap-wo-the-repository: mailmap: drop global config variables mailmap: stop using the_repository
2026-03-02Merge branch 'ps/odb-for-each-object'Junio C Hamano1-7/+29
Revamp object enumeration API around odb. * ps/odb-for-each-object: odb: drop unused `for_each_{loose,packed}_object()` functions reachable: convert to use `odb_for_each_object()` builtin/pack-objects: use `packfile_store_for_each_object()` odb: introduce mtime fields for object info requests treewide: drop uses of `for_each_{loose,packed}_object()` treewide: enumerate promisor objects via `odb_for_each_object()` builtin/fsck: refactor to use `odb_for_each_object()` odb: introduce `odb_for_each_object()` packfile: introduce function to iterate through objects packfile: extract function to iterate through objects of a store object-file: introduce function to iterate through objects object-file: extract function to read object info from path odb: fix flags parameter to be unsigned odb: rename `FOR_EACH_OBJECT_*` flags
2026-02-23Merge branch 'ps/odb-for-each-object' into ps/odb-sourcesJunio C Hamano1-7/+29
* ps/odb-for-each-object: odb: drop unused `for_each_{loose,packed}_object()` functions reachable: convert to use `odb_for_each_object()` builtin/pack-objects: use `packfile_store_for_each_object()` odb: introduce mtime fields for object info requests treewide: drop uses of `for_each_{loose,packed}_object()` treewide: enumerate promisor objects via `odb_for_each_object()` builtin/fsck: refactor to use `odb_for_each_object()` odb: introduce `odb_for_each_object()` packfile: introduce function to iterate through objects packfile: extract function to iterate through objects of a store object-file: introduce function to iterate through objects object-file: extract function to read object info from path odb: fix flags parameter to be unsigned odb: rename `FOR_EACH_OBJECT_*` flags
2026-02-20mailmap: stop using the_repositoryBurak Kaan Karaçay1-1/+1
The 'read_mailmap' and 'read_mailmap_blob' functions rely on the global 'the_repository' variable. Update both functions to accept a 'struct repository' parameter. Update all callers to pass 'the_repository' to retain the current behavior. Signed-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-26treewide: drop uses of `for_each_{loose,packed}_object()`Patrick Steinhardt1-6/+28
We're using `for_each_loose_object()` and `for_each_packed_object()` at a couple of callsites to enumerate all loose and packed objects, respectively. These functions will be removed in a subsequent commit in favor of the newly introduced `odb_source_loose_for_each_object()` and `packfile_store_for_each_object()` replacements. Prepare for this by refactoring the sites accordingly. Note that ideally, we'd convert all callsites to use the generic `odb_for_each_object()` function already. But for some callers this is not possible (yet), and it would require some significant refactorings to make this work. Converting these site will thus be deferred to a later patch series. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-26odb: rename `FOR_EACH_OBJECT_*` flagsPatrick Steinhardt1-1/+1
Rename the `FOR_EACH_OBJECT_*` flags to have an `ODB_` prefix. This prepares us for a new upcoming `odb_for_each_object()` function and ensures that both the function and its flags have the same prefix. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-21Merge branch 'ps/read-object-info-improvements'Junio C Hamano1-2/+1
The object-info API has been cleaned up. * ps/read-object-info-improvements: packfile: drop repository parameter from `packed_object_info()` packfile: skip unpacking object header for disk size requests packfile: disentangle return value of `packed_object_info()` packfile: always populate pack-specific info when reading object info packfile: extend `is_delta` field to allow for "unknown" state packfile: always declare object info to be OI_PACKED object-file: always set OI_LOOSE when reading object info
2026-01-16Merge branch 'jk/cat-file-avoid-bitmap-when-unneeded'Junio C Hamano1-3/+5
Fix for a performance regression in "git cat-file". * jk/cat-file-avoid-bitmap-when-unneeded: cat-file: only use bitmaps when filtering