Subject: Re: [PATCH v2 1/7] reset: behave correctly with sparse-checkout

From: Junio C Hamano <[email-masked]>
Date: Wed, 06 Oct 2021 05:44:14 -0700

Victoria Dye <[email-masked]> writes:

> Thanks for the thorough explanation, I'm on-board with your approach (and
> will re-roll the series with that implemented). A lot of my thought process
> (and confusion) came from a comment in e5ca291076 (t1092: document bad
> sparse-checkout behavior, 2021-07-14) suggesting that full and sparse
> checkouts should have the same result in scenarios like the one you
> outlined above.

Thanks for bringing this up.  I agree that it is crucial to clarify
what use case we are aiming for.  If the objective were to make a
sparse checkout behave just like full checkout, the desired
behaviour would be very different from a system whose objective is
to allow users to pretend as if the hidden parts of sparse checkout
do not even exist, which was the model my example was after.  I
agree with you that the "comment" in an earlier commit may have been
unhelpful in that they stopped at "should behave the same but they
shouldn't" without saying "why they should behave the same".

If the goal were to make sparse behave like full, continuing with
the previous example, after a

    $ git reset --mixed HEAD^

the user should be able to say

    $ git commit -a --amend

to replace the original two-commit history with a single commit
history that records the same resulting tree.  If the path "skip"
were to be reset to the blob from the first commit, just like the
path "no-skip" is, for such a "commit -a --amend" to work, we would
need to have a working tree file for "skip" magically materialized
with the contents from the *second* commit.  After all, the whole
point of mixed (and soft) reset is that they do not (logically)
change the files in the working tree, so if you are resetting from
the second commit to the first, if you were to have a working tree
file, it should come from the second commit, so that both "skip"
and "no-skip" should show "changed in the working tree relative to
the index", i.e.

    $ git reset --mixed HEAD^
    $ git ls-files -t
    M no-skip
    M skip

While such a "make sparse behave the same way as full" can be made
internally consistent, however, as the above example shows, it would
make the resulting "sparse checkout" practically unusable.

By stepping back a bit and realizing that the reason why the user
wanted to mark some path as "skip-worktree" was because the user had
no intention to make any change to them, we can make it usable again,
by not insisting that sparse should behave the same way as full.

When we redesign these patches, I would like to see what we failed
short the last time gets improved.  Instead of saying "skip-worktree
entries should stay so" and stopping there, we should leave a note
for later readers to explain why they should.

Thanks.