On Fri, Sep 15, 2017 at 10:21 AM, Kevin Willford <kewillf@xxxxxxxxxxxxx> wrote: > From: Junio C Hamano [mailto:gitster@xxxxxxxxx] > Sent: Thursday, September 14, 2017 11:00 PM >> >> Kevin Willford <kewillf@xxxxxxxxxxxxx> writes: >> >> > 1. Does this statement, "I only care about the files in this >> > sparse checkout, and do not concern me with anything else", mean >> > that git should not change files outside the sparse-checkout whether >> > that be in the working directory or in the index? Or does that only >> > apply to the working directory and the index version of files can >> > change to whatever git the git command would do without using >> > sparse? For example if I am doing a 'git reset HEAD~1' should the >> > version in the index of files outside the sparse not be changed or >> > change to the HEAD~1 version with the skip-worktree bit on? >> >> My understanding of the purpose of "sparse checkout" thing is that >> the user still wants to create correct whole-tree commit even the >> user does not have the whole-tree checkout. The object names for >> blobs recorded in the index that are meant to be included in the >> next commit MUST be the same as those that would be in the index >> when the "sparse" feature is not in use. "reset HEAD~1" should >> match the index entries to the tree entries in HEAD~1. So, the >> latter, I would think, among your two alternatives. >> >> IOW, after "git reset HEAD~", if you drop the skip-worktree bit from >> all index entries, "git diff --cached HEAD" must say "there is no >> changes". >> >> The only difference between the "sparse" and normal would be that, >> because the "sparse" user does not intend to change anything outside >> the "sparse" area, these paths outside her "sparse" area would not >> materialize on the filesystem. For the next "write-tree" out of the >> index to still write the correct tree out, the entries outside her >> "sparse" area in the index MUST match the tree of the commit she >> started working from. >> > > Makes sense. And even though the reset might only change entries > outside the sparse area and the next status will report "nothing to commit, > working tree clean", that's okay because the user hasn't changed > anything in their sparse area and intended to roll back the index to > whatever they specified in their reset command. > >> > 2. How will this work with other git commands like merge, rebase, >> > cherry-pick, etc.? >> > 3. What about when there is a merge conflict with a file that is outside >> > the sparse checkout? >> >> I would say, rather than forbidding such a merge, it should let her >> see and deal with the conflict by dropping the "this is outside the >> sparse area, so do not bother materializing it to the filesystem" >> bit, but tell her loudly what it did ("I checked out a half-merged >> file outside your sparse-checkout area because you'd need it while >> resolving the conflict"). By doing things that way, the user can >> decide if she wants to go ahead and complete the merge, even if the >> conflict is outside the area she is currently interested in, or >> postpone the merge and continue working on what she has been working >> on inside the narrowed-down area first. >> >> I do not have a strong opinion whether the sparse-checkout >> configuration file should be adjusted to match when the command must >> tentatively bust the sparse checkout area; I'd imagine it can be >> argued either way. >> >> Note that "sparse" is not my itch, and I would not be surprised if >> those who designed it may want it to work differently from my >> knee-jerk reaction in the previous two paragraphs, and I may even >> find such an alternative solution preferable. >> >> But it is highly unlikely for any sensible solution would violate >> the basic premise, i.e. "the indexed contents will stay the same as >> the case without any 'sparse', so the next write-tree will do the >> right thing". > > There was one other case that I thought about while implementing > this approach and it is when the user creates a file that is outside their > sparse definition. From your explanation above I will attempt to > explain how I think it should work and please correct me if you see > it working differently. > > The user creates a file that is outside the sparse area and it will show > up as untracked. No problem here since the untracked are outside the > scope of using sparse. Next the user adds the untracked file to the index. > The skip-worktree bit should be off and stay off since the user could make > additional changes and want to add them. Once the user commits the > newly created file, I could see turning on the skip-worktree bit and > removing the file from the working tree after the commit but since > this was a user initiated action and it is sparse "checkout" it makes > sense to wait until the next "checkout" command which will use the > sparse definition to clean this file from the working directory and > turn on the skip-worktree flag. If the user wants to continue to use > the new file, they would need to update their sparse-checkout file > to include the newly created file so that the next checkout will not > remove it and turn on the flag. This makes sense to me, but possibly we should warn when a user tries to do things with files outside the sparse area? Like when adding a file warn that it already exists? Maybe users do expect the ability to add new files and those would want to get automatically pulled into the "sparse" list? Like if a user adds a completely new file that's never been in the work tree before... Thanks, Jake