summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2026-05-25Merge branch 'mm/diff-U-takes-no-negative-values'Junio C Hamano6-17/+40
The command line parser for "git diff" learned a few options take only non-negative integers. * mm/diff-U-takes-no-negative-values: parse-options: clarify what "negated" means for PARSE_OPT_NONEG xdiff: guard against negative context lengths diff: reject negative values for -U/--unified diff: reject negative values for --inter-hunk-context
2026-05-25Merge branch 'dk/doc-exclude-is-shared-per-repo'Junio C Hamano6-13/+13
Document the fact that .git/info/exclude is shared across worktrees linked to the same repository. * dk/doc-exclude-is-shared-per-repo: ignore: note info/exclude lives in GIT_COMMON_DIR, not GIT_DIR
2026-05-25Merge branch 'kk/paint-down-to-common-optim'Junio C Hamano4-11/+81
"git merge-base" optimization. * kk/paint-down-to-common-optim: commit-reach: early exit paint_down_to_common for single merge-base commit-reach: introduce merge_base_flags enum
2026-05-24stash: reuse cached index entries in --patch temporary indexAdam Johnson2-6/+107
`git stash -p` prepares the interactive selection by creating a temporary index at HEAD, switching `GIT_INDEX_FILE` to it, and then running the `add -p` machinery. That temporary index was created by running `git read-tree HEAD`. The resulting index had no useful cached stat data or fsmonitor-valid bits from the real index. When `run_add_p()` refreshed that temporary index before showing the first prompt, it could end up lstat(2)-ing every tracked file, even in a repository where `git diff` and `git restore -p` can use fsmonitor to avoid that work. Create the temporary index in-process instead. Use `unpack_trees()` to reset the real index contents to HEAD while writing the result to the temporary index path. For paths whose index entries already match HEAD, `oneway_merge()` reuses the existing cache entries, preserving their cached stat data and `CE_FSMONITOR_VALID` state. This makes the refresh performed by `run_add_p()` behave like the one used by `git restore -p`: unchanged paths can be skipped via fsmonitor instead of being scanned again. In a 206k file repository with `core.fsmonitor` enabled and a one-line change in one file, time to first prompt dropped from 34.774 seconds to 0.659 seconds. The new perf test file demonstrates similar improvements, with maen times for without- and with-fsmonitor cases dropping from 6.90 and 6.83 seconds to 0.55 and 0.28 seconds, respectively. Signed-off-by: Adam Johnson <me@adamj.eu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: support `combine` filterTaylor Blau3-6/+93
The `combine` filter takes the intersection of its children, that is: objects are shown only when all child filters would admit the object. The preceding patches added support for many individual filter types. Enable users to compose these filters by implementing support for the `combine` filter type. Mapping intersection onto path_walk_info works because every supported child filter is a monotonic restriction: - `blob:none`, `tree:0` unconditionally clear `info->blobs` and (for `tree:0`) `info->trees`; clearing an already-cleared flag is a no-op. - `object:type=X` is now expressed as an AND of each type flag with the filtered type, so applying multiple such filters only refines the existing set rather than overwrites it. - `blob:limit=N` has to compose too: the intersection of "size < L1" and "size < L2" is "size < min(L1, L2)". Update the `LOFC_BLOB_LIMIT` handler to take the running minimum when `info->blob_limit` is already set, so a combined filter with, e.g., both "blob:limit=10" and "blob:limit=5" produces a limit of 5 regardless of ordering. - `sparse:oid` is left unchanged. A `combine` filter that includes a `sparse:oid` is allowed at most once, since the existing handler refuses to overwrite `info->pl`. Two `sparse:oid` filters in a single `combine` would be unusual and are rejected with a warning, matching the standalone `sparse:oid` behavior. Implementation-wise, the existing `prepare_filters()` called `list_objects_filter_release()` inside each case branch. That works fine for top-level filters, but `combine` filters need to recurse over its child filters without releasing each one in turn (since the parent's release iterates the sub array). Split `prepare_filters()` into a recursive helper that performs only the mutation, plus a thin wrapper that calls the helper and then releases the top-level filter once. The `LOFC_COMBINE` case in the helper just walks `sub_nr` and recurses; child filters are released by the wrapper's single `list_objects_filter_release()` call on the parent (which itself recursively releases each sub-filter, the same way it always has). If any sub-filter is unsupported (e.g. "tree:1", "sparse:<path>", or a not-yet-supported choice), the recursion bubbles a failure up and the existing pack-objects/backfill fallback paths kick in. Add coverage in t6601: - "combine:blob:none+tree:0" collapses to "tree:0" - "combine:object:type=blob+blob:limit=3" yields only the blobs smaller than three bytes - "combine:object:type=blob+object:type=tree" intersects to empty - "combine:tree:1+blob:none" reports the "tree:1" error. Update Documentation/git-pack-objects.adoc to add combine to the list of supported --filter forms. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: support `object:type` filterTaylor Blau4-2/+103
The `object:type` filter accepts only objects of a single type; it is the second member of the object-info-only filter family that bitmap traversal already supports. Like `blob:none` and `tree:0`, it can be evaluated with nothing more than the object's type, which is exactly the granularity path-walk's existing info->{commits,trees,blobs,tags} flags already control. Map `LOFC_OBJECT_TYPE` in `prepare_filters()` by AND-ing each flag against the filtered type. A single `object:type=X` filter applied to the default info (all flags = 1) leaves `info->X = 1` and all the others 0, which is what we want. Using an AND rather than straight assignment prepares us for a subsequent change to implement combined object filters. The path-walk machinery is mostly already wired for the per-type distinction: - `walk_path()` calls `path_fn` for a batch only when the corresponding `info->X` flag is set, so unwanted types are silently not reported. - `add_tree_entries()` skips tree entries of type `OBJ_BLOB` when `info->blobs` is unset, so we don't even allocate paths for them. - The commit-walk loop short-circuits the root-tree fetch when `!info->trees && !info->blobs`, so commit-only filters don't descend into trees at all. But there are a couple of side effects of the "trees off, blobs on" case that need fixing: 1. 'setup_pending_objects()' previously skipped pending trees as soon as `info->trees` was zero. For 'object:type=blob' the call site needs those pending trees: a lightweight tag pointing to a tree, or an annotated tag whose peeled target is a tree, can both reach blobs that are otherwise unreachable from any commit's root tree. Loosen the gate to "if (!info->trees && !info->blobs) continue" and similarly retrieve the root_tree_list whenever either trees or blobs are wanted. 2. The revision machinery's `handle_commit()` drops pending trees when `revs->tree_objects` is zero (see the 'OBJ_TREE' handler in revision.c), so by the time path-walk sees the pending list after `prepare_revision_walk()` the tree-bearing pendings would already be gone. Fix this by setting revs->tree_objects = info->trees || info->blobs so pending trees survive `prepare_revision_walk()` whenever we need to walk into them. Path-walk still resets tree_objects to zero immediately after `prepare_revision_walk()` returns, so the rev-walk itself never enumerates trees redundantly with path-walk's own descent. Add coverage in t6601 for each of the four `object:type` values. The 'object:type=blob' test in particular asserts that file2 and child/file (both reachable only through tag-pointed trees) show up in the output, exercising the pending-tree fix. Update Documentation/git-pack-objects.adoc to add object:type to the list of supported --filter forms. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: support `tree:0` filterTaylor Blau3-70/+152
The `tree:0` object filter omits all trees and blobs from the result, keeping only commits and tags. Consequently, this filter type should has a fairly straightforward integration with path-walk, as the decision to include an object depends only on its type and does not depend on any path-sensitive state. Mapping it onto `path_walk_info` is direct: set `info->trees = 0` and `info->blobs = 0` in `prepare_filters()` when the `LOFC_TREE_DEPTH` choice is requested with depth zero. The existing code already plumbs those flags through the rest of the walk: - 'walk_objects_by_path()' sets `revs->blob_objects = info->blobs` and `revs->tree_objects = info->trees` before `prepare_revision_walk()`, so the revision walk doesn't try to enumerate trees or blobs itself. - The commit-walk loop short-circuits the root-tree fetch with "if (!info->trees && !info->blobs) continue;", so we never even look up the root tree, let alone descend into it. - `setup_pending_objects()` skips pending trees and blobs based on the same flags. This means the path-walk doesn't allocate or expand any tree structures at all under `tree:0`, which matches the intended behavior of the filter. However, this requires first fixing some issues with how the path-walk API handles directly-requested trees _and_ trees requested through lightweight tags. These changes create substantial updates to t6601-path-walk.sh, which the previous change highlighted as a problem by tagging otherwise-unreachable trees and having them not appear in the output. Non-zero tree-depth filters are not supported. Those depend on the depth at which a tree is visited, which is a path-walk concept the filter machinery doesn't currently share with the path-walk API. Reject them in `prepare_filters()` with a helpful error and let pack-objects fall back to the regular traversal, the same way it already does for unsupported filters. Add coverage in t6601 for both `--all` and a single-branch case to confirm that no trees or blobs are emitted, and a separate test that `tree:1` is rejected with the expected error message. Place the new tests before "setup sparse filter blob" so they run on the original set of refs, before the orphan branch that the sparse-tree tests create. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24t6601: tag otherwise-unreachable treesDerrick Stolee1-13/+11
The tests in t6601-path-walk.sh demonstrate the behavior of the path-walk API under different conditions. One thing that I noticed while updating the behavior of directly-requested objects is that we don't actually emit tagged trees. This was previously not noticed due to those tagged trees actually being reachable from commits that we are including in the path-walk. Update the test setup to have tree-tag and tree-tag2 point to trees that are otherwise unreachable. It is worth noting that this does not meaningfully change any of the other test cases, demontrating the bug. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24pack-objects: support sparse:oid filter with path-walkDerrick Stolee6-10/+350
The --filter=sparse:<oid> option to 'git pack-objects' allows focusing an object set to a sparse-checkout definition. This reduces the set of matching blobs while retaining all reachable trees. No server currently supports fetching with this filter because it is expensive to compute and reachability bitmaps do not help without a significant effort to extend the bitmap feature to store bitmaps for each supported sparse- checkout definition. Without focusing on serving fetches and clones with these filters, there are still benefits that could be realized by making this faster. With the sparse index, it's more realistic now than ever to be able to operate a local clone that was bootstrapped by a packfile created with a sparse filter, because the missing trees are not needed to move a sparse-checkout from one commit to another or to view the history of any path in scope. Such clones could perhaps be bootstrapped by partial bundles. Previously, constructing these sparse packs has been incredibly computationally inefficient. The revision walk that explores which objects are in scope spends a lot of time checking each object to see if it matches the sparse-checkout patterns, causing quadratic behavior (number of objects times number of sparse-checkout patterns). This improves somewhat when using cone-mode sparse-checkout patterns that can use hashtables and prefix matches to determine containment. However, the check per object is still too expensive for most cases. This is where the path-walk feature comes in. We can proceed as normal by placing objects in bins by path and _then_ check a group of objects all at once. Since sparse:<oid> only restricts blobs, the path-walk must include all reachable trees while using the cone-mode patterns to skip blobs at paths outside the sparse scope. This establishes a baseline for a potential future "treesparse:<oid>" filter that would also restrict trees, but introducing such a new filter is deferred to a later change. The implementation here is focused around loading the sparse-checkout patterns from the provided object ID and checking that the patterns are indeed cone-mode patterns. We can then load the correct pattern list into the path walk context and use the logic that already exists from bff45557675 (backfill: add --sparse option, 2025-02-03), though that feature loads sparse-checkout patterns from the worktree's local settings and also restricts tree objects. We use a combination of errors and warnings to signal problems during this load. The difference is that errors are likely fatal for the non-path-walk version while the warnings are probably just implementation details for the path-walk version and the 'git pack-objects' command can fall back to the revision walk version. Now that the SEEN flag is deferred until after pattern checks (from the previous commit), handle the case where a tree with a shared OID appears at both an out-of-cone and in-cone path. When trees are not being pruned (pl_sparse_trees == 0), the path-walk re-walks the tree at the in-cone path so that in-cone blobs within it are discovered. The new tests in t5317 and t6601 demonstrate this behavior and would fail without these changes. The performance test p5315 shows the impact of this change when using sparse filters: Test HEAD~1 HEAD ---------------------------------------------------------------------- 5315.10: repack (sparse:oid) 77.98 77.47 -0.7% 5315.11: repack size (sparse:oid) 187.5M 187.4M -0.0% 5315.12: repack (sparse:oid, --path-walk) 77.91 31.41 -59.7% 5315.13: repack size (sparse:oid, --path-walk) 187.5M 161.1M -14.1% These performance tests were run on the Git repository. The --path-walk feature shows meaningful space savings (14% smaller for sparse packs) and dramatic time savings (60% faster) by leveraging the path-walk's ability to skip blobs outside the sparse scope. Co-authored-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Taylor Blaue <me@ttaylorr.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: add pl_sparse_trees to control tree pruningDerrick Stolee5-3/+52
The path-walk API prunes trees and blobs when a sparse-checkout pattern list is provided, which is the correct behavior for 'git backfill --sparse' since it only needs to fill in objects at paths within the sparse cone. However, a future change will use the path-walk API with a sparse:<oid> filter that restricts only blobs while retaining all reachable trees. To support both behaviors, add a 'pl_sparse_trees' flag to path_walk_info. When set (as in 'git backfill --sparse' and the --stdin-pl test helper mode), the sparse patterns prune both trees and blobs. When unset, only blobs are filtered and all trees are walked and reported. Additionally, move the SEEN flag assignment in add_tree_entries() to after the sparse pattern and pathspec checks. Previously, SEEN was set immediately upon discovering an object, before checking whether its path matched the sparse patterns. When the same object ID appeared at multiple paths (e.g. sibling directories with identical contents), the first path to be visited would mark the object as SEEN. If that path was outside the sparse cone, the object would be skipped there but also never discovered at its in-cone path. By deferring the SEEN flag until after the checks pass, objects that are skipped due to sparse filtering remain discoverable at other paths where they may be in scope. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: support blob size limit filterDerrick Stolee6-6/+130
Extend the path-walk API to handle the 'blob:limit=<size>' object filter natively. This filter omits blobs whose size is equal to or greater than the given limit, matching the semantics used by the list-objects-filter machinery. When revs->filter.choice is LOFC_BLOB_LIMIT, the prepare_filters() method stores the limit value in info->blob_limit and clears the filter from revs. If the limit is zero, this degenerates to blob:none (all blobs excluded), so info->blobs is set to 0 instead. During walk_path(), blob batches are filtered before being delivered to the callback: each blob's size is checked via odb_read_object_info(), and only blobs strictly smaller than the limit are included. Blobs whose size cannot be determined (e.g. missing in a partial clone) are conservatively included, matching the existing filter behavior. Empty batches after filtering are skipped entirely. The check for inclusion in the path batch looks a little strange at first glance. We use odb_read_object_info() to read the object's size. Based on all of the assumptions to this point, this _should_ return OBJ_BLOB. Since we are focused on the size filter, we use a short-circuited OR (||) to skip the size check if that method returns a different object type. Notice that this inspection of object sizes requires the content to be present in the repository. The odb_read_object_info() call will download a missing blob on-demand. This means that the use of the path-walk API within 'git backfill' would not operate nicely with this filter type. The intention of that command is to download missing blobs in batches. Downloading objects one-by-one would go against the point. Update the validation in 'git backfill' to add its own compatibility check on top of path_walk_filter_compatible(). Add tests for blob:limit=0 (equivalent to blob:none) and blob:limit=3 (which exercises partial filtering within a batch where some blobs are kept and others are excluded). Co-authored-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24backfill: die on incompatible filter optionsDerrick Stolee2-3/+10
The 'git backfill' command uses the path-walk API in a critical way: it uses the objects output from the command to find the batches of missing objects that should be requested from the server. Unlike 'git pack-objects', we cannot fall back to another mechanism. The previous change added the path_walk_filter_compatible() method that we can reuse here. Use it during argument validation in cmd_backfill(). Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: support blobless filterDerrick Stolee7-14/+113
The 'git pack-objects' command can opt-in to using the path-walk API for scanning the objects. Currently, this option is dynamically disabled if combined with '--filter=<X>', even when using a simple filter such as 'blob:none' to signal a blobless packfile. This is a common scenario for repos at scale, so is worth integrating. Also, users can opt-in to the '--path-walk' option by default through the pack.usePathWalk=true config option. When using that in a blobless partial clone, the following warning can appear even though the user did not specify either option directly: warning: cannot use --filter with --path-walk Teach the path-walk API to handle the 'blob:none' object filter natively. When revs->filter.choice is LOFC_BLOB_NONE, the path-walk sets info->blobs to 0 (skipping all blob objects) and clears the filter from revs so that prepare_revision_walk() does not reject the configuration. This check is implemented in the static prepare_filters() method, which will simultaneously check if the input filters are compatible and will make the appropriate mutations to the path_walk_info and filters if the path_walk_info is non-NULL. This allows us to use this logic both in the API method path_walk_filter_compatible() for use in builtin/pack-objects.c and as a prep step in walk_objects_by_path(). Update the test helper (test-path-walk) to accept --filter=<spec> as a test-tool option (before '--'), applying it to revs after setup_revisions() to avoid the --objects requirement check. We can also revert recent GIT_TEST_PACK_PATH_WALK overrides in t5620. Also switch test-path-walk from REV_INFO_INIT with manual repo assignment to repo_init_revisions(), which properly initializes the filter_spec strbuf needed for filter parsing. Add tests for blob:none with --all and with a single branch. The performance test p5315 shows the impact of this change when using blobless filters: Test HEAD~1 HEAD --------------------------------------------------------------------- 5315.6: repack (blob:none) 13.53 13.87 +2.5% 5315.7: repack size (blob:none) 137.7M 137.8M +0.1% 5315.8: repack (blob:none, --path-walk) 13.51 23.43 +73.4% 5315.9: repack size (blob:none, --path-walk) 137.7M 115.2M -16.3% These performance tests were run on the Git repository. The --path-walk feature shows meaningful space savings (16% smaller for blobless packs) at the cost of increased computation time due to the two compression passes. This data demonstrates that the feature is engaged and provides real compression benefits when --no-reuse-delta forces fresh deltas. Co-Authored-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24path-walk: always emit directly-requested objectsDerrick Stolee3-15/+39
We are preparing to integrate the path-walk API with some --filter options in 'git pack-objects', but there is a subtle issue that is revealed when those are put together and the test suite is run with GIT_TEST_PACK_PATH_WALK=1. When a filter reduces the set of requested objects, this results in filtering out directly-requested objects, such as in the download of needed blobs in a blobless partial clone. The root cause is that the scan of pending objects in the path-walk API respects the filters set in the path_walk_info instead of overriding them for pending objects. We can tell that a path is part of the directly-referenced objects if its path name starts with '/' (other paths, including root trees never have this starting character). Create a path_is_for_direct_objects() to make this meaning clear, especially as we add more references in the future as we integrate the path-walk API with partial clone filter options. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24t/perf: add pack-objects filter and path-walk benchmarkDerrick Stolee1-0/+129
Add p5315-pack-objects-filter.sh to measure the performance of 'git pack-objects --revs --all' under different filter and traversal combinations: * no filter (baseline) * --filter=blob:none (blobless) * --filter=sparse:oid=<oid> (cone-mode sparse) Each filter scenario is tested both with and without --path-walk, producing paired measurements that show the impact of the path-walk traversal for each filter type as we integrate the --path-walk feature with different --filter options. It currently has no integration so falls back to the standard revision walk. Thus, there are no significant differences in the current results other than a full repack (and even then, the --path-walk feature is not incredibly different for the default Git repository): Test HEAD ----------------------------------------------------- 5315.2: repack (no filter) 27.91 5315.3: repack size (no filter) 250.7M 5315.4: repack (no filter, --path-walk) 34.92 5315.5: repack size (no filter, --path-walk) 220.0M 5315.6: repack (blob:none) 13.63 5315.7: repack size (blob:none) 137.6M 5315.8: repack (blob:none, --path-walk) 13.48 5315.9: repack size (blob:none, --path-walk) 137.7M 5315.10: repack (sparse:oid) 72.67 5315.11: repack size (sparse:oid) 187.4M 5315.12: repack (sparse:oid, --path-walk) 72.47 5315.13: repack size (sparse:oid, --path-walk) 187.4M The sparse filter definition is built automatically by sampling depth-2 directories from the test repository, making the test work on any repo passed via GIT_PERF_LARGE_REPO. For repos that lack depth-2 directories, a single top-level directory is used; for flat repos, the sparse tests are skipped via prerequisite. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24pack-objects: pass --objects with --path-walkDerrick Stolee1-4/+1
When 'git pack-objects' has the --path-walk option enabled, it uses a different set of revision walk parameters than normal. For one, --objects was previously assumed by the path-walk API and could be omitted. We also needed --boundary to allow discovering UNINTERESTING objects to use as delta bases. We will be updating the path-walk API soon to work with some filter options. However, the revision machinery will trigger a fatal error: fatal: object filtering requires --objects The fix is easy: add the --objects option as an argument. This has no effect on the path-walk API but does simplify the revision option parsing for the objects filter. We can remove the comment about "removing" the options because they were never removed and instead not added. We still need to disable using bitmaps. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-24t5620: make test work with path-walk varDerrick Stolee1-0/+9
The GIT_TEST_PACK_PATH_WALK test variable allows enabling the --path-walk option to 'git pack-objects' by default. This sometimes engages the warning that --path-walk is incompatible with the --filter option. These tests in t5620 fail due to this warning over stderr in this case. Disable this variable for this moment until these options work together. Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22transport-helper: fix typo in BUG() messageJeff King1-1/+1
We mistakenly refer to the git_connect_service enum as "_type" rather than "_service". Users should never see this message in practice, but it is slightly confusing when reading the code. Reported-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22doc: hook: don’t self-link via config includeKristoffer Haugsbakk2-6/+14
Do not link to git-hook(1) from the config options when we already are in that doc. This implementation is similar to the updates to git-init(1) and git-commit(1), implemented in [1] and [2], respectively. † 1: e7b3a768 (doc: git-init: rework config item init.templateDir, 2024-03-10) † 2: 819fdd6e (doc: convert git commit config to new format, 2025-01-15) Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22doc: config: include existing git-hook(1) sectionKristoffer Haugsbakk1-0/+2
It is already included in git-hook(1) but missing from git-config(1). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22doc: hook: consistently capitalize GitKristoffer Haugsbakk1-4/+4
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22doc: hook: remove stray backtickKristoffer Haugsbakk1-1/+1
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22remote: qualify "git pull" advice for non-upstream compareBranchesHarald Nordgren2-8/+140
Enable ENABLE_ADVICE_PULL for push-branch comparisons too, not just the upstream entry, so the "use git pull" hint prints when the local branch is behind its push branch. Spell out "git pull <remote> <branch>" so running the suggested command actually pulls the ref the user was told about; plain "git pull" would fetch the upstream instead. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22Merge branch 'ps/setup-wo-the-repository' into ps/setup-centralize-odb-creationJunio C Hamano84-384/+403
* ps/setup-wo-the-repository: setup: stop using `the_repository` in `init_db()` setup: stop using `the_repository` in `create_reference_database()` setup: stop using `the_repository` in `initialize_repository_version()` setup: stop using `the_repository` in `check_repository_format()` setup: stop using `the_repository` in `upgrade_repository_format()` setup: stop using `the_repository` in `setup_git_directory()` setup: stop using `the_repository` in `setup_git_directory_gently()` setup: stop using `the_repository` in `setup_git_env()` setup: stop using `the_repository` in `set_git_work_tree()` setup: stop using `the_repository` in `setup_work_tree()` setup: stop using `the_repository` in `enter_repo()` setup: stop using `the_repository` in `verify_non_filename()` setup: stop using `the_repository` in `verify_filename()` setup: stop using `the_repository` in `path_inside_repo()` setup: stop using `the_repository` in `prefix_path()` setup: stop using `the_repository` in `is_inside_work_tree()` setup: stop using `the_repository` in `is_inside_git_dir()` setup: replace use of `the_repository` in static functions
2026-05-22The 7th batchJunio C Hamano1-0/+7
With this batch, we have flushed all the topics that need to be merged to 'maint' to make its build healthy. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22Merge branch 'ps/maintenance-daemonize-lockfix'Junio C Hamano6-4/+143
"git maintenance" that goes background did not use the lockfile to prevent multiple maintenance processes from running at the same time, which has been corrected. * ps/maintenance-daemonize-lockfix: run-command: honor "gc.auto" for auto-maintenance builtin/maintenance: fix locking with "--detach"
2026-05-22Merge branch 'jk/apply-leakfix'Junio C Hamano1-2/+4
Leakfix. * jk/apply-leakfix: apply: plug leak on "patch too large" error
2026-05-22Merge branch 'jk/commit-sign-overflow-fix'Junio C Hamano1-16/+15
Leakfix. * jk/commit-sign-overflow-fix: commit: handle large commit messages in utf8 verification
2026-05-21git-jump: pick a mode automatically when invoked without argumentsGreg Hurrell2-3/+35
When `git jump` is invoked with no positional arguments (and no arguments after `--stdout`) it currently prints usage and exits with status 1. But there are two situations where we can usefully infer the most valuable and likely mode that a user would want to use, and select it automatically: 1. When there are unmerged paths in the index, the user likely wants `git jump merge`. 2. When the working tree has unstaged changes, the user likely wants `git jump diff`. In this commit we teach `git jump` a new "auto" mode which detects these cases and dispatches to the corresponding mode automatically. The user can either explicitly spell out `git jump auto`, or just leave it at `git jump` (because "auto" is the default). If none of the interesting cases listed above applies, then auto mode falls back to the existing usage-and-exit behavior. Signed-off-by: Greg Hurrell <greg.hurrell@datadoghq.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21Merge branch 'ps/odb-in-memory' into ps/odb-source-looseJunio C Hamano25-331/+1158
* ps/odb-in-memory: (24 commits) t/unit-tests: add tests for the in-memory object source odb: generic in-memory source odb/source-inmemory: stub out remaining functions odb/source-inmemory: implement `freshen_object()` callback odb/source-inmemory: implement `count_objects()` callback odb/source-inmemory: implement `find_abbrev_len()` callback odb/source-inmemory: implement `for_each_object()` callback odb/source-inmemory: convert to use oidtree oidtree: add ability to store data cbtree: allow using arbitrary wrapper structures for nodes odb/source-inmemory: implement `write_object_stream()` callback odb/source-inmemory: implement `write_object()` callback odb/source-inmemory: implement `read_object_stream()` callback odb/source-inmemory: implement `read_object_info()` callback odb: fix unnecessary call to `find_cached_object()` odb/source-inmemory: implement `free()` callback odb: introduce "in-memory" source odb/transaction: make `write_object_stream()` pluggable object-file: generalize packfile writes to use odb_write_stream object-file: avoid fd seekback by checking object size upfront ...
2026-05-21gitlab-ci: update macOS imagePatrick Steinhardt1-2/+2
The GitLab CI jobs for macOS are all using the macOS 15 images. While these images are not deprecated yet, there is a new image for macOS 26 generally available by now [1]. Switch two of our jobs to use the new image. The third job still continues to use the old image. This ensures broader test coverage until this old image gets deprecated. [1]: https://docs.gitlab.com/ci/runners/hosted_runners/macos/ Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21gitlab-ci: upgrade macOS runnersPatrick Steinhardt1-1/+1
We're currently using M1-based runners for our macOS jobs. GitLab has since introduced a new M2 Pro-based runner type that is available for all GitLab tiers [1], which upgrades from 4 to 6 cores and from 8 to 16 GB RAM. Upgrade to this new runner type, which results in some nice speedups: - osx-clang goes from 26 minutes to 16 minutes. - osx-meson goes from 19 minutes to 13 minutes. - osx-reftable goes from 23 minutes to 14 mintues. [1]: https://docs.gitlab.com/ci/runners/hosted_runners/macos/ Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21approxidate: use deferred mday adjustments for "specials"Tuomas Ahola2-10/+25
There are cases where the "wrap-to-yesterday" behavior of "tea" and "noon" should be reverted later on down the line, so that "today tea" and "tea today" won't yield different results. However, the logic of approxidate doesn't seem to lend itself particularly well to such cases. Start tackling the issue by reusing negative values of `tm->tm_mday` field for deferred date adjustments which can be easily reverted, so that the default logic of the special formats only applies if we don't get any explicit date (mday) specification. In particular, overwrite the field with -1 in "today" and "yesterday", so that those formats will be relative to the current date. That makes specifications like "tea yesterday" behave more sensibly: instead of going backwards to the last tea-time and then a day back, Git will now understand that as the tea-time of yesterday. Replace the call of `update_tm()` in `date_time()` with the assignment `tm->tm_mday = -2`. Add the corresponding code to handle that in `update_tm()`, wrapping to the previous day if the field still holds such assignment, meaning that we haven't seen any better specification for the day-of-month. On the other hand, `mday=-3` would mean going two days back and so on. Even though such functionality isn't actually needed by this patch, it won't add much complexity in the code and is rather natural way to handle such values. As `date_time()` won't no longer need the `now` struct, mark the associated function parameters as unused. The parameters themselves have to stay, however, as those functions are called through pointers in `approxidate_alpha`. Add relevant tests to cover the changes. Signed-off-by: Tuomas Ahola <taahol@utu.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21approxidate: make "specials" respect fixed day-of-monthTuomas Ahola2-1/+9
The special approxidate time formats, "noon" and "tea" differ from "12pm" and "5pm" by having the feature of wrapping to the previous day if the current time is before those hours: now -> 2026-05-13 11:00:00 +0000 12pm -> 2026-05-13 12:00:00 +0000 5pm -> 2026-05-13 17:00:00 +0000 noon -> 2026-05-12 12:00:00 +0000 tea -> 2026-05-12 17:00:00 +0000 However, that logic carries too far. Even when the date is specified, the behavior of the "specials" depends on the current time. Assuming the same time as above, we get: today at noon -> 2026-05-12 12:00:00 +0000 (should be 13 May) 13 May at tea -> 2026-05-12 17:00:00 +0000 or, using an example mentioned in date-formats.adoc: last Friday at noon -> 2026-05-07 12:00:00 +0000 (should be 8 May) The quirk seems to be rather old. Already in 2006, Linus Torvalds remarked that the date yielded by "one year ago yesterday at tea-time" was "just silly and not even correct". Indeed, even today it gives: One year ago yesterday at tea-time -> 2025-05-11 17:00:00 +0000 (should be 12 May) Let's fix all of those with a simple patch. Check whether we already have a specified day-of-month in `tm->tm_mday` and make `date_time()` stick to it. Ensure the correct behavior with relevant tests. Links: 1. https://lore.kernel.org/git/Pine.LNX.4.64.0610101102560.3952@g5.osdl.org/ Signed-off-by: Tuomas Ahola <taahol@utu.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21t0006: add support for approxidate test date adjustmentTuomas Ahola1-1/+32
t0006 uses a hard-coded test date and provides no convenient way to override it temporarily. Add an optional parameter to check_approxidate to adjust the time as needed, and demonstrate the feature with a new test. Signed-off-by: Tuomas Ahola <taahol@utu.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21approxidate: make "today" wrap to midnightTuomas Ahola3-1/+16
Although some commands do reject invalid approxidate expressions, in other cases those are simply evaluated as the current time. Oftentimes that is a perfectly good compromise to handle silly requests, but it isn't without rough edges. Because of the silent acceptance, it is easy to forget that "today" isn't actually a valid approxidate format. That is a bit awkward because while the fallback logic of using the current time does make some sense, there is no deliberative decision behind such behavior of "today". Indeed, whatever (non-)action "today" currently has, is just an accidental side effect. That means "git log --since=today" is currently unlikely to print anything at all as it tries to list commits dated with *future* timestamps. Arguably it would be more useful to list the commits of the current day---i.e. those made since midnight. On the other hand, "git log --until=today" doesn't really filter commits at all. Changing the definition of "today" would make it return the commits made before the current day. That isn't without problems though---running "git log --until=today" in the late afternoon could reasonably include the work done earlier that day (as the command currently does do). Still the utility of no-op "--until=today" is debatable and perhaps outweighed by the pros of having "--since=today" to mean "--since=midnight". The thing is that the approxidate machinery doesn't know about its consumers, so the meaning of "today" has to be the same for "--since" and "--until". In fact, "git log --until=" is documented as `--until=<date>`:: `--before=<date>`:: Show commits older than _<date>_, so excluding commits made today would actually match the documentation more closely. Moreover, a revision parameter "@{today}" is currently outright rejected. Making "today" a valid approxidate time format could make a natural way to specify the state of the ref at the start of the current day. Bind "today" to new function `date_today()` as an approxidate special. Make it return the last midnight if no specific time is given; i.e. retain the old behavior of "noon today" and such. Document the new behavior of "git log --since=today" in rev-list-options.adoc. Signed-off-by: Tuomas Ahola <taahol@utu.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21Documentation/git-range-diff: add missing notes options in synopsisSiddh Raman Pant1-1/+1
git-range-diff supports note options which are also mentioned later in the help, but they are missing from the synopsis. Let's fix that. Signed-off-by: Siddh Raman Pant <siddh.raman.pant@oracle.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21Sync with 'maint'Junio C Hamano2-8/+29
2026-05-21Start preparing for 2.54.1Junio C Hamano2-1/+30
Mostly build and CI related updates taken from the 'master' front are included in here. We still need to grab a couple more topics once they graduate to 'master', namely jk/apply-leakfix jk/commit-sign-overflow-fix Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21Merge branch 'jc/t5551-fix-expensive' into maint-2.54Junio C Hamano1-0/+1
Test fix. * jc/t5551-fix-expensive: t5551: "GIT_TEST_LONG=Yes make test" is broken
2026-05-21Merge branch 'jh/alias-i18n-fixes' into maint-2.54Junio C Hamano3-3/+34
Further update to the i18n alias support to avoid regressions. * jh/alias-i18n-fixes: alias: restore support for simple dotted aliases
2026-05-21Merge branch 'js/mingw-no-nedmalloc' into maint-2.54Junio C Hamano10-7080/+1
Stop using unmaintained custom allocator in Windows build which was the last user of the code. * js/mingw-no-nedmalloc: mingw: remove the vendored compat/nedmalloc/ subtree mingw: drop the build-system plumbing for nedmalloc mingw: stop using nedmalloc
2026-05-21Merge branch 'js/maintenance-fix-deadlock-on-win10' into maint-2.54Junio C Hamano3-3/+67
To help Windows 10 installations, avoid removing files whose contents are still mmap()'ed. * js/maintenance-fix-deadlock-on-win10: maintenance(geometric): do release the `.idx` files before repacking mingw: optionally use legacy (non-POSIX) delete semantics
2026-05-21Merge branch 'js/t5564-socks-use-short-path' into maint-2.54Junio C Hamano1-2/+9
Avoid hitting the pathname limit for socks proxy socket during the test. * js/t5564-socks-use-short-path: t5564: use a short path for the SOCKS proxy socket
2026-05-21Merge branch 'js/ci-github-actions-update' into maint-2.54Junio C Hamano5-34/+34
Update various GitHub Actions versions. * js/ci-github-actions-update: l10n: bump mshick/add-pr-comment from v2 to v3 ci: bump git-for-windows/setup-git-for-windows-sdk from v1 to v2 ci: bump actions/checkout from v5 to v6 ci: bump actions/github-script from v8 to v9 ci: bump actions/{upload,download}-artifact to v7 and v8 ci: bump microsoft/setup-msbuild from v2 to v3
2026-05-21Merge branch 'jk/revert-aa-reap-transport-child-processes' into maint-2.54Junio C Hamano2-6/+0
Revert a recent change that introduced a regression to help mksh users. * jk/revert-aa-reap-transport-child-processes: Revert "transport-helper, connect: use clean_on_exit to reap children on abnormal exit"
2026-05-21Merge branch 'ps/clang-w-glibc-2.43-and-_Generic' into maint-2.54Junio C Hamano2-0/+13
Headers from glibc 2.43 when used with clang does not allow disabling C11 language features, causing build failures.. * ps/clang-w-glibc-2.43-and-_Generic: build: tolerate use of _Generic from glibc 2.43 with Clang
2026-05-21The 6th batchJunio C Hamano1-0/+21
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21Merge branch 'sp/shallow-deepen-on-non-shallow-repo-fix'Junio C Hamano2-1/+15
"git fetch --deepen=<n>" in a full clone truncated the history to <n> commits deep, which has been corrected to be a no-op instead. * sp/shallow-deepen-on-non-shallow-repo-fix: shallow: fix relative deepen on non-shallow repositories
2026-05-21Merge branch 'jc/ci-enable-expensive'Junio C Hamano1-4/+6
Enable expensive tests to catch topics that may cause breakages on integration branches closer to their origin in the contributor PR builds. * jc/ci-enable-expensive: ci: enable EXPENSIVE for contributor builds