{"thread":{"id":"66267","subject":"history: 'reword HEAD' surfaces a memory leak","startedAt":"2026-09-03T15:27:07Z","lastAt":"2026-09-10T15:28:13Z","messageCount":5,"participants":["Kristoffer Haugsbakk","Patrick Steinhardt","Kaartic Sivaraam"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"551880","messageId":"04faa984-5b56-406b-baa9-dbb4b5eab259@app.fastmail.com","threadId":"66267","inReplyTo":null,"subject":"history: 'reword HEAD' surfaces a memory leak","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2026-09-03T15:26:44Z","receivedAt":"2026-09-03T15:27:07Z","isPatch":false,"body":"I get a sanitizer error when I run a simple reword command:\n\n    $ make SANITIZE=address install\n    $ GIT_EDITOR=true git history reword \\\n        --dry-run 3cb9185f65410273787f74333cc027d2ea5daada\n    update HEAD eeb9d4b5c4041739c0a19b4043924513c8aad2d2 3cb9185f65410273787f74333cc027d2ea5daada\n\n    =================================================================\n    ==116999==ERROR: LeakSanitizer: detected memory leaks\n\n    Direct leak of 283 byte(s) in 1 object(s) allocated from:\n        #0 0x712d2f6b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145\n        #1 0x61970a5757b2 in do_xmalloc /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:55\n        #2 0x61970a575ec0 in do_xmallocz /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:89\n        #3 0x61970a575ec0 in do_xmallocz /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:79\n        #4 0x61970a575ec0 in xmallocz_gently /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:102\n        #5 0x61970a309ca0 in unpack_compressed_entry /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1732\n        #6 0x61970a310bf0 in unpack_entry /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1885\n        #7 0x61970a311fbf in cache_or_unpack_entry /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1528\n        #8 0x61970a311fbf in packed_object_info_with_index_pos /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1610\n        #9 0x61970a313097 in packed_object_info /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1720\n        #10 0x61970a313097 in packfile_store_read_object_info /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:2214\n        #11 0x61970a2caae8 in odb_source_files_read_object_info odb/source-files.c:58\n        #12 0x61970a2c69a7 in odb_source_read_object_info odb/source.h:326\n        #13 0x61970a2c69a7 in do_oid_object_info_extended /home/kristoffer/programming/git-worktree/git-leakcheck/odb.c:572\n        #14 0x61970a2c69a7 in odb_read_object_info_extended /home/kristoffer/programming/git-worktree/git-leakcheck/odb.c:710\n        #15 0x61970a2c7cbe in odb_read_object /home/kristoffer/programming/git-worktree/git-leakcheck/odb.c:756\n        #16 0x61970a101d5a in repo_get_commit_buffer /home/kristoffer/programming/git-worktree/git-leakcheck/commit.c:399\n        #17 0x61970a101d5a in repo_get_commit_buffer /home/kristoffer/programming/git-worktree/git-leakcheck/commit.c:391\n        #18 0x61970a346bf6 in repo_logmsg_reencode /home/kristoffer/programming/git-worktree/git-leakcheck/pretty.c:716\n        #19 0x619709ebbe64 in commit_tree_ext builtin/history.c:127\n        #20 0x619709ebd17f in commit_tree_with_edited_message builtin/history.c:183\n        #21 0x619709ebd17f in cmd_history_reword builtin/history.c:717\n        #22 0x619709ec186f in cmd_history builtin/history.c:998\n        #23 0x619709d87ca0 in run_builtin /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:506\n        #24 0x619709d87ca0 in handle_builtin /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:782\n        #25 0x619709d8c9a6 in run_argv /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:865\n        #26 0x619709d8c9a6 in cmd_main /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:986\n        #27 0x619709d83f54 in main /home/kristoffer/programming/git-worktree/git-leakcheck/common-main.c:9\n        #28 0x712d2f229d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58\n\n    SUMMARY: AddressSanitizer: 283 byte(s) leaked in 1 allocation(s).\n\nThe `--dry-run` is optional.\n\nI get this on master, next, and seen, respectively:\n\n1. `master`: 17ff1f98 (Sync with 'master', 2026-09-02)\n2. 17ff1f98 (Sync with 'master', 2026-09-02)\n3. 99855fed (Merge branch 'cc/early-scan-options' into seen, 2026-09-02)\n\nI do not get this error when testing on the commit that introduced `git\nhistory reword` (see later bisect log).\n\nIt’s too technical for me, but it seems that git-history(1) just\ntriggers a memory leak in the internal library (name?) code. Maybe you\nneed a packfile and/or a commit graph?\n\nBisecting told me that the first bad commit is 13763ecf (Merge branch\n'ps/receive-pack-shallow-optim', 2026-03-02).\n\nI tried to make an automated test for it but didn’t quite hack it. I got\nan ad hoc repo to reproduce. Running a GC or commit-graph (and/or) might\nhave what have done it.\n\nBut it seems to happen every time I run the command in a “real repo” as\nlong as I don’t violate one of the preconditions (“can’t replay merge\ncommits yet!” etc.).\n\nBISECT SCRIPT\n\nNote: hopefully this isn’t sensitive to if there are\nrefs pointing to that commit. The commit is just\n`git rev-parse origin/master`.\n\n```\n#!/bin/sh\n\n# No setup. Just use this repo.\nmake SANITIZE=address || exit 125\n: >err.txt\nGIT_EDITOR=true ./bin-wrappers/git history reword 3cb9185f65410273787f74333cc027d2ea5daada 2>err.txt || {\n    grep -q 'detected memory leaks' err.txt && exit 1\n}\n\nexit 0\n```\n\nBISECT LOG\n\n    $ git bisect log\n    git bisect start\n    # status: waiting for both 'good' and 'bad' commits\n    # bad: [1630431f326e15fcde608827b5ff38422528eb59] The 21st batch\n    git bisect bad 1630431f326e15fcde608827b5ff38422528eb59\n    # status: waiting for 'good' commit(s), 'bad' commit known\n    # good: [d205234cb05a5e330c0f7f5b3ea764533a74d69e] builtin/history: implement \"reword\" subcommand\n    git bisect good d205234cb05a5e330c0f7f5b3ea764533a74d69e\n    # bad: [27caa6b4f7bce94fc1f07b96bcb0bcef8c5215f5] Merge branch 'en/backfill-fixes-and-edges'\n    git bisect bad 27caa6b4f7bce94fc1f07b96bcb0bcef8c5215f5\n    # bad: [6cdef943d28fa7d6964ec570b33a0bff4c80ea8c] Merge branch 'ps/odb-sources' into ps/object-counting\n    git bisect bad 6cdef943d28fa7d6964ec570b33a0bff4c80ea8c\n    # good: [94336d77bcbf4360b67a9454d8bf2e84b3d88ae7] Merge branch 'sd/doc-my1c-api-config-reference-fix'\n    git bisect good 94336d77bcbf4360b67a9454d8bf2e84b3d88ae7\n    # bad: [13763ecf7d92be72beff75c59163c5448d9e085e] Merge branch 'ps/receive-pack-shallow-optim'\n    git bisect bad 13763ecf7d92be72beff75c59163c5448d9e085e\n    # good: [bb9c781f4f4be2e6bf6285149ba7007fdaa735e7] Merge branch 'ps/history-ergonomics-updates'\n    git bisect good bb9c781f4f4be2e6bf6285149ba7007fdaa735e7\n    # good: [2cc71917514657b93014134350864f4849edfc83] The 8th batch\n    git bisect good 2cc71917514657b93014134350864f4849edfc83\n    # good: [664bd4e15a99a477acb616337df0f9fa95c729c3] Merge branch 'ty/symlinks-use-unsigned-for-bitset'\n    git bisect good 664bd4e15a99a477acb616337df0f9fa95c729c3\n    # good: [05c4af5c8f3d7310c8a3b2909d30ce761c6757aa] Merge branch 'kh/doc-am-xref'\n    git bisect good 05c4af5c8f3d7310c8a3b2909d30ce761c6757aa\n    # good: [427d39ca4f4f7a0e66652d92340af43cbda5135e] Merge branch 'ps/meson-gitk-git-gui'\n    git bisect good 427d39ca4f4f7a0e66652d92340af43cbda5135e\n    # good: [34113149cfde760b6b791939c6d8d87d27ca2767] Merge branch 'kh/doc-patch-id-4'\n    git bisect good 34113149cfde760b6b791939c6d8d87d27ca2767\n    # good: [024b4c96976fabdc8b73f4183d6bb8626ffe2c7d] commit: make `repo_parse_commit_no_graph()` more robust\n    git bisect good 024b4c96976fabdc8b73f4183d6bb8626ffe2c7d\n    # good: [bb5da75d6116c35924a04a418ef4c3182663d0a2] commit: use commit graph in `lookup_commit_reference_gently()`\n    git bisect good bb5da75d6116c35924a04a418ef4c3182663d0a2\n    # first 'bad' commit: [13763ecf7d92be72beff75c59163c5448d9e085e] Merge branch 'ps/receive-pack-shallow-optim'\n"},{"id":"552122","messageId":"ap6cU2elXvmlLgb8@pks.im","threadId":"66267","inReplyTo":"04faa984-5b56-406b-baa9-dbb4b5eab259@app.fastmail.com","subject":"Re: history: 'reword HEAD' surfaces a memory leak","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-09-07T11:13:23Z","receivedAt":"2026-09-07T11:13:30Z","isPatch":false,"body":"On Thu, Sep 03, 2026 at 05:26:44PM +0200, Kristoffer Haugsbakk wrote:\n> I get a sanitizer error when I run a simple reword command:\n> \n>     $ make SANITIZE=address install\n>     $ GIT_EDITOR=true git history reword \\\n>         --dry-run 3cb9185f65410273787f74333cc027d2ea5daada\n>     update HEAD eeb9d4b5c4041739c0a19b4043924513c8aad2d2 3cb9185f65410273787f74333cc027d2ea5daada\n> \n>     =================================================================\n>     ==116999==ERROR: LeakSanitizer: detected memory leaks\n> \n>     Direct leak of 283 byte(s) in 1 object(s) allocated from:\n>         #0 0x712d2f6b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145\n>         #1 0x61970a5757b2 in do_xmalloc /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:55\n>         #2 0x61970a575ec0 in do_xmallocz /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:89\n>         #3 0x61970a575ec0 in do_xmallocz /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:79\n>         #4 0x61970a575ec0 in xmallocz_gently /home/kristoffer/programming/git-worktree/git-leakcheck/wrapper.c:102\n>         #5 0x61970a309ca0 in unpack_compressed_entry /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1732\n>         #6 0x61970a310bf0 in unpack_entry /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1885\n>         #7 0x61970a311fbf in cache_or_unpack_entry /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1528\n>         #8 0x61970a311fbf in packed_object_info_with_index_pos /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1610\n>         #9 0x61970a313097 in packed_object_info /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:1720\n>         #10 0x61970a313097 in packfile_store_read_object_info /home/kristoffer/programming/git-worktree/git-leakcheck/packfile.c:2214\n>         #11 0x61970a2caae8 in odb_source_files_read_object_info odb/source-files.c:58\n>         #12 0x61970a2c69a7 in odb_source_read_object_info odb/source.h:326\n>         #13 0x61970a2c69a7 in do_oid_object_info_extended /home/kristoffer/programming/git-worktree/git-leakcheck/odb.c:572\n>         #14 0x61970a2c69a7 in odb_read_object_info_extended /home/kristoffer/programming/git-worktree/git-leakcheck/odb.c:710\n>         #15 0x61970a2c7cbe in odb_read_object /home/kristoffer/programming/git-worktree/git-leakcheck/odb.c:756\n>         #16 0x61970a101d5a in repo_get_commit_buffer /home/kristoffer/programming/git-worktree/git-leakcheck/commit.c:399\n>         #17 0x61970a101d5a in repo_get_commit_buffer /home/kristoffer/programming/git-worktree/git-leakcheck/commit.c:391\n>         #18 0x61970a346bf6 in repo_logmsg_reencode /home/kristoffer/programming/git-worktree/git-leakcheck/pretty.c:716\n>         #19 0x619709ebbe64 in commit_tree_ext builtin/history.c:127\n>         #20 0x619709ebd17f in commit_tree_with_edited_message builtin/history.c:183\n>         #21 0x619709ebd17f in cmd_history_reword builtin/history.c:717\n>         #22 0x619709ec186f in cmd_history builtin/history.c:998\n>         #23 0x619709d87ca0 in run_builtin /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:506\n>         #24 0x619709d87ca0 in handle_builtin /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:782\n>         #25 0x619709d8c9a6 in run_argv /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:865\n>         #26 0x619709d8c9a6 in cmd_main /home/kristoffer/programming/git-worktree/git-leakcheck/git.c:986\n>         #27 0x619709d83f54 in main /home/kristoffer/programming/git-worktree/git-leakcheck/common-main.c:9\n>         #28 0x712d2f229d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58\n> \n>     SUMMARY: AddressSanitizer: 283 byte(s) leaked in 1 allocation(s).\n\nThis feels familiar, even though it doesn't reproduce on my machine. Do\nyou have \"i18n.commitencoding\" set? In any case, I think the following\npatch should fix it:\n\ndiff --git a/builtin/history.c b/builtin/history.c\nindex 000155ad9c..bca95b9d05 100644\n--- a/builtin/history.c\n+++ b/builtin/history.c\n@@ -158,6 +158,7 @@ static int commit_tree_ext(struct repository *repo,\n \t*out = lookup_commit_or_die(&rewritten_commit_oid, \"rewritten commit\");\n \n out:\n+\trepo_unuse_commit_buffer(repo, commit_with_message, original_message);\n \tfree_commit_extra_headers(original_extra_headers);\n \tstrbuf_release(&commit_message);\n \tfree(original_author);\n\nI know that we've already been discussing this memory leak on the\nmailing list at one point in time, and we've already had a patch similar\nto the above. So why wasn't this merged...?\n\nAh, the discussion was in [1]. Cc'ing Kaartic.\n\nThanks!\n\nPatrick\n\n[1]: https://lore.kernel.org/git/20260614141600.620272-1-kaartic.sivaraam@gmail.com/\n"},{"id":"552135","messageId":"c12fe123-bf10-46f1-b369-b582a623ce19@gmail.com","threadId":"66267","inReplyTo":"ap6cU2elXvmlLgb8@pks.im","subject":"Re: history: 'reword HEAD' surfaces a memory leak","fromName":"Kaartic Sivaraam","fromEmail":"kaartic.sivaraam@gmail.com","sentAt":"2026-09-07T11:46:44Z","receivedAt":"2026-09-07T11:46:50Z","isPatch":false,"body":"On 9/7/26 16:43, Patrick Steinhardt wrote:\n> \n> This feels familiar, even though it doesn't reproduce on my machine. Do\n> you have \"i18n.commitencoding\" set? In any case, I think the following\n> patch should fix it:\n> \n> diff --git a/builtin/history.c b/builtin/history.c\n> index 000155ad9c..bca95b9d05 100644\n> --- a/builtin/history.c\n> +++ b/builtin/history.c\n> @@ -158,6 +158,7 @@ static int commit_tree_ext(struct repository *repo,\n>   \t*out = lookup_commit_or_die(&rewritten_commit_oid, \"rewritten commit\");\n>   \n>   out:\n> +\trepo_unuse_commit_buffer(repo, commit_with_message, original_message);\n>   \tfree_commit_extra_headers(original_extra_headers);\n>   \tstrbuf_release(&commit_message);\n>   \tfree(original_author);\n> \n> I know that we've already been discussing this memory leak on the\n> mailing list at one point in time, and we've already had a patch similar\n> to the above. So why wasn't this merged...?\n>\n\nMy bad, I suppose. There was a suggestion by Peff that the commit \nmessage was misleading. Per [2], the leak only happens when we get a \ncommit that isn't cached in the commit slab. I was trying to identify \nthe specific case in which we get a commit that's not cached in the slab \nbut eventually got busy with other work. I will get around to it soon \nand send a long pending re-roll.\n\n[[ References ]]\n\n[2]: \nhttps://lore.kernel.org/git/94b0bed5-c86a-4291-b958-52f09faebd29@gmail.com/\n\n--\nSivaraam\n\n"},{"id":"552137","messageId":"ap6qQPL7dPjZy1lO@pks.im","threadId":"66267","inReplyTo":"c12fe123-bf10-46f1-b369-b582a623ce19@gmail.com","subject":"Re: history: 'reword HEAD' surfaces a memory leak","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-09-07T12:12:48Z","receivedAt":"2026-09-07T12:12:54Z","isPatch":false,"body":"On Mon, Sep 07, 2026 at 05:16:44PM +0530, Kaartic Sivaraam wrote:\n> On 9/7/26 16:43, Patrick Steinhardt wrote:\n> > \n> > This feels familiar, even though it doesn't reproduce on my machine. Do\n> > you have \"i18n.commitencoding\" set? In any case, I think the following\n> > patch should fix it:\n> > \n> > diff --git a/builtin/history.c b/builtin/history.c\n> > index 000155ad9c..bca95b9d05 100644\n> > --- a/builtin/history.c\n> > +++ b/builtin/history.c\n> > @@ -158,6 +158,7 @@ static int commit_tree_ext(struct repository *repo,\n> >   \t*out = lookup_commit_or_die(&rewritten_commit_oid, \"rewritten commit\");\n> >   out:\n> > +\trepo_unuse_commit_buffer(repo, commit_with_message, original_message);\n> >   \tfree_commit_extra_headers(original_extra_headers);\n> >   \tstrbuf_release(&commit_message);\n> >   \tfree(original_author);\n> > \n> > I know that we've already been discussing this memory leak on the\n> > mailing list at one point in time, and we've already had a patch similar\n> > to the above. So why wasn't this merged...?\n> > \n> \n> My bad, I suppose. There was a suggestion by Peff that the commit message\n> was misleading. Per [2], the leak only happens when we get a commit that\n> isn't cached in the commit slab. I was trying to identify the specific case\n> in which we get a commit that's not cached in the slab but eventually got\n> busy with other work. I will get around to it soon and send a long pending\n> re-roll.\n> \n> [[ References ]]\n> \n> [2]:\n> https://lore.kernel.org/git/94b0bed5-c86a-4291-b958-52f09faebd29@gmail.com/\n\nAwesome, thanks!\n\nPatrick\n"},{"id":"552459","messageId":"2589b284-28ea-4724-8aaf-5ca438957755@app.fastmail.com","threadId":"66267","inReplyTo":"ap6qQPL7dPjZy1lO@pks.im","subject":"Re: history: 'reword HEAD' surfaces a memory leak","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2026-09-10T15:27:48Z","receivedAt":"2026-09-10T15:28:13Z","isPatch":false,"body":"On Mon, Sep 7, 2026, at 14:12, Patrick Steinhardt wrote:\n> On Mon, Sep 07, 2026 at 05:16:44PM +0530, Kaartic Sivaraam wrote:\n>> On 9/7/26 16:43, Patrick Steinhardt wrote:\n>> >\n>> > This feels familiar, even though it doesn't reproduce on my machine. Do\n>> > you have \"i18n.commitencoding\" set? In any case, I think the following\n>> > patch should fix it:\n>> >\n>> >[snip]\n>> >\n>>\n>> My bad, I suppose. There was a suggestion by Peff that the commit message\n>> was misleading. Per [2], the leak only happens when we get a commit that\n>> isn't cached in the commit slab. I was trying to identify the specific case\n>> in which we get a commit that's not cached in the slab but eventually got\n>> busy with other work. I will get around to it soon and send a long pending\n>> re-roll.\n>>\n>> [[ References ]]\n>>\n>> [2]:\n>> https://lore.kernel.org/git/94b0bed5-c86a-4291-b958-52f09faebd29@gmail.com/\n>\n> Awesome, thanks!\n\nThanks, everyone. It makes sense that the commit graph was the\ntriggering factor.\n"}]}