git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Thomas Gummerer <t.gummerer@gmail.com>
Cc: Grzegorz Rajchman <rayman17@gmail.com>, git@vger.kernel.org
Subject: Re: [BUG] git stash pop --quiet deletes files in git 2.24.0
Date: Fri, 08 Nov 2019 11:32:50 +0900	[thread overview]
Message-ID: <xmqq7e4bp06l.fsf@gitster-ct.c.googlers.com> (raw)
In-Reply-To: <20191107184912.GA3115@cat> (Thomas Gummerer's message of "Thu, 7 Nov 2019 18:49:12 +0000")

Thomas Gummerer <t.gummerer@gmail.com> writes:

> On 11/07, Grzegorz Rajchman wrote:
>> Hi, this is the first time I report an issue in git so I hope I'm
>> doing it right.
>
> Thanks for the report.  You are indeed doing this right, and the
> included reproduction is very helpful.
>
> I broke this in 34933d0eff ("stash: make sure to write refreshed
> cache", 2019-09-11), which wasn't caught by the tests, nor by me as I
> don't use the --quiet flag normally.
>
> Below is a fix for this, but I want to understand the problem a bit
> better and write some tests before sending a patch.

OK, thanks for quickly looking into this.

The commit added two places where refresh_and_write_cache() gets
called.

The first one at the very beginning of do_apply_stash() used to be
refresh_cache() that immediately follows read_cache_preload().  We
are writing back exactly what we read from the filesystem [*], so
this should be a no-op from the correctness POV, with benefit of
having a refreshed cache on disk.

	Side note.  This argument assumes that no caller has called
	read_cache() before calling us and did its own in-core index
	operation.  In such a case, the in-core index is already out
	of sync with the on-disk one due to our own operation, and
	read_cache() will not overwrite already initilized in-core
	index, so we will write out what the original code did not
	want to, which would be a bug.

The second one happens after we do all the 3-way merges to replay
the change between the base commit and the working tree state
recorded in the stash, and then adjust the index to the desired
state:

 - If we are propagating the change to the index recorded in the
   stash to the current index, reset_tree() reads the index_tree
   that has been computed earlier in the function to update the
   in-core index and the on-disk index.

 - Otherwise, we compute paths added between the base commit and the
   working tree state recorded in the stash (i.e. those that were
   created but not yet commited when the stash was made), go back to
   the in-core index state we had upon entry to this function
   (i.e. c_tree), and then add these new paths from the working tree
   directly to the on-disk index without updating the in-core
   index.  Notice that this leaves the in-core index stale wrt the
   on-disk index---but the stale in-core index gets discarded.

Then the code goes on to do:

 - under --quiet, refresh_cache() used to be called to silently
   refresh the in-core index.  34933d0eff made it to also write the
   in-core index to on-disk index.  OOPS.  The in-core index has
   been discarded at this point.

 - otherwise, "git status" is spawned and directly acted on the
   on-disk index (this also has a side effect of writing a refreshed
   on-disk index).

So, I do not think removing that discard_cache() alone solves the
breakage exposed by 34933d0eff.  Discarding and re-reading the
on-disk index there would restore correctness, but then you would
want to make sure that we are not wasting the overall cost for the
I/O and refreshing.

I think the safer immediate short-term fix is to revert the change
to the quiet codepath and let it only refresh the in-core index.

> index ab30d1e920..2dd9c9bbcd 100644
> --- a/builtin/stash.c
> +++ b/builtin/stash.c
> @@ -473,22 +473,20 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
>  
>                 if (reset_tree(&c_tree, 0, 1)) {
>                         strbuf_release(&out);
>                         return -1;
>                 }
>  
>                 ret = update_index(&out);
>                 strbuf_release(&out);
>                 if (ret)
>                         return -1;
> -
> -               discard_cache();
>         }
>  
>         if (quiet) {
>                 if (refresh_and_write_cache(REFRESH_QUIET, 0, 0))
>                         warning("could not refresh index");
>         } else {
>                 struct child_process cp = CHILD_PROCESS_INIT;

  reply	other threads:[~2019-11-08  2:32 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-07 10:36 [BUG] git stash pop --quiet deletes files in git 2.24.0 Grzegorz Rajchman
2019-11-07 18:49 ` Thomas Gummerer
2019-11-08  2:32   ` Junio C Hamano [this message]
2019-11-08 16:59     ` Thomas Gummerer
2019-11-10  6:11       ` Junio C Hamano
2019-11-11 19:56         ` Thomas Gummerer
2019-11-12  5:21           ` Junio C Hamano
2019-11-13 11:15             ` Thomas Gummerer
2019-11-13 13:31               ` Junio C Hamano
2019-11-13 15:01                 ` [PATCH v3] stash: make sure we have a valid index before writing it Thomas Gummerer
2019-11-14  2:07                   ` Junio C Hamano
2019-11-13 11:17           ` [PATCH v2 1/2] t3903: avoid git commands inside command substitution Thomas Gummerer
2019-11-13 11:17             ` [PATCH v2 2/2] stash: make sure we have a valid index before writing it Thomas Gummerer

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqq7e4bp06l.fsf@gitster-ct.c.googlers.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=rayman17@gmail.com \
    --cc=t.gummerer@gmail.com \
    /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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).