summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2025-10-24builtin/maintenance: improve readability of strategiesPatrick Steinhardt
Our maintenance strategies are essentially a large array of structures, where each of the tasks can be enabled and scheduled individually. With the current layout though all the configuration sits on the same nesting layer, which makes it a bit hard to discern which initialized fields belong to what task. Improve readability of the individual tasks by using nested designated initializers instead. Suggested-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24builtin/maintenance: don't silently ignore invalid strategyPatrick Steinhardt
When parsing maintenance strategies we completely ignore the user-configured value in case it is unknown to us. This makes it basically undiscoverable to the user that scheduled maintenance is devolving into a no-op. Change this to instead die when seeing an unknown maintenance strategy. While at it, pull out the parsing logic into a separate function so that we can reuse it in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24builtin/maintenance: make the geometric factor configurablePatrick Steinhardt
The geometric repacking task uses a factor of two for its geometric sequence, meaning that each next pack must contain at least twice as many objects as the next-smaller one. In some cases it may be helpful to configure this factor though to reduce the number of packfile merges even further, e.g. in very big repositories. But while git-repack(1) itself supports doing this, the maintenance task does not give us a way to tune it. Introduce a new "maintenance.geometric-repack.splitFactor" configuration to plug this gap. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24builtin/maintenance: introduce "geometric-repack" taskPatrick Steinhardt
Introduce a new "geometric-repack" task. This task uses our geometric repack infrastructure as provided by git-repack(1) itself, which is a strategy that especially hosting providers tend to use to amortize the costs of repacking objects. There is one issue though with geometric repacks, namely that they unconditionally pack all loose objects, regardless of whether or not they are reachable. This is done because it means that we can completely skip the reachability step, which significantly speeds up the operation. But it has the big downside that we are unable to expire objects over time. To address this issue we thus use a split strategy in this new task: whenever a geometric repack would merge together all packs, we instead do an all-into-one repack. By default, these all-into-one repacks have cruft packs enabled, so unreachable objects would now be written into their own pack. Consequently, they won't be soaked up during geometric repacking anymore and can be expired with the next full repack, assuming that their expiry date has surpassed. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24builtin/gc: make `too_many_loose_objects()` reusable without GC configPatrick Steinhardt
To decide whether or not a repository needs to be repacked we estimate the number of loose objects. If the number exceeds a certain threshold we perform the repack, otherwise we don't. This is done via `too_many_loose_objects()`, which takes as parameter the `struct gc_config`. This configuration is only used to determine the threshold. In a subsequent commit we'll add another caller of this function that wants to pass a different limit than the one stored in that structure. Refactor the function accordingly so that we only take the limit as parameter instead of the whole structure. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24builtin/gc: remove global `repack` variablePatrick Steinhardt
The global `repack` variable is used to store all command line arguments that we eventually want to pass to git-repack(1). It is being appended to from multiple different functions, which makes it hard to follow the logic. Besides being hard to follow, it also makes it unnecessarily hard to reuse this infrastructure in new code. Refactor the code so that we store this variable on the stack and pass a pointer to it around as needed. This is done so that we can reuse `add_repack_all_options()` in a subsequent commit. The refactoring itself is straight-forward. One function that deserves attention though is `need_to_gc()`: this function determines whether or not we need to execute garbage collection for `git gc --auto`, but also for `git maintenance run --auto`. But besides figuring out whether we have to perform GC, the function also sets up the `repack` arguments. For `git gc --auto` it's trivial to adapt, as we already have the on-stack variable at our fingertips. But for the maintenance condition it's less obvious what to do. As it turns out, we can just use another temporary variable there that we then immediately discard. If we need to perform GC we execute a child git-gc(1) process to repack objects for us, and that process will have to recompute the arguments anyway. Signed-off-by: Patrick Steinhardt <ps@pks.im> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24diff: simplify run_external_diff() quiet logicJeff King
We'd sometimes end up in run_external_diff() to do a dry-run diff (e.g., to find content-level changes for --quiet). We recognize this quiet mode by seeing the lack of DIFF_FORMAT_PATCH in the output format. But since introducing an explicit dry-run check via 3ed5d8bd73 (diff: stop output garbled message in dry run mode, 2025-10-20), this logic can never trigger. We can only get to this function by calling diff_flush_patch(), and that comes from only two places: 1. A dry-run flush comes from diff_flush_patch_quietly(), which is always in dry-run mode (so the other half of our "||" is true anyway). 2. A regular flush comes from diff_flush_patch_all_file_pairs(), which is only called when output_format has DIFF_FORMAT_PATCH in it. So we can simplify our "quiet" condition to just checking dry-run mode (which used to be a specific flag, but recently became just a NULL "file" pointer). And since it's so simple, we can just do that inline. This makes the logic about o->file more obvious, since we handle the NULL and non-stdout cases next to each other. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24diff: drop dry-run redirection to /dev/nullJeff King
As an added protection against dry-run diffs accidentally producing output, we redirect diff_options.file to /dev/null. But as of the previous patch, this now does nothing, since dry-run diffs are implemented by setting "file" to NULL. So we can drop this extra code with no change in behavior. This is effectively a revert of 623f7af284 (diff: restore redirection to /dev/null for diff_from_contents, 2025-10-17) and 3da4413dbc (diff: make sure the other caller of diff_flush_patch_quietly() is silent, 2025-10-22), but: 1. We get a conflict because we already dropped the color_moved handling in an earlier patch. But we just resolve the conflicts to "theirs" (removing all of the code). 2. We retain the test from 623f7af284. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24diff: replace diff_options.dry_run flag with NULL fileJeff King
We introduced a dry_run flag to diff_options in b55e6d36eb (diff: ensure consistent diff behavior with ignore options, 2025-08-08), with the idea that the lower-level diff code could skip output when it is set. As we saw with the bugs fixed by 3ed5d8bd73 (diff: stop output garbled message in dry run mode, 2025-10-20), it is easy to miss spots. In the end, we located all of them by checking where diff_options.file is used. That suggests another possible approach: we can replace the dry_run boolean with a NULL pointer for "file", as we know that using "file" in dry_run mode would always be an error. This turns any missed spots from producing extra output[1] into a segfault. Which is less forgiving, but that is the point: this is indicative of a programming error, and complaining loudly and immediately is good. [1] We protect ourselves against garbled output as a separate step, courtesy of 623f7af284 (diff: restore redirection to /dev/null for diff_from_contents, 2025-10-17). So in that sense this patch can only introduce user-visible errors (since any "bugs" were going to /dev/null before), but the idea is to catch them rather than quietly send garbage to /dev/null. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24diff: drop save/restore of color_moved in dry-run modeJeff King
When running a dry-run content-level diff to check whether a "--quiet" diff has any changes, we have always unset the color_moved variable since the feature was added in 2e2d5ac184 (diff.c: color moved lines differently, 2017-06-30). The reasoning is not given explicitly there, but presumably the idea is that since color_moved requires a lot of extra computation to match lines but does not actually affect the found_changes flag, we want to skip it. Later, in 3da4413dbc (diff: make sure the other caller of diff_flush_patch_quietly() is silent, 2025-10-22) we copied the same idea for other dry-run diffs. But neither spot actually needs to reset this flag at all, because diff_flush_patch() will not ever compute color_moved. Nor could it, as it is only looking at a single file-pair, and we detect moves across files. So color_moved is checked only when we are actually doing real DIFF_FORMAT_PATCH output, and call diff_flush_patch_all_file_pairs(). So we can get rid of these extra lines to save and restore the color_moved flag without changing the behavior at all. (Note that there is no "restore" to drop for the second caller, as we know at that point we are not generating any output and can just leave the feature disabled). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24diff: send external diff output to diff_options.fileJeff King
Diff output usually goes to the process stdout, but it can be redirected with the "--output" option. We store this in the "file" pointer of diff_options, and all of the diff code should write there instead of to stdout. But there's one spot we missed: running an external diff cmd. We don't redirect its output at all, so it just defaults to the stdout of the parent process. We should instead point its stdout at our output file. There are a few caveats to watch out for when doing so: - The stdout field takes a descriptor, not a FILE pointer. We can pull out the descriptor with fileno(). - The run-command API always closes the stdout descriptor we pass to it. So we must duplicate it (otherwise we break the FILE pointer, since it now points to a closed descriptor). - We don't need to worry about closing our dup'd descriptor, since the point is that run-command will do it for us (even in the case of an error). But we do need to make sure we skip the dup() if we set no_stdout (because then run-command will not look at it at all). - When the output is going to stdout, it would not be wrong to dup() the descriptor, but we don't need to. We can skip that extra work with a simple pointer comparison. - It seems like you'd need to fflush() the descriptor before handing off a copy to the child process to prevent out-of-order writes. But that was true even before this patch! It works because run-command always calls fflush(NULL) before running the child. The new test shows the breakage (and fix). The need for duplicating the descriptor doesn't need a new test; that is covered by the later test "GIT_EXTERNAL_DIFF with more than one changed files". Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24Merge branch 'ly/diff-name-only-with-diff-from-content' into ↵Junio C Hamano
jk/diff-patch-dry-run-cleanup * ly/diff-name-only-with-diff-from-content: diff: stop output garbled message in dry run mode
2025-10-24commit-reach: avoid commit_list_insert_by_date()René Scharfe
Building a list using commit_list_insert_by_date() has quadratic worst case complexity. Avoid it by just appending in the loop and sorting at the end. The number of merge bases is usually small, so don't expect speedups in normal repositories. It has no limit, though. The added perf test shows a nice improvement when dealing with 16384 merge bases: Test v2.51.1 HEAD ----------------------------------------------------------------- 6010.2: git merge-base 0.55(0.54+0.00) 0.03(0.02+0.00) -94.5% Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24The twenty-third batchJunio C Hamano
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-24Merge branch 'jc/diff-from-contents-fix'Junio C Hamano
The code to squelch output from "git diff -w --name-status" etc. for paths that "git diff -w -p" would have stayed silent leaked output from dry-run patch generation, which has been corrected. * jc/diff-from-contents-fix: diff: make sure the other caller of diff_flush_patch_quietly() is silent
2025-10-24Merge branch 'jk/diff-from-contents-fix'Junio C Hamano
Recently we attempted to improve "git diff -w" and friends to handle cases where patch output would be suppressed, but it introduced a bug that emits unnecessary output, which has been corrected. * jk/diff-from-contents-fix: diff: restore redirection to /dev/null for diff_from_contents
2025-10-23t7528: work around ETOOMANY in OpenSSH 10.1 and newerPatrick Steinhardt
In t7528 we spawn an SSH agent to verify that we can sign a commit via it. This test has started to fail on some machines: +++ ssh-agent unix_listener_tmp: path "/home/pks/Development/git/build/test-output/trash directory.t7528-signed-commit-ssh/.ssh/agent/s.UTulegefEg.agent.UrPHumMXPq" too long for Unix domain socket main: Couldn't prepare agent socket As it turns out this is caused by a change in OpenSSH 10.1 [1]: * ssh-agent(1), sshd(8): move agent listener sockets from /tmp to under ~/.ssh/agent for both ssh-agent(1) and forwarded sockets in sshd(8). Instead of creating the socket in "/tmp", OpenSSH now creates the socket in our home directory. And as the home directory gets modified to be located in our test output directory we end up with paths that are somewhat long. But Linux has a rather short limit of 108 characters for socket paths, and other systems have even lower limits, so it is very easy now to exceed the limit and run into the above error. Work around the issue by using `ssh-agent -T`, which instructs it to use the old behaviour and create the socket in "/tmp" again. This switch has only been introduced with 10.1 though, so for older versions we have to fall back to not using it. That's fine though, as older versions know to put the socket into "/tmp" already. An alternative approach would be to abbreviate the socket name itself so that we create it as e.g. "sshsock" in the trash directory. But taking the above example we'd still end up with a path that is 91 characters long. So we wouldn't really have a lot of headroom, and it is quite likely that some developers would see the issue on their machines. [1]: https://www.openssh.com/txt/release-10.1 Reported-by: Xi Ruoyao <xry111@xry111.site> Suggested-by: brian m. carlson <sandals@crustytoothpaste.net> Helped-by: Jeff King <peff@peff.net> Helped-by: Lauri Tirkkonen <lauri@hacktheplanet.fi> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-23gpg-interface: do not use misdesigned strbuf_split*()Olamide Caleb Bello
In get_default_ssh_signing_key(), the default ssh signing key is retrieved in `key_stdout` buf, which is then split using strbuf_split_max() into up to two strbufs at a new line and the first strbuf is returned as a `char *`and not a strbuf. This makes the function lack the use of strbuf API as no edits are performed on the split tokens. Simplify the process of retrieving and returning the desired line by using strchr() to isolate the line and xmemdupz() to return a copy of the line. This removes the roundabout way of splitting the string into strbufs, just to return the line. Reported-by: Junio Hamano <gitster@pobox.com> Helped-by: Christian Couder <christian.couder@gmail.com> Helped-by: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-23gpg-interface: do not use misdesigned strbuf_split*()Olamide Caleb Bello
In get_ssh_finger_print(), the output of the `ssh-keygen` command is put into `fingerprint_stdout` strbuf. The string in `fingerprint_stdout` is then split into up to 3 strbufs using strbuf_split_max(). However they are not modified after the split thereby not making use of the strbuf API as the fingerprint token is merely returned as a char * and not a strbuf. Hence they do not need to be strbufs. Simplify the process of retrieving and returning the desired token by using strchr() to isolate the token and xmemdupz() to return a copy of the token. This removes the roundabout way of splitting the string into strbufs just to return the token. Reported-by: Junio Hamano <gitster@pobox.com> Helped-by: Christian Couder <christian.couder@gmail.com> Helped-by: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com> Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-23diff: stop output garbled message in dry run modeLidong Yan
Earlier, b55e6d36 (diff: ensure consistent diff behavior with ignore options, 2025-08-08) introduced "dry-run" mode to the diff machinery so that content-based diff filtering (like ignoring space changes or those that match -I<regex>) can first try to produce a patch without emitting any output to see if under the given diff filtering condition we would get any output lines, and a new helper function diff_flush_patch_quietly() was introduced to use the mode to see an individual filepair needs to be shown. However, the solution was not complete. When files are deleted, file modes change, or there are unmerged entries in the index, dry-run mode still produces output because we overlooked these conditions, and as a result, dry-run mode was not quiet. To fix this, return early in emit_diff_symbol_from_struct() if we are in dry-run mode. This function will be called by all the emit functions to output the results. Returning early can avoid diff output when files are deleted or file modes are changed. Stop print message in dry-run mode if we have unmerged entries in index. Discard output of external diff tool in dry-run mode. Signed-off-by: Lidong Yan <yldhome2d2@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-23Merge branch 'jc/diff-from-contents-fix' into ↵Junio C Hamano
ly/diff-name-only-with-diff-from-content * jc/diff-from-contents-fix: diff: make sure the other caller of diff_flush_patch_quietly() is silent
2025-10-23diff: make sure the other caller of diff_flush_patch_quietly() is silentJunio C Hamano
Earlier, we added is a protection for the loop that computes "git diff --quiet -w" to ensure calls to the diff_flush_patch_quietly() helper stays quiet. Do the same for another loop that deals with options like "--name-status" to make calls to the same helper. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-22Merge branch 'jk/diff-from-contents-fix' into ↵Junio C Hamano
ly/diff-name-only-with-diff-from-content * jk/diff-from-contents-fix: diff: restore redirection to /dev/null for diff_from_contents
2025-10-22The twenty-second batchJunio C Hamano
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-22Merge branch 'so/t2401-use-test-path-helpers'Junio C Hamano
Test modernization. * so/t2401-use-test-path-helpers: t2401: update path checks using test_path helpers
2025-10-22Merge branch 'je/doc-pull'Junio C Hamano
Documentation updates. * je/doc-pull: doc: git-pull: clarify how to exit a conflicted merge doc: git-pull: delete the example doc: git-pull: clarify options for integrating remote branch doc: git-pull: move <repository> and <refspec> params
2025-10-22Merge branch 'bc/sha1-256-interop-01'Junio C Hamano
The beginning of SHA1-SHA256 interoperability work. * bc/sha1-256-interop-01: t1010: use BROKEN_OBJECTS prerequisite t: allow specifying compatibility hash fsck: consider gpgsig headers expected in tags rev-parse: allow printing compatibility hash docs: add documentation for loose objects docs: improve ambiguous areas of pack format documentation docs: reflect actual double signature for tags docs: update offset order for pack index v3 docs: update pack index v3 format
2025-10-22Merge branch 'js/ci-github-actions-update'Junio C Hamano
CI update. * js/ci-github-actions-update: build(deps): bump actions/github-script from 7 to 8 build(deps): bump actions/setup-python from 5 to 6 build(deps): bump actions/checkout from 4 to 5 build(deps): bump actions/download-artifact from 4 to 5
2025-10-22bisect: fix handling of `help` and invalid subcommandsRuoyu Zhong
As documented in git-bisect(1), `git bisect help` should display usage information. However, since the migration of `git bisect` to a full builtin command in 73fce29427 (Turn `git bisect` into a full built-in, 2022-11-10), this behavior was broken. Running `git bisect help` would, instead of showing usage, either fail silently if already in a bisect session, or otherwise trigger an interactive autostart prompt asking "Do you want me to do it for you [Y/n]?". Similarly, since df63421be9 (bisect--helper: handle states directly, 2022-11-10), running invalid subcommands like `git bisect foobar` also led to the same behavior. This occurred because `help` and other unrecognized subcommands were being unconditionally passed to `bisect_state`, which then called `bisect_autostart`, triggering the interactive prompt. Fix this by: 1. Adding explicit handling for the `help` subcommand to show usage; 2. Validating that unrecognized commands are actually valid state commands before calling `bisect_state`; 3. Showing an error with usage for truly invalid commands. This ensures that `git bisect help` displays the usage as documented, and invalid commands fail cleanly without entering interactive mode. Alternate terms are still handled correctly through `check_and_set_terms`. Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-22commit-graph: add new config for changed-paths & recommend it in scalarEmily Yang
The changed-path Bloom filters feature has proven stable and reliable over several years of use, delivering significant performance improvement for file history computation in large monorepos. Currently a user can opt-in to writing the changed-path Bloom filters using the "--changed-paths" option to "git commit-graph write". The filters will be persisted until the user drops the filters using the "--no-changed-paths" option. For this functionality, refer to 0087a87ba8 (commit-graph: persist existence of changed-paths, 2020-07-01). Large monorepos using Git's background maintenance to build and update commit-graph files could use an easy switch to enable this feature without a foreground computation. In this commit, we're proposing a new config option "commitGraph.changedPaths": * If "true", "git commit-graph write" will write Bloom filters, equivalent to passing "--changed-paths"; * If "false" or "unset", Bloom filters will be written during "git commit-graph write" only if the filters already exist in the current commit-graph file. This matches the default behaviour of "git commit-graph write" without any "--[no-]changed-paths" option. Note "false" can disable a previous "true" config value but doesn't imply "--no-changed-paths". This config will always respect the precedence of command line option "--[no-]changed-paths". We also set this new config as optional recommended config in scalar to turn on this feature for large repos. Helped-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Emily Yang <emilyyang.git@gmail.com> Acked-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-22Merge branch 'jt/repo-structure' into ps/ref-peeled-tagsJunio C Hamano
* jt/repo-structure: builtin/repo: add progress meter for structure stats builtin/repo: add keyvalue and nul format for structure stats builtin/repo: add object counts in structure output builtin/repo: introduce structure subcommand ref-filter: export ref_kind_from_refname() ref-filter: allow NULL filter pattern builtin/repo: rename repo_info() to cmd_repo_info()
2025-10-22Merge branch 'tb/incremental-midx-part-3.1' into ps/ref-peeled-tagsJunio C Hamano
* tb/incremental-midx-part-3.1: (49 commits) builtin/repack.c: clean up unused `#include`s repack: move `write_cruft_pack()` out of the builtin repack: move `write_filtered_pack()` out of the builtin repack: move `pack_kept_objects` to `struct pack_objects_args` repack: move `finish_pack_objects_cmd()` out of the builtin builtin/repack.c: pass `write_pack_opts` to `finish_pack_objects_cmd()` repack: extract `write_pack_opts_is_local()` repack: move `find_pack_prefix()` out of the builtin builtin/repack.c: use `write_pack_opts` within `write_cruft_pack()` builtin/repack.c: introduce `struct write_pack_opts` repack: 'write_midx_included_packs' API from the builtin builtin/repack.c: inline packs within `write_midx_included_packs()` builtin/repack.c: pass `repack_write_midx_opts` to `midx_included_packs` builtin/repack.c: inline `remove_redundant_bitmaps()` builtin/repack.c: reorder `remove_redundant_bitmaps()` repack: keep track of MIDX pack names using existing_packs builtin/repack.c: use a string_list for 'midx_pack_names' builtin/repack.c: extract opts struct for 'write_midx_included_packs()' builtin/repack.c: remove ref snapshotting from builtin repack: remove pack_geometry API from the builtin ...
2025-10-21builtin/repo: add progress meter for structure statsJustin Tobler
When using the structure subcommand for git-repo(1), evaluating a repository may take some time depending on its shape. Add a progress meter to provide feedback to the user about what is happening. The progress meter is enabled by default when the command is executed from a tty. It can also be explicitly enabled/disabled via the --[no-]progress option. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21builtin/repo: add keyvalue and nul format for structure statsJustin Tobler
All repository structure stats are outputted in a human-friendly table form. This format is not suitable for machine parsing. Add a --format option that supports three output modes: `table`, `keyvalue`, and `nul`. The `table` mode is the default format and prints the same table output as before. With the `keyvalue` mode, each line of output contains a key-value pair of a repository stat. The '=' character is used to delimit between keys and values. The `nul` mode is similar to `keyvalue`, but key-values are delimited by a NUL character instead of a newline. Also, instead of a '=' character to delimit between keys and values, a newline character is used. This allows stat values to support special characters without having to cquote them. These two new modes provides output that is more machine-friendly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21builtin/repo: add object counts in structure outputJustin Tobler
The amount of objects in a repository can provide insight regarding its shape. To surface this information, use the path-walk API to count the number of reachable objects in the repository by object type. All regular references are used to determine the reachable set of objects. The object counts are appended to the same table containing the reference information. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21builtin/repo: introduce structure subcommandJustin Tobler
The structure of a repository's history can have huge impacts on the performance and health of the repository itself. Currently, Git lacks a means to surface repository metrics regarding its structure/shape via a single command. Acquiring this information requires users to be familiar with the relevant data points and the various Git commands required to surface them. To fill this gap, supplemental tools such as git-sizer(1) have been developed. To allow users to more readily identify repository structure related information, introduce the "structure" subcommand in git-repo(1). The goal of this subcommand is to eventually provide similar functionality to git-sizer(1), but natively in Git. The initial version of this command only iterates through all references in the repository and tracks the count of branches, tags, remote refs, and other reference types. The corresponding information is displayed in a human-friendly table formatted in a very similar manner to git-sizer(1). The width of each table column is adjusted automatically to satisfy the requirements of the widest row contained. Subsequent commits will surface additional relevant data points to output and also provide other more machine-friendly output formats. Based-on-patch-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21ref-filter: export ref_kind_from_refname()Justin Tobler
When filtering refs, `ref_kind_from_refname()` is used to determine the ref type. In a subsequent commit, this same logic is reused when counting refs by type. Export the function to prepare for this change. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21ref-filter: allow NULL filter patternJustin Tobler
When setting up `struct ref_filter` for filter_refs(), the `name_patterns` field must point to an array of pattern strings even if no patterns are required. To improve this interface, treat a NULL `name_patterns` field the same as when it points to an empty array. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21builtin/repo: rename repo_info() to cmd_repo_info()Justin Tobler
Subcommand functions are often prefixed with `cmd_` to denote that they are an entrypoint. Rename repo_info() to cmd_repo_info() accordingly. Signed-off-by: Justin Tobler <jltobler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21add-patch: fully document option PRené Scharfe
Show option P in the prompt and explain it properly on a dedicated line in online help and documentation. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-21Merge branch 'tb/incremental-midx-part-3.1' into ps/maintenance-geometricJunio C Hamano
* tb/incremental-midx-part-3.1: (64 commits) builtin/repack.c: clean up unused `#include`s repack: move `write_cruft_pack()` out of the builtin repack: move `write_filtered_pack()` out of the builtin repack: move `pack_kept_objects` to `struct pack_objects_args` repack: move `finish_pack_objects_cmd()` out of the builtin builtin/repack.c: pass `write_pack_opts` to `finish_pack_objects_cmd()` repack: extract `write_pack_opts_is_local()` repack: move `find_pack_prefix()` out of the builtin builtin/repack.c: use `write_pack_opts` within `write_cruft_pack()` builtin/repack.c: introduce `struct write_pack_opts` repack: 'write_midx_included_packs' API from the builtin builtin/repack.c: inline packs within `write_midx_included_packs()` builtin/repack.c: pass `repack_write_midx_opts` to `midx_included_packs` builtin/repack.c: inline `remove_redundant_bitmaps()` builtin/repack.c: reorder `remove_redundant_bitmaps()` repack: keep track of MIDX pack names using existing_packs builtin/repack.c: use a string_list for 'midx_pack_names' builtin/repack.c: extract opts struct for 'write_midx_included_packs()' builtin/repack.c: remove ref snapshotting from builtin repack: remove pack_geometry API from the builtin ...
2025-10-21unicode: update the width tables to Unicode 17Torsten Bögershausen
Unicode 17 is out. Update the unicode with table. https://blog.unicode.org/2025/09/unicode-170-release-announcement.html Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-20The twenty-first batchJunio C Hamano
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-20Merge branch 'tb/cat-file-objectmode-update'Junio C Hamano
Code clean-up. * tb/cat-file-objectmode-update: builtin/cat-file.c: simplify calling `report_object_status()`
2025-10-20Merge branch 'kh/doc-continued-paragraph-fix'Junio C Hamano
Doc mark-up fixes. * kh/doc-continued-paragraph-fix: doc: fix accidental literal blocks
2025-10-20Merge branch 'js/unreachable-workaround-for-no-symlink-head'Junio C Hamano
Code clean-up. * js/unreachable-workaround-for-no-symlink-head: refs: forbid clang to complain about unreachable code
2025-10-20Merge branch 'js/mingw-includes-cleanup'Junio C Hamano
Code clean-up. * js/mingw-includes-cleanup: mingw: order `#include`s alphabetically mingw: avoid relative `#include`s
2025-10-20Merge branch 'dk/stash-apply-index'Junio C Hamano
Doc update. * dk/stash-apply-index: doc: explain the impact of stash.index on --autostash options
2025-10-20contrib/credential: harmonize MakefilesThomas Uhle
Update these Makefiles to be in line with other Makefiles from contrib such as for contacts or subtree by making the following changes: * Make the default settings after including config.mak.autogen and config.mak. * Add the missing $(CPPFLAGS) to the compiler command as well as the missing $(CFLAGS) to the linker command. * Use a pattern rule for compilation instead of a dedicated rule for each compile unit. * Get rid of $(MAIN), $(SRCS) and $(OBJS) and simply use their values such as git-credential-libsecret and git-credential-libsecret.o. * Strip @ from $(RM) to let the clean target rule be verbose. * Define .PHONY for all special targets (all, clean). Signed-off-by: Thomas Uhle <thomas.uhle@mailbox.tu-dresden.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-10-20completion: complete some 'git log' optionsKIYOTA Fumiya
1. '--exclude=' option to 'git log' and 'git shortlog' are missing. Add the option to __git_log_shortlog_options. 2. The `--committer` option in `git log` requires a pattern, such as `--committer=ba`, but in `git shortlog`, specifying a pattern results in an error: “error: option `committer' takes no value.” Handle them as separate options for completion rather than a shared one. Signed-off-by: KIYOTA Fumiya <aimluck.kiyota@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>