From: Phillip Wood <phillip.wood123@gmail.com>
To: jasmeet.bhatia.us@gmail.com, git@vger.kernel.org
Cc: Deveshi Dwivedi <deveshigurgaon@gmail.com>,
Junio C Hamano <gitster@pobox.com>,
Patrick Steinhardt <ps@pks.im>,
Leon Michalak <leonmichalak6@gmail.com>
Subject: Re: [PATCH] stash: reuse prepared state when creating stash
Date: Mon, 2 Nov 2026 14:14:57 +0000 [thread overview]
Message-ID: <845be1de-8d12-41c9-996d-038886bde4cf@gmail.com> (raw)
In-Reply-To: <20261031200107.285168-1-jasmeet.bhatia.us@gmail.com>
Hi Jasmeet
On 31/10/2026 20:01, jasmeet.bhatia.us@gmail.com wrote:
> From: "Jasmeet (Jazz) Bhatia" <jasmeet.bhatia.us@gmail.com>
>
> do_push_stash() already preloads and refreshes the index and calls
> check_changes() before invoking do_create_stash(). However, Git then
> repeats this same index preparation and change detection, including
> rebuilding the list of untracked files when requested, which is
> duplicate work.
Good observation
> Instead, avoid this duplicate work by passing the already prepared
> untracked file list to do_create_stash(). When the list is provided,
> reuse it and skip the redundant index preload, refresh, and
> check_changes() call.
I've got some patches in "seen" [1] that take a slightly different
approach and keep the call to check_changes() in do_create_stash() and
remove it from create_stash() and do_push_stash() instead. That series
also removes a number of unnecessary calls to preload_index(). If you
have time to post a review that would be really helpful.
Thanks
Phillip
[1] The patches are at
https://lore.kernel.org/git/cover.1792767794.git.phillip.wood@dunelm.org.uk/
and are merged into seen as branch 'pw/stash-change-check-only-once'
> This maintains the existing behavior of "git stash create", which
> invokes do_create_stash() without prepared state and thus continues
> to perform its own index preparation and change detection.
>
> Testing this using the p3904 stash performance tests shows a decent
> performance boost.
>
> stash -p, no fsmonitor
> 0.12(0.11+0.17) -> 0.10(0.10+0.18) -16.7%
>
> stash -p, builtin fsmonitor
> 0.11(0.10+0.02) -> 0.09(0.08+0.01) -18.2%
>
> Testing this on the Linux kernel on my system, "git stash push"
> improved from 254 ms to about 239 ms, which is about 6%.
>
> Signed-off-by: Jasmeet (Jazz) Bhatia <jasmeet.bhatia.us@gmail.com>
> ---
> builtin/stash.c | 25 +++++++++++++++----------
> 1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/builtin/stash.c b/builtin/stash.c
> index e1a3a76bd0..58eb782597 100644
> --- a/builtin/stash.c
> +++ b/builtin/stash.c
> @@ -1459,7 +1459,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
> int include_untracked, int patch_mode,
> struct interactive_options *interactive_opts,
> int only_staged, struct stash_info *info, struct strbuf *patch,
> - int quiet)
> + int quiet, struct strbuf *prepared_untracked_files)
> {
> int ret = 0;
> int flags = 0;
> @@ -1473,14 +1473,17 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
> struct strbuf msg = STRBUF_INIT;
> struct strbuf commit_tree_label = STRBUF_INIT;
> struct strbuf untracked_files = STRBUF_INIT;
> + struct strbuf *untracked_files_p = prepared_untracked_files ? prepared_untracked_files : &untracked_files;
>
> prepare_fallback_ident("git stash", "git@stash");
>
> - repo_read_index_preload(the_repository, NULL, 0);
> - if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
> - NULL, NULL, NULL) < 0) {
> - ret = error(_("could not write index"));
> - goto done;
> + if (!prepared_untracked_files) {
> + repo_read_index_preload(the_repository, NULL, 0);
> + if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0,
> + NULL, NULL, NULL) < 0) {
> + ret = error(_("could not write index"));
> + goto done;
> + }
> }
>
> if (repo_get_oid(the_repository, "HEAD", &info->b_commit)) {
> @@ -1493,7 +1496,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
> head_commit = lookup_commit(the_repository, &info->b_commit);
> }
>
> - if (!check_changes(ps, include_untracked, &untracked_files)) {
> + if (!prepared_untracked_files &&
> + !check_changes(ps, include_untracked, untracked_files_p)) {
> ret = 1;
> goto done;
> }
> @@ -1529,7 +1533,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
> parents = NULL;
>
> if (include_untracked) {
> - if (save_untracked_files(info, &msg, &untracked_files)) {
> + if (save_untracked_files(info, &msg, untracked_files_p)) {
> if (!quiet)
> fprintf_ln(stderr, _("Cannot save "
> "the untracked files"));
> @@ -1615,7 +1619,7 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED,
> return 0;
>
> ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, NULL, 0, &info,
> - NULL, 0);
> + NULL, 0, NULL);
> if (!ret)
> printf_ln("%s", oid_to_hex(&info.w_commit));
>
> @@ -1698,7 +1702,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
> if (stash_msg)
> strbuf_addstr(&stash_msg_buf, stash_msg);
> if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode,
> - interactive_opts, only_staged, &info, &patch, quiet)) {
> + interactive_opts, only_staged, &info, &patch, quiet,
> + &untracked_files)) {
> ret = -1;
> goto done;
> }
next prev parent reply other threads:[~2026-11-02 14:15 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-31 20:01 [PATCH] stash: reuse prepared state when creating stash jasmeet.bhatia.us
2026-11-02 14:14 ` Phillip Wood [this message]
2026-11-09 5:09 ` jasmeet.bhatia.us
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=845be1de-8d12-41c9-996d-038886bde4cf@gmail.com \
--to=phillip.wood123@gmail.com \
--cc=deveshigurgaon@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jasmeet.bhatia.us@gmail.com \
--cc=leonmichalak6@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox