On Thu, Nov 21, 2019 at 09:28:59AM -0500, Derrick Stolee wrote: > On 11/21/2019 6:49 AM, SZEDER Gábor wrote: > > On Mon, Oct 21, 2019 at 01:56:11PM +0000, Derrick Stolee via GitGitGadget wrote: > >> Getting started with a sparse-checkout file can be daunting. Help > >> users start their sparse enlistment using 'git sparse-checkout init'. > >> This will set 'core.sparseCheckout=true' in their config, write > >> an initial set of patterns to the sparse-checkout file, and update > >> their working directory. > > > > Enabling sparse-checkout can remove modified files: > > > > $ mkdir dir > > $ touch foo dir/bar > > $ git add . > > $ git commit -m Initial > > [master (root-commit) ecc81bd] Initial > > 2 files changed, 0 insertions(+), 0 deletions(-) > > create mode 100644 dir/bar > > create mode 100644 foo > > $ echo changes >dir/bar > > $ ~/src/git/git sparse-checkout init > > error: Entry 'dir/bar' not uptodate. Cannot update sparse checkout. > > error: failed to update index with new sparse-checkout paths > > $ cat dir/bar > > changes > > > > So far so good, my changes are still there. Unfortunately, however: > > > > $ git add -u > > $ ~/src/git/git sparse-checkout init > > $ echo $? > > 0 > > $ ls > > foo > > > > Uh-oh, my changes are gone. > > Here, your changes are not "lost", they are staged, correct? Well, yes, the changes were staged, so they must be in the object database somewhere, the user just has to go through the dangling objects reported by 'git fsck' to find and restore it... So from the perspective of an ordinary user they are lost. > A "git status" > should report that your changes are ready for committing. This seems to be > the expected behavior. No, unfortunately enabling sparse-checkout did throw the staged changes away: ~/test (master +)$ ~/src/git/git sparse-checkout init ~/test (master)$ git status On branch master nothing to commit, working tree clean Note also the shell prompt going from "you have staged changes" to "working tree is clean". But wait, I thought that only changes to files that are excluded from the sparse-checkout are thrown away, but as it turns out it throws away changes to files that are included in the sparse-checkout: ~/test (master #)$ echo original >foo ~/test (master #%)$ git add . ~/test (master +)$ git commit -m Initial [master (root-commit) 04cb2a2] Initial 1 file changed, 1 insertion(+) create mode 100644 foo ~/test (master)$ echo changes >foo ~/test (master *)$ ~/src/git/git sparse-checkout init ~/test (master *)$ cat foo changes So far so good, but: ~/test (master *)$ ~/src/git/git sparse-checkout disable ~/test (master *)$ git add . ~/test (master +)$ ~/src/git/git sparse-checkout init ~/test (master)$ cat foo original This is not really sparse-checkout-specific, because this is what 'git read-tree -um HEAD' always does on its own: ~/test (master)$ echo changes >foo ~/test (master *)$ git read-tree -um HEAD ~/test (master *)$ cat foo changes ~/test (master *)$ git add -u ~/test (master +)$ git read-tree -um HEAD ~/test (master)$ cat foo original These issues are present at the end of the patch series as well, but that is sort-of expected, because the later commit message states that: Remove this extra process call by creating a direct call to unpack_trees() in the same way 'git read-tree -mu HEAD' does.