On Fri, Jul 20, 2018 at 2:13 PM, Junio C Hamano <gitster@xxxxxxxxx> wrote: > Elijah Newren <newren@xxxxxxxxx> writes: > >> But that brings up another interesting question. What if a merge >> *does* modify a file for which you have skip-worktree set? >> Previously, it'd clear the bit and write the file to the working tree, >> but that was by no means an explicit decision; > > At least in my mind, the "skip worktree" aka sparse checkout has > always been "best effort" in that if Git needs to materialize a > working tree file in order to carry out some operation (e.g. a merge > needs conflict resolution, hence we need to give a working tree file > with conflict markers to the end user) Git is free to do so. > > Isn't that what happens currently? Ah, okay, that's helpful. So, if there are conflicts, it should be free to clear the skip_worktree flag. Since merge-recursive calls add_cacheinfo() for all entries it needs to update, which deletes the old cache entry and just makes new ones, we get that for free. And conversely, if a file-level merge succeeds without conflicts then it clearly doesn't "need to materialize a working tree file", so it should NOT clear the skip_worktree flag for that path. (Unfortunately, that means we have to work around add_cacheinfo() for these cases.)