git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3] range-diff: add configurable memory limit for cost matrix

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 29, 2025, 15:40 UTC
Message-ID
<xmqqecsup25j.fsf@gitster.g>
In-Reply-To
<pull.1958.v3.git.1756465231183.gitgitgadget@gmail.com>
"Paulo Casaretto via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 41 quoted lines
> From: Paulo Casaretto <pcasaretto@gmail.com>
>
> When comparing large commit ranges (e.g., 250,000+ commits), range-diff
> attempts to allocate an n×n cost matrix that can exhaust available
> memory. For example, with 256,784 commits (n = 513,568), the matrix
> would require approximately 256GB of memory (513,568² × 4 bytes),
> causing either immediate segmentation faults due to integer overflow or
> system hangs.
>
> Add a memory limit check in get_correspondences() before allocating the
> cost matrix. This check uses the total size in bytes (n² × sizeof(int))
> and compares it against a configurable maximum, preventing both
> excessive memory usage and integer overflow issues.
>
> The limit is configurable via a new --max-memory option that accepts
> human-readable sizes (e.g., "1G", "500M"). The default is 4GB for 64 bit
> systems and 2GB for 32 bit systems. This allows comparing ranges of
> approximately 32,000 (16,000) commits - generous for real-world use cases
> while preventing impractical operations.
>
> When the limit is exceeded, range-diff now displays a clear error
> message showing both the requested memory size and the maximum allowed,
> formatted in human-readable units for better user experience.
>
> Example usage:
>   git range-diff --max-memory=1G branch1...branch2
>   git range-diff --max-memory=500M base..topic1 base..topic2
>
> This approach was chosen over alternatives:
> - Pre-counting commits: Would require spawning additional git processes
>   and reading all commits twice
> - Limiting by commit count: Less precise than actual memory usage
> - Streaming approach: Would require significant refactoring of the
>   current algorithm
>
> This issue was previously discussed in:
> https://lore.kernel.org/git/RFC-cover-v2-0.5-00000000000-20211210T122901Z-avarab@gmail.com/
>
> Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> Signed-off-by: Paulo Casaretto <pcasaretto@gmail.com>
> ---

Looks good, especially without the reordering existing entries in the options list. The authorship information above looks much better, too.

Show 11 quoted lines
> @@ -40,6 +57,10 @@ int cmd_range_diff(int argc,
>  				  PARSE_OPT_OPTARG),
>  		OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg,
>  				  N_("style"), N_("passed to 'git log'"), 0),
> +		OPT_CALLBACK(0, "max-memory", &range_diff_opts.max_memory,
> +			     N_("size"),
> +			     N_("maximum memory for cost matrix (default 4G)"),
> +			     parse_max_memory),
>  		OPT_PASSTHRU_ARGV(0, "remerge-diff", &diff_merges_arg, NULL,
>  				  N_("passed to 'git log'"), PARSE_OPT_NOARG),
>  		OPT_BOOL(0, "left-only", &left_only,
Among existing options (an excerpt from "git range-diff h")
    --[no-]creation-factor <n>
                          percentage by which creation is weighted
    This controls how correspondence between commits on old and new
    branches are computed.
    --no-dual-color       use simple diff colors
    --dual-color          opposite of --no-dual-color
    These control how the findings are shown, by painting the lines
    in distinct colors. 
    --[no-]notes[=<notes>]
                          passed to 'git log'
    --[no-]diff-merges <style>
                          passed to 'git log'
    --[no-]remerge-diff   passed to 'git log'
    These control what text are used to represent each commit and
    participate in comparison and display.
    --[no-]left-only      only emit output related to the first range
    --[no-]right-only     only emit output related to the second range
    These again control how the findings are shown, by omitting some
    commits from the output.

So there is no perfectly logical place to place the new option, but between diff-merges and remerge-diff somewhat feels a bit odder choice than other possible places.

Will queue as is. If some users find the location in the "-h" output too odd and disturbing, they can later send in a reordering patch on top, but I would think the chosen location is good enough.

As #leftoverbits we might want to
 * Group range-diff specific options with OPT_GROUP()
 * Instead of having to match the full NxN matrix, perhaps reduce
   the matrix by keeping the most promising M (which is much smaller
   than N) for each N, or something?

but that (especially the latter) is totally outside the scope of this patch.

Thanks.
Previous: Junio C HamanoNext: Paulo Casaretto via GitGitGadget
Message 17 of 18 in “range-diff: add configurable memory limit for cost matrix”
  1. range-diff: add configurable memory limit for cost matrixPaulo Casaretto via GitGitGadget, Aug 26, 2025
  2. Junio C HamanoAug 26, 2025
  3. 0/2 range-diff: add configurable memory limit for cost matrixPaulo Casaretto via GitGitGadget, Aug 28, 2025
  4. 1/2 range-diff: reorder options lexicographicallypcasaretto via GitGitGadget, Aug 28, 2025
  5. Junio C HamanoAug 28, 2025
  6. Elijah NewrenAug 28, 2025
  7. Paulo L F CasarettoAug 29, 2025
  8. Junio C HamanoAug 29, 2025
  9. 2/2 range-diff: add configurable memory limit for cost matrixpcasaretto via GitGitGadget, Aug 28, 2025
  10. Elijah NewrenAug 28, 2025
  11. Junio C HamanoAug 28, 2025
  12. Elijah NewrenAug 28, 2025
  13. Junio C HamanoAug 28, 2025
  14. range-diff: add configurable memory limit for cost matrixPaulo Casaretto via GitGitGadget, Aug 29, 2025
  15. Elijah NewrenAug 29, 2025
  16. Junio C HamanoAug 29, 2025
  17. Junio C HamanoAug 29, 2025
  18. range-diff: add configurable memory limit for cost matrixPaulo Casaretto via GitGitGadget, Aug 29, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.