Re: [PATCH v2 4/4] builtin/stash: merge index in-core
- From
- Phillip Wood <phillip.wood123@gmail.com>
- Date
- Sep 24, 2026, 09:42 UTC
- Message-ID
- <68e83baa-6ccb-4ca8-a1df-f09d51749c67@gmail.com>
- In-Reply-To
- <e49936ee12aaf5d82a98dddcc618cee01ac3c681.1790168285.git.ben.knoble@gmail.com>
Hi Ben
I've spotted a memory leak that I missed last time, apart from that this looks good.
On 23/09/2026 13:58, D. Ben Knoble wrote:
Show 13 quoted lines
> @@ -671,29 +627,27 @@ static enum stash_apply_result do_apply_stash(const char *prefix,
> oideq(&c_tree, &info->i_tree)) {
> has_index = 0;
> } else {
> - struct strbuf out = STRBUF_INIT;
> + struct merge_result result = { 0 };
>
> - if (diff_tree_binary(&out, &info->w_commit)) {
> - strbuf_release(&out);
> - return error(_("could not generate diff %s^!."),
> - oid_to_hex(&info->w_commit));
> - }
> + o.branch1 = "Upstream index";This is the current index, calling it "upstream" is a bit confusing to me but that's not worth a re-roll on its own.
Show 18 quoted lines
> + o.branch2 = "Stashed index changes";
> + o.ancestor = "Stash base";
>
> - ret = apply_cached(&out);
> - strbuf_release(&out);
> - if (ret)
> + o.verbosity = 0;
> +
> + head = lookup_tree(o.repo, &c_tree);
> + merge = lookup_tree(o.repo, &info->i_tree);
> + merge_base = lookup_tree(o.repo, &info->b_tree);
> +
> + merge_incore_nonrecursive(&o, head, merge, merge_base,
> + &result);
> +
> + if (!result.clean)
> return error(_("conflicts in index. "
> "Try without --index."));Sorry, I missed this last time, but we should finalize the merge before returning to ensure the allocations in result are freed. Everything else looks fine.
Thanks
Phillip
Show 34 quoted lines
> - discard_index(the_repository->index);
> - repo_read_index(the_repository);
> - if (write_index_as_tree(&index_tree, the_repository->index,
> - repo_get_index_file(the_repository), 0, NULL))
> - return error(_("could not save index tree"));
> -
> - reset_head();
> - discard_index(the_repository->index);
> - repo_read_index(the_repository);
> + oidcpy(&index_tree, &result.tree->object.oid);
> + merge_finalize(&o, &result);
> }
> }
>
> diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
> index 64fe21717d..8f6109fb91 100755
> --- a/t/t7600-merge.sh
> +++ b/t/t7600-merge.sh
> @@ -801,6 +801,15 @@ verify_no_mergehead () {
> test_cmp result.1-5 file
> '
>
> +test_expect_success 'fast-forward merge with --autostash, stash.index' '
> + git reset --hard c0 &&
> + git stash clear &&
> + echo staged >>z && git add z &&
> + git -c stash.index=true merge --autostash c1 2>err &&
> + test_grep "Applied autostash." err &&
> + test_stdout_line_count = 0 git stash list
> +'
> +
> test_expect_success 'failed fast-forward merge with --autostash' '
> git reset --hard c0 &&
> git merge-file file file.orig file.5 &&