Derrick Stolee <derrickstolee@xxxxxxxxxx> writes: >> I suspect that is a situation that is not so uncommon. Working >> inside a narrow cone of a wide tree, performing a merge would >> hopefully allow many subtrees that are outside of the cones of our >> interest merged without getting expanded at all (e.g. only the other >> side touched these subtrees we are not working on, so their version >> will become the merge result), while changes to some paths in the >> cone of our interest may result in true conflicts represented as >> cache entries at higher stages, needing conflict resolution >> concluded with "git add". Having to expand these subtrees that we >> managed to merge while still collapsed, only because we have >> conflicts in some other parts of the tree, feels somewhat sad. > > You are correct that conflicts outside of the sparse-checkout cone will > cause index expansion. That happens during the 'git merge' command, but > the index will continue to fail to collapse as long as those conflicts > still exist in the index. > > When there are conflicts like this during the merge, then the index > expansion is not as large of a portion of the command as normal, because > the conflict resolution also takes some time to compute. The commands > afterwards do take longer purely because of the expanded index. I was imagining a situation more like "tech-writers only have Documentation/ inside the cone of interest, attempt a pull from somebody else, have conflicts inside Documentation/, but everything else could be resolved cleanly without expanding the index". If the puller's tree is based on the pristine upstream release tag, and the pullee's tree is based on a slightly newer version of upstream snapshot, everything that happened outside Documentation/ in their trees would fast-forward, so such a merge wouldn't have to expand directories like "builtin/" or "contrib/" in the index and instead can merge at the tree level, right? On the other hand, ... > However, this state is also not as common as you might think. If a user > has a sparse-checkout cone specified, then they are unlikely to change > files outside of the sparse-checkout cone. They would not be the reason > that those files have a conflict. The conflicts would exist only if they > are merging branches that had conflicts outside of the cone. Typically, > any merge of external changes like this are of the form of "git pull" or > "git rebase", in which case the conflicts are still "local" to the > developer's changes. ... you seem to be talking about the opposite case (e.g. in the above paragraph), where a conflict happens outside the cone of interest of the person who is making a merge. So, I am a bit puzzled. > You are right that there is additional work that could be done here, > specifically allowing the cache tree to partially succeed and use the > successfully generated trees to create sparse directory entries where > possible. This was not viable before because we lacked the "partially > expanded" index state. This series establishes the necessary vocabulary to > do such an improvement later. >> By the way, why are we passing the "--missing-ok" option to "git >> write-tree" here? >> >>> + cache_tree_update(istate, WRITE_TREE_MISSING_OK); >> >> The same question here. We didn't say "missing trees are OK". What >> made it OK in this change? > > Both of these additions of WRITE_TREE_MISSING_OK are not needed. I > think I added them in an earlier version, thinking they were needed > due to something in the Scalar functional tests. I confirmed just now > that they are not needed for that. I will remove them. > > Thanks, > -Stolee