summaryrefslogtreecommitdiff
path: root/t/meson.build
AgeCommit message (Collapse)AuthorFilesLines
2026-08-25Merge branch 'ss/repack-drop-filtered'Junio C Hamano1-0/+1
'git repack' has been taught '--drop-filtered' to delete local promisor blobs exceeding a limit (currently 'blob:limit=') in partial clones, reclaiming space. Guards prevent running during other operations or if referenced by the index. * ss/repack-drop-filtered: builtin/repack: add guards for --drop-filtered builtin/repack: actually drop filtered promisor blobs builtin/repack: enumerate promisor blobs for --drop-filtered repack-promisor: allow excluding objects from the rebuilt promisor pack list-objects-filter: add list_objects_filter__filter_oidset() builtin/repack: add --drop-filtered and --dry-run options
2026-08-23Merge branch 'kk/merge-base-exhaustion'Junio C Hamano1-0/+1
The merge-base computation has been optimized by stopping the walk early when one side's exclusive commits in the queue are exhausted, yielding significant speedups for queries with one-sided histories. * kk/merge-base-exhaustion: commit-reach: remove commit-date ordering fallback commit-reach: move min_generation check into paint_queue_get() commit-reach: terminate merge-base walk when one paint side is exhausted commit-reach: introduce struct paint_state with per-side counters t6600: add clock-skew topologies and step counts for edge cases commit-reach: add trace2 instrumentation to paint_down_to_common() t6099: add side-exhaustion regression test t6600: add test cases for side-exhaustion edge cases test-lib-functions: improve diagnostic output for trace2 data assertions Documentation/technical: add paint-down-to-common doc
2026-08-15Merge branch 'jc/add-resolved'Junio C Hamano1-0/+1
'git add' has been taught a new '--resolved' option to stage conflict-resolved paths, while leaving unrelated local changes unstaged. It scans the unmerged paths for leftover conflict markers and aborts if any are found. * jc/add-resolved: add: introduce '--resolved' option read-cache: add remove_file_from_index_with_flags() merge-ll: consolidate conflict marker scanning logic read-cache: reindent
2026-08-13builtin/repack: add --drop-filtered and --dry-run optionsSiddharth Shrimali1-0/+1
Add two new command-line options to 'git-repack': --drop-filtered: intended to eventually delete objects that match the filter specification. Requires --filter and -a, and is incompatible with --filter-to. --dry-run: show which objects would be dropped without making any changes. Only meaningful with --drop-filtered. Keep --dry-run as a separate option rather than folding it into --drop-filtered (e.g. --drop-filtered=dry-run), to stay consistent with the --dry-run option other Git commands already provide and to leave room for it to describe other repack behavior later. A --drop-filtered=<mode> form can still be added later if more drop-specific modes are needed. --drop-filtered also requires a promisor remote to be configured, since dropping objects without a remote to fetch them back from would be permanent data loss. --drop-filtered is incompatible with bitmap writing: filtering breaks the "all objects in one pack" closure that bitmaps require. Detect an explicit -b/--write-bitmap-index on the command line with a dedicated option callback that sets a "write_bitmaps_given" flag, so it can be distinguished from a repack.writeBitmaps configuration value even when config already enables bitmaps. An explicit -b is reported as a conflict, while a config-provided default is silently disabled for the duration of the command. These options currently only perform validation. The actual enumeration and deletion will be added in follow-up commits. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Siddharth Asthana <siddharthasthana31@gmail.com> Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11t6099: add side-exhaustion regression testKristofer Karlsson1-0/+1
Add t6099 to test the case where multiple merge-base candidates exist and one is an ancestor of another. This exercises the side-exhaustion optimization in paint_down_to_common together with the remove_redundant safety net in get_merge_bases_many_0. Signed-off-by: Kristofer Karlsson <krka@spotify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-31add: introduce '--resolved' optionJunio C Hamano1-0/+1
During a conflicted merge, rebase, or cherry-pick, 'git add -u' is a handy way to add modified paths to the index. However, '-u' indiscriminately adds all modified tracked paths, including unmerged paths that may still contain unresolved conflict markers. It also adds tracked files modified in the worktree that are not involved in the ongoing merge. The latter is not a huge problem for "git rebase", which refuses to start with any local changes, but is a problem for "git merge", which is often run with local changes in maintainer workflows. Introduce 'git add --resolved' to add only unmerged paths, limited by an optional pathspec, where no conflict markers remain in the working tree. Before modifying the index, scan unmerged regular files for leftover conflict markers using a new helper, has_conflict_markers(), defined in merge-ll.c in terms of the is_conflict_marker_line() helper we introduced earlier. If any unmerged path still contains conflict markers, show an error listing the conflicted paths and abort without updating the index. Otherwise, add these unmerged paths that do not have conflict markers to the index. Note that unmerged paths without conflict markers (such as binary files and deletions) are added as resolved using add_file_to_index() and remove_file_from_index_with_flags(). Tracked files that were not in a conflicted state are ignored by '--resolved'. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-30Merge branch 'ps/cat-file-remote-object-info'Junio C Hamano1-0/+1
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-27Merge branch 'ps/shift-root-in-graph'Junio C Hamano1-0/+1
'git log --graph' has been modified to visually distinguish parentless 'root' commits (and commits that become roots due to history simplification) by indenting them, preventing them from appearing falsely related to unrelated commits rendered immediately above them. * ps/shift-root-in-graph: graph: add --[no-]graph-indent and log.graphIndent graph: move config reading into graph_read_config() graph: wrap cascading commits after 4 columns graph: indent visual root in graph graph: add a 2 commit buffer for lookahead revision: add next_commit_to_show() lib-log-graph: move check_graph function
2026-07-24cat-file: add remote-object-info to batch-commandEric Ju1-0/+1
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-15Merge branch 'ps/history-drop'Junio C Hamano1-0/+1
The experimental 'git history' command has been taught a new 'drop' subcommand to remove a commit, with its descendants replayed onto its parent. * ps/history-drop: builtin/history: implement "drop" subcommand builtin/history: split handling of ref updates into two phases replay: expose `replay_result_queue_update()` reset: stop assuming that the caller passes in a clean index reset: allow the caller to specify the current HEAD object reset: introduce ability to skip updating HEAD reset: introduce dry-run mode reset: modernize flags passed to `reset_working_tree()` reset: rename `reset_head()` reset: drop `USE_THE_REPOSITORY_VARIABLE` read-cache: split out function to drop unmerged entries to stage 0
2026-07-15Merge branch 'ps/refs-writing-subcommands'Junio C Hamano1-0/+4
The 'git refs' toolbox has been extended with new 'create', 'delete', 'update', and 'rename' subcommands to create, delete, update, and rename references, respectively. * ps/refs-writing-subcommands: builtin/refs: add "rename" subcommand builtin/refs: add "create" subcommand builtin/refs: add "update" subcommand builtin/refs: add "delete" subcommand builtin/refs: drop `the_repository`
2026-07-14graph: indent visual root in graphPablo Sabater1-0/+1
When rendering a graph, if the history contains multiple "visual roots", actual roots or commits that look like roots (i.e. have their parents filtered out) can end up being vertically adjacent to unrelated commits, falsely appearing to be related. A fix for this issue was already attempted [1] a while ago. This happens because the commits fill the space from left to right and when a visual root ends, its column becomes free for the following commit even if they are not related. Once this happens the unrelated commit is rendered below the visual root. Because there is no special character or way to identify when a visual root is rendered making the graph confusing. By indenting the visual roots when there are still commits to show the vertical adjacency can be avoided. Add is_visual_root flag to git_graph making it visible in all graph states, give graph_update() a new function, graph_is_visual_root() to know if the current commit is a visual root and set is_visual_root. The different handled cases are: - If a visual root has children: similar to GRAPH_PRE_COMMIT state when octopus merges need space, an edge row needs to be printed to connect the child with the indented visual root. A new state GRAPH_PRE_ROOT is needed to connect the child with the visual root: * child of the visual root \ GRAPH_PRE_ROOT * visual root indented - If a visual root is child-less we can skip GRAPH_PRE_ROOT state and render the indented commit directly. * visual root indented * unrelated commit - If two or more visual roots are adjacent: by having a lookahead to the next commit that will be rendered, if the next commit is also a visual root and we are on a visual root, meaning two visual root adjacent in the history, the top one can omit the indent, making the one below to indent only once, if there are more adjacent visual commits, the indentation will increase for each adjacent one, cascading. * visual root * visual root * visual root * last commit Even if the last commit is a root, because there is nothing that will be rendered below we can omit the indentation on purpose. [1]: https://lore.kernel.org/git/xmqqwnwajbuj.fsf@gitster.c.googlers.com/ Helped-by: Kristofer Karlsson <krka@spotify.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-07-06Merge branch 'mv/log-follow-mergy'Junio C Hamano1-0/+1
"git log --follow" has been updated to better handle non-linear history, in which the path being tracked gets renamed differently in multiple history lines. * mv/log-follow-mergy: log: improve --follow following renames for non-linear history
2026-07-06Merge branch 'en/ort-harden-against-corrupt-trees'Junio C Hamano1-0/+1
The 'ort' merge backend has been hardened against corrupt trees by ensuring it aborts under appropriate error conditions. * en/ort-harden-against-corrupt-trees: cache-tree: fix verify_cache() to catch non-adjacent D/F conflicts merge-ort: abort merge when trees have duplicate entries merge-ort: free diff pairs queue in clear_or_reinit_internal_opts() merge-ort: drop unnecessary show_all_errors from collect_merge_info() merge-ort: propagate callback errors from traverse_trees_wrapper()
2026-07-06builtin/refs: add "rename" subcommandPatrick Steinhardt1-0/+1
Add a "rename" subcommand to git-refs(1) with the syntax: $ git refs rename <oldref> <newref> It renames <oldref> together with its reflog to <newref>; even when used on a local branch ref, the current value and the reflog of the ref are the only things that are renamed. Document it and redirect casual users to "git branch -m" if that is what they wanted to do. Co-authored-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06builtin/refs: add "create" subcommandPatrick Steinhardt1-0/+1
The "update" subcommand cannot only update an existing reference, but it can also create new branches and delete existing branches by specifying the all-zeroes object ID as either old or new value. Despite that, we already have the "delete" subcommand as a handy shortcut so that a user can easily delete a branch. This relieves them of needing to understand the more arcane uses of the "update" command, and of counting the number of zeroes they need to pass. But while we have a "delete" subcommand, we don't have an equivalent that would allow the user to create a new branch, which creates a certain asymmetry. Add a new "create" subcommand to plug this gap. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06builtin/refs: add "update" subcommandPatrick Steinhardt1-0/+1
Add a new "update" subcommand which mirrors `git update-ref <refname> <oldoid> <newoid>`. This follows the same reasoning as the preceding commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06builtin/refs: add "delete" subcommandPatrick Steinhardt1-0/+1
Reference-related functionality in Git is currently spread across many different commands: git-update-ref(1), git-for-each-ref(1), git-show-ref(1), git-pack-refs(1) and git-symbolic-ref(1). This makes it hard for users to discover what functionality we have available to work with references. We have thus started to consolidate this functionality into git-refs(1), which is a toolbox of everything related to references. Until now, the command doesn't handle functionality of git-update-ref(1). Fix this gap by introducing a new "delete" subcommand, which is the equivalent of `git update-ref -d`. Note that we're intentionally not using a generic "write" subcommand with a "-d" flag. This is rather harder to discover, and subcommands that are implmented as flags tend to be hard to reason about in the code as we'd have to handle mutually-exclusive flags that stem from the other subcommand-like modes. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-03builtin/history: implement "drop" subcommandPatrick Steinhardt1-0/+1
A common operation when editing the commit history is to drop a specific commit from the history entirely, but this operation is not currently covered by git-history(1). A couple of noteworthy bits: - This is the first git-history(1) command that will ultimately result in changes to both the index and the working tree. We thus have to add logic to merge resulting changes into those. - It is still not possible to replay merge commits, so this limitation is inherited for the new "drop" command. - For now we refuse to drop root commits. While we _can_ indeed drop root commits in the general case, there are edge cases where the resulting history would become completely empty. This is thus left to a subsequent patch series. Other than that, most of the logic is rather straight-forward as we can continue to build on the preexisting logic in git-history(1) for most of the part. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-22log: improve --follow following renames for non-linear historyMiklos Vajna1-0/+1
Have a repo with a subtree merge, do a 'git log --follow prefix/test.c', the output only contains history in the outer repo, not commits that were merged via a subtree merge. What happens is that 'git log --follow' stores the followed path only in opt->diffopt.pathspec, so in case the commit history is non-linear, and multiple parents have renames to the followed path, then the end result isn't really defined: the first commit that happens to be visited in one of the parents update opt->diffopt.pathspec, and from that point, only that updated path is visited. Fix the problem by introducing a commit -> path map (follow_pathspec_slab) that stores what will be a path to follow when visiting that parent. At the top of log_tree_commit(), if the slab has an entry for this commit, we replace opt->diffopt.pathspec with a path from this entry, so the correct path is followed, even if an unrelated sub-tree changed the path to be followed to something else. After log_tree_diff() runs, we record each parent's path in the slab. As a result, the walk order doesn't matter, which was exactly the source of problems previously. This helps with subtree merges (rename happens inside the merge commit), but also fixes the general case when the rename happens in the history of parents, not in the merge commit itself. Signed-off-by: Miklos Vajna <vmiklos@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-14cache-tree: fix verify_cache() to catch non-adjacent D/F conflictsElijah Newren1-0/+1
verify_cache() checks that the index does not contain both "path" and "path/file" before writing a tree. It does this by comparing only adjacent entries, relying on the assumption that "path/file" would immediately follow "path" in sorted order. Unfortunately, this assumption does not always hold. For example: docs <-- submodule entry docs-internal/README.md <-- intervening entry docs/requirements.txt <-- D/F conflict, NOT adjacent to "docs" When this happens, verify_cache() silently misses the D/F conflict and write-tree produces a corrupt tree object containing duplicate entries (one for the submodule "docs" and one for the tree "docs"). I could not find any caller in current git that both allows the index to get into this state and then tries to write it out without doing other checks beyond the verify_cache() call in cache_tree_update(), but verify_cache() is documented as a safety net for preventing corrupt trees and should actually provide that guarantee. A downstream consumer that relied solely on cache_tree_update()'s internal checking via verify_cache() to prevent duplicate tree entries was bitten by the gap. Add a test that constructs a corrupt index directly (bypassing the D/F checks in add_index_entry) and verifies that write-tree now rejects it. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-12ls-files: filter pathspec before lstatTamir Duberstein1-0/+1
In --deleted and --modified modes, show_files() calls lstat() for each index entry before show_ce() applies the pathspec. prune_index() avoids most of these calls for pathspecs with a common directory prefix, but not for a top-level name or leading wildcard. Match before lstat() to avoid accessing the worktree for entries that cannot be shown. Treat this as a prefilter: do not update ps_matched, and retain the match in show_ce() so --error-unmatch is satisfied only by entries that the selected modes actually show. Prefilter only a single pathspec item, bounding the added work for each index entry. Applying match_pathspec() to multiple arguments can cost more than the lstat() calls it avoids. In a synthetic repository with 10,000 clean files, passing every path to ls-files --modified increased runtime from 112.5 ms to 494.1 ms when the prefilter was unconditional. With $parent and $this exported as paths to binaries built from the parent and this commit, on a repository with 881,290 index entries: hyperfine --warmup 0 --runs 3 \ --command-name parent \ '$parent -c core.fsmonitor=false ls-files --deleted -- README.md >/dev/null' \ --command-name this-commit \ '$this -c core.fsmonitor=false ls-files --deleted -- README.md >/dev/null' reported means of 65.790 seconds for the parent and 4.987 seconds for this commit. Link: https://lore.kernel.org/r/xmqqfr2tnfk0.fsf@gitster.g Helped-by: Jeff King <peff@peff.net> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-09Merge branch 'ua/push-remote-group'Junio C Hamano1-0/+1
"git push" learned to take a "remote group" name to push to, which causes pushes to multiple places, just like "git fetch" would do. * ua/push-remote-group: push: support pushing to a remote group remote: move remote group resolution to remote.c remote: fix sign-compare warnings in push_cas_option
2026-05-27Merge branch 'ps/odb-in-memory'Junio C Hamano1-0/+1
Add a new odb "in-memory" source that is meant to only hold tentative objects (like the virtual blob object that represents the working tree file used by "git blame"). * ps/odb-in-memory: 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
2026-05-27Merge branch 'tb/incremental-midx-part-3.3'Junio C Hamano1-0/+1
The repacking code has been refactored and compaction of MIDX layers have been implemented, and incremental strategy that does not require all-into-one repacking has been introduced. * tb/incremental-midx-part-3.3: repack: allow `--write-midx=incremental` without `--geometric` repack: introduce `--write-midx=incremental` repack: implement incremental MIDX repacking packfile: ensure `close_pack_revindex()` frees in-memory revindex builtin/repack.c: convert `--write-midx` to an `OPT_CALLBACK` repack-geometry: prepare for incremental MIDX repacking repack-midx: extract `repack_fill_midx_stdin_packs()` repack-midx: factor out `repack_prepare_midx_command()` midx: expose `midx_layer_contains_pack()` repack: track the ODB source via existing_packs midx: support custom `--base` for incremental MIDX writes midx: introduce `--no-write-chain-file` for incremental MIDX writes midx: use `strvec` for `keep_hashes` midx: build `keep_hashes` array in order midx: use `strset` for retained MIDX files midx-write: handle noop writes when converting incremental chains
2026-05-21Merge branch 'mm/git-url-parse'Junio C Hamano1-0/+1
The internal URL parsing logic has been made accessible via a new subcommand "git url-parse". * mm/git-url-parse: t9904: add tests for the new url-parse builtin doc: describe the url-parse builtin builtin: create url-parse command urlmatch: define url_parse function url: return URL_SCHEME_UNKNOWN instead of dying url: move scheme detection to URL header/source url: move url_is_local_not_ssh to url.h connect: rename enum protocol to url_scheme
2026-05-20repack: introduce `--write-midx=incremental`Taylor Blau1-0/+1
Expose the incremental MIDX repacking mode (implemented in an earlier commit) via a new --write-midx=incremental option for `git repack`. Add "incremental" as a recognized argument to the --write-midx OPT_CALLBACK, mapping it to REPACK_WRITE_MIDX_INCREMENTAL. When this mode is active and --geometric is in use, set the midx_layer_threshold on the pack geometry so that only packs in sufficiently large tip layers are considered for repacking. Two new configuration options control the compaction behavior: - repack.midxSplitFactor (default: 2): the factor used in the geometric merging condition for MIDX layers. - repack.midxNewLayerThreshold (default: 8): the minimum number of packs in the tip MIDX layer before its packs are considered as candidates for geometric repacking. Add tests exercising the new mode across a variety of scenarios including basic geometric violations, multi-round chain integrity, branching and merging histories, cross-layer object uniqueness, and threshold-based compaction. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-15t/unit-tests: add tests for the in-memory object sourcePatrick Steinhardt1-0/+1
While the in-memory object source is a full-fledged source, our code base only exercises parts of its functionality because we only use it in git-blame(1). Implement unit tests to verify that the yet-unused functionality of the backend works as expected. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-06t9904: add tests for the new url-parse builtinMatheus Afonso Martins Moreira1-0/+1
Test git URL parsing, validation and component extraction on all documented git URL schemes and syntaxes. Add IPv6 host coverage in URL form: ssh://[::1]/path ssh://user@[::1]:1234/path git://[::1]:9418/path http://[2001:db8::1]/path https://[2001:db8::1]/path In URL form the brackets are kept in the host component (RFC 3986 syntax for IPv6 literals). Also exercise the bracketed scp short forms that t5601-clone.sh covers via parse_connect_url: [host]:path [host:port]:path [::1]:repo user@[::1]:repo user@[host:port]:path In scp form, brackets are kept for IPv6 literals (two or more inner colons) and stripped for plain hostnames or host:port pairs. Suggested-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Matheus Afonso Martins Moreira <matheus@matheusmoreira.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-04push: support pushing to a remote groupUsman Akinyemi1-0/+1
`git fetch` accepts a remote group name (configured via `remotes.<name>` in config) and fetches from each member remote. `git push` has no equivalent — it only accepts a single remote name. Teach `git push` to resolve its repository argument through `add_remote_or_group()`, which was made public in the previous patch, so that a user can push to all remotes in a group with: git push <group> When the argument resolves to a single remote, the behaviour is identical to before. When it resolves to a group, each member remote is pushed in sequence. The group push path rebuilds the refspec list (`rs`) from scratch for each member remote so that per-remote push mappings configured via `remote.<name>.push` are resolved correctly against each specific remote. Without this, refspec entries would accumulate across iterations and each subsequent remote would receive a growing list of duplicated entries. Mirror detection (`remote->mirror`) is also evaluated per remote using a copy of the flags, so that a mirror remote in the group cannot set TRANSPORT_PUSH_FORCE on subsequent non-mirror remotes in the same group. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-27builtin/history: introduce "fixup" subcommandPatrick Steinhardt1-0/+1
The newly introduced git-history(1) command provides functionality to easily edit commit history while also rebasing dependent branches. The functionality exposed by this command is still somewhat limited though. One common use case when editing commit history that is not yet covered is fixing up a specific commit. Introduce a new subcommand that allows the user to do exactly that by performing a three-way merge into the target's commit tree, using HEAD's tree as the merge base. The flow is thus essentially: $ echo changes >file $ git add file $ git history fixup HEAD~ Like with the other commands, this will automatically rebase dependent branches, as well. Unlike the other commands though: - The command does not work in a bare repository as it interacts with the index. - The command may run into merge conflicts. If so, the command will simply abort. Especially the second item limits the usefulness of this command a bit. But there are plans to introduce first-class conflicts into Git, which will help use cases like this one. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-01Merge branch 'vp/http-rate-limit-retries'Junio C Hamano1-0/+1
The HTTP transport learned to react to "429 Too Many Requests". * vp/http-rate-limit-retries: http: add support for HTTP 429 rate limit retries strbuf_attach: fix call sites to pass correct alloc strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()
2026-03-25Merge branch 'tb/incremental-midx-part-3.2'Junio C Hamano1-0/+1
Further work on incremental repacking using MIDX/bitmap * tb/incremental-midx-part-3.2: midx: enable reachability bitmaps during MIDX compaction midx: implement MIDX compaction t/helper/test-read-midx.c: plug memory leak when selecting layer midx-write.c: factor fanout layering from `compute_sorted_entries()` midx-write.c: enumerate `pack_int_id` values directly midx-write.c: extract `fill_pack_from_midx()` midx-write.c: introduce `midx_pack_perm()` helper midx: do not require packs to be sorted in lexicographic order midx-write.c: introduce `struct write_midx_opts` midx-write.c: don't use `pack_perm` when assigning `bitmap_pos` t/t5319-multi-pack-index.sh: fix copy-and-paste error in t5319.39 git-multi-pack-index(1): align SYNOPSIS with 'git multi-pack-index -h' git-multi-pack-index(1): remove non-existent incompatibility builtin/multi-pack-index.c: make '--progress' a common option midx: introduce `midx_get_checksum_hex()` midx: rename `get_midx_checksum()` to `midx_get_checksum_hash()` midx: mark `get_midx_checksum()` arguments as const
2026-03-24Merge branch 'yc/histogram-hunk-shift-fix'Junio C Hamano1-0/+1
The final clean-up phase of the diff output could turn the result of histogram diff algorithm suboptimal, which has been corrected. * yc/histogram-hunk-shift-fix: xdiff: re-diff shifted change groups when using histogram algorithm
2026-03-24Merge branch 'ps/history-split'Junio C Hamano1-0/+1
"git history" learned the "split" subcommand. * ps/history-split: builtin/history: implement "split" subcommand builtin/history: split out extended function to create commits cache-tree: allow writing in-memory index as tree add-patch: allow disabling editing of hunks add-patch: add support for in-memory index patching add-patch: remove dependency on "add-interactive" subsystem add-patch: split out `struct interactive_options` add-patch: split out header from "add-interactive.h"
2026-03-23Merge branch 'ng/submodule-default-remote'Junio C Hamano1-0/+1
Instead of hardcoded 'origin', use the configured default remote when fetching from submodules. * ng/submodule-default-remote: submodule: fetch missing objects from default remote
2026-03-19Merge branch 'lc/rebase-trailer'Junio C Hamano1-0/+1
"git rebase" learns "--trailer" command to drive the interpret-trailers machinery. * lc/rebase-trailer: rebase: support --trailer commit, tag: parse --trailer with OPT_STRVEC trailer: append trailers without fork/exec trailer: libify a couple of functions interpret-trailers: refactor create_in_place_tempfile() interpret-trailers: factor trailer rewriting
2026-03-17http: add support for HTTP 429 rate limit retriesVaidas Pilkauskas1-0/+1
Add retry logic for HTTP 429 (Too Many Requests) responses to handle server-side rate limiting gracefully. When Git's HTTP client receives a 429 response, it can now automatically retry the request after an appropriate delay, respecting the server's rate limits. The implementation supports the RFC-compliant Retry-After header in both delay-seconds (integer) and HTTP-date (RFC 2822) formats. If a past date is provided, Git retries immediately without waiting. Retry behavior is controlled by three new configuration options (http.maxRetries, http.retryAfter, and http.maxRetryTime) which are documented in git-config(1). The retry logic implements a fail-fast approach: if any delay (whether from server header or configuration) exceeds maxRetryTime, Git fails immediately with a clear error message rather than capping the delay. This provides better visibility into rate limiting issues. The implementation includes extensive test coverage for basic retry behavior, Retry-After header formats (integer and HTTP-date), configuration combinations, maxRetryTime limits, invalid header handling, environment variable overrides, and edge cases. Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-16Merge branch 'ty/setup-error-tightening'Junio C Hamano1-0/+1
While discovering a ".git" directory, the code treats any stat() failure as a sign that a filesystem entity .git does not exist there, and ignores ".git" that is not a "gitdir" file or a directory. The code has been tightened to notice and report filesystem corruption better. * ty/setup-error-tightening: setup: improve error diagnosis for invalid .git files
2026-03-09Merge branch 'cs/add-skip-submodule-ignore-all'Junio C Hamano1-0/+1
"git add <submodule>" has been taught to honor submodule.<name>.ignore that is set to "all" (and requires "git add -f" to override it). * cs/add-skip-submodule-ignore-all: Documentation: update add --force option + ignore=all config tests: fix existing tests when add an ignore=all submodule tests: t2206-add-submodule-ignored: ignore=all and add --force tests read-cache: submodule add need --force given ignore=all configuration read-cache: update add_files_to_cache take param ignored_too
2026-03-06rebase: support --trailerLi Chen1-0/+1
Add a new --trailer=<trailer> option to git rebase to append trailer lines to each rewritten commit message (merge backend only). Because the apply backend does not provide a commit-message filter, reject --trailer when --apply is in effect and require the merge backend instead. This option implies --force-rebase so that fast-forwarded commits are also rewritten. Validate trailer arguments early to avoid starting an interactive rebase with invalid input. Add integration tests covering error paths and trailer insertion across non-interactive and interactive rebases. Signed-off-by: Li Chen <me@linux.beauty> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-04Merge branch 'lo/repo-leftover-bits'Junio C Hamano1-1/+1
Clean-up the code around "git repo info" command. * lo/repo-leftover-bits: Documentation/git-repo: capitalize format descriptions Documentation/git-repo: replace 'NUL' with '_NUL_' t1901: adjust nul format output instead of expected value t1900: rename t1900-repo to t1900-repo-info repo: rename struct field to repo_info_field repo: replace get_value_fn_for_key by get_repo_info_field repo: rename repo_info_fields to repo_info_field CodingGuidelines: instruct to name arrays in singular
2026-03-04Merge branch 'kn/ref-location'Junio C Hamano1-0/+1
Allow the directory in which reference backends store their data to be specified. * kn/ref-location: refs: add GIT_REFERENCE_BACKEND to specify reference backend refs: allow reference location in refstorage config refs: receive and use the reference storage payload refs: move out stub modification to generic layer refs: extract out `refs_create_refdir_stubs()` setup: don't modify repo in `create_reference_database()`
2026-03-04setup: improve error diagnosis for invalid .git filesTian Yuchen1-0/+1
'read_gitfile_gently()' treats any non-regular file as 'READ_GITFILE_ERR_NOT_A_FILE' and fails to discern between 'ENOENT' and other stat failures. This flawed error reporting is noted by two 'NEEDSWORK' comments. Address these comments by introducing two new error codes: 'READ_GITFILE_ERR_MISSING'(which groups the "file missing" scenarios together) and 'READ_GITFILE_ERR_IS_A_DIR': 1. Update 'read_gitfile_error_die()' to treat 'IS_A_DIR', 'MISSING', 'NOT_A_FILE' and 'STAT_FAILED' as non-fatal no-ops. This accommodates intentional non-repo scenarios (e.g., GIT_DIR=/dev/null). 2. Explicitly catch 'NOT_A_FILE' and 'STAT_FAILED' during discovery and call 'die()' if 'die_on_error' is set. 3. Unconditionally pass '&error_code' to 'read_gitfile_gently()'. 4. Only invoke 'is_git_directory()' when we explicitly receive 'READ_GITFILE_ERR_IS_A_DIR', avoiding redundant checks. Additionally, audit external callers of 'read_gitfile_gently()' in 'submodule.c' and 'worktree.c' to accommodate the refined error codes. Signed-off-by: Tian Yuchen <a3205153416@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-03submodule: fetch missing objects from default remoteNasser Grainawi1-0/+1
When be76c21282 (fetch: ensure submodule objects fetched, 2018-12-06) added support for fetching a missing submodule object by id, it hardcoded the remote name as "origin" and deferred anything more complicated for a later patch. Implement the NEEDSWORK item to remove the hardcoded assumption by adding and using a submodule helper subcmd 'get-default-remote'. Fixing this lets 'git fetch --recurse-submodules' succeed when the fetched commit(s) in the superproject trigger a submodule fetch, and that submodule's default remote name is not "origin". Add non-"origin" remote tests to t5526-fetch-submodules.sh and t5572-pull-submodule.sh demonstrating this works as expected and add dedicated tests for get-default-remote. Signed-off-by: Nasser Grainawi <nasser.grainawi@oss.qualcomm.com> Reviewed-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-03builtin/history: implement "split" subcommandPatrick Steinhardt1-0/+1
It is quite a common use case that one wants to split up one commit into multiple commits by moving parts of the changes of the original commit out into a separate commit. This is quite an involved operation though: 1. Identify the commit in question that is to be dropped. 2. Perform an interactive rebase on top of that commit's parent. 3. Modify the instruction sheet to "edit" the commit that is to be split up. 4. Drop the commit via "git reset HEAD~". 5. Stage changes that should go into the first commit and commit it. 6. Stage changes that should go into the second commit and commit it. 7. Finalize the rebase. This is quite complex, and overall I would claim that most people who are not experts in Git would struggle with this flow. Introduce a new "split" subcommand for git-history(1) to make this way easier. All the user needs to do is to say `git history split $COMMIT`. From hereon, Git asks the user which parts of the commit shall be moved out into a separate commit and, once done, asks the user for the commit message. Git then creates that split-out commit and applies the original commit on top of it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-03xdiff: re-diff shifted change groups when using histogram algorithmYee Cheng Chin1-0/+1
After a diff algorithm has been run, the compaction phase (xdl_change_compact()) shifts and merges change groups to produce a cleaner output. However, this shifting could create a new matched group where both sides now have matching lines. This results in a wrong-looking diff output which contains redundant lines that are the same on both files. Fix this by detecting this situation, and re-diff the texts on each side to find similar lines, using the fall-back Myer's diff. Only do this for histogram diff as it's the only algorithm where this is relevant. Below contains an example, and more details. For an example, consider two files below: file1: A A A A A A A file2: A A x A A A A When using Myer's diff, the algorithm finds that only the "x" has been changed, and produces a final diff result (these are line diffs, but using word-diff syntax for ease of presentation): A A[-A-]{+x+}A AAA When using histogram diff, the algorithm first discovers the LCS "A AAA", which it uses as anchor, then produces an intermediate diff: {+A Ax+}A AAA[- AAA-]. This is a longer diff than Myer's, but it's still self-consistent. However, the compaction phase attempts to shift the first file's diff group upwards (note that this shift crosses the anchor that histogram had used), leading to the final results for histogram diff: [-A AA-]{+A Ax+}A AAA This is a technically correct patch but looks clearly redundant to a human as the first 3 lines should not be in the diff. The fix would detect that a shift has caused matching to a new group, and re-diff the "A AA" and "A Ax" parts, which results in "A A" correctly re-marked as unchanged. This creates the now correct histogram diff: A A[-A-]{+x+}A AAA This issue is not applicable to Myer's diff algorithm as it already generates a minimal diff, which means a shift cannot result in a smaller diff output (the default Myer's diff in xdiff is not guaranteed to be minimal for performance reasons, but it typically does a good enough job). It's also not applicable to patience diff, because it uses only unique lines as anchor for its splits, and falls back to Myer's diff within each split. Shifting requires both ends having the same lines, and therefore cannot cross the unique line boundaries established by the patience algorithm. In contrast histogram diff uses non-unique lines as anchors, and therefore shifting can cross over them. This issue is rare in a normal repository. Below is a table of repositories (`git log --no-merges -p --histogram -1000`), showing how many times a re-diff was done and how many times it resulted in finding matching lines (therefore addressing this issue) with the fix. In general it is fewer than 1% of diff's that exhibit this offending behavior: | Repo (1k commits) | Re-diff | Found matching lines | |--------------------|---------|----------------------| | llvm-project | 45 | 11 | | vim | 110 | 9 | | git | 18 | 2 | | WebKit | 168 | 1 | | ripgrep | 22 | 1 | | cpython | 32 | 0 | | vscode | 13 | 0 | Signed-off-by: Yee Cheng Chin <ychin.git@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-27Merge branch 'ps/ci-gitlab-msvc-updates'Junio C Hamano1-0/+1
CI update. * ps/ci-gitlab-msvc-updates: gitlab-ci: handle failed tests on MSVC+Meson job gitlab-ci: use "run-test-slice-meson.sh" ci: make test slicing consistent across Meson/Make github: fix Meson tests not executing at all meson: fix MERGE_TOOL_DIR with "--no-bin-wrappers" ci: don't skip smallest test slice in GitLab ci: handle failures of test-slice helper
2026-02-25Merge branch 'mc/tr2-process-ancestry-cleanup'Junio C Hamano1-0/+1
Add process ancestry data to trace2 on macOS to match what we already do on Linux and Windows. Also adjust the way Windows implementation reports this information to match the other two. * mc/tr2-process-ancestry-cleanup: t0213: add trace2 cmd_ancestry tests test-tool: extend trace2 helper with 400ancestry trace2: emit cmd_ancestry data for Windows trace2: refactor Windows process ancestry trace2 event build: include procinfo.c impl for macOS trace2: add macOS process ancestry tracing
2026-02-25Merge branch 'cc/lop-filter-auto'Junio C Hamano1-0/+1
"auto filter" logic for large-object promisor remote. * cc/lop-filter-auto: fetch-pack: wire up and enable auto filter logic promisor-remote: change promisor_remote_reply()'s signature promisor-remote: keep advertised filters in memory list-objects-filter-options: support 'auto' mode for --filter doc: fetch: document `--filter=<filter-spec>` option fetch: make filter_options local to cmd_fetch() clone: make filter_options local to cmd_clone() promisor-remote: allow a client to store fields promisor-remote: refactor initialising field lists