Re: [PATCH v2 08/10] sparse-index: complete partial expansion
- From
Derrick Stolee <derrickstolee@github.com>
- Date
- May 25, 2022, 14:26 UTC
- Message-ID
- <f0327fd6-f2b3-64b6-3a34-2a7bbad20a01@github.com>
- In-Reply-To
- <xmqqv8tvlvao.fsf@gitster.g>
On 5/23/2022 6:48 PM, Junio C Hamano wrote:
Show 50 quoted lines
> Derrick Stolee <derrickstolee@github.com> 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.
Hm. We must be getting mixed up with each other. Let me try again from the beginning.
When the conflict happens inside of the sparse-checkout cone, then the sparse index is not expanded. This is checked by the test 'sparse-index is not expanded: merge conflict in cone' in t1092.
Most merges get to "fast forward" changes that are outside of the sparse-checkout cone because the only interesting changes that could lead to a conflict are those created by the current user (and hence within the sparse-checkout cone).
So, the typical case of a tech writer only editing "Documentation/" should only see conflicts within "Documentation/".
The case where we would see conflicts outside of the cone include cases where long-lived branches are being merged by someone with a small cone. I can imagine an automated process using an empty sparse-checkout cone to occasionally merge a "deployed" and a "develop" branch, and it gets conflicts when someone ships a hotfix directly to "deployed" without first going through "develop". Any conflict is likely to cause index expansion in this case.
Let's re-introduce the patch section we are talking about:
+ if (pl && !pl->use_cone_patterns) {
pl = NULL;
+ } else {
+ /*
+ * We might contract file entries into sparse-directory
+ * entries, and for that we will need the cache tree to
+ * be recomputed.
+ */
+ cache_tree_free(&istate->cache_tree);
+
+ /*
+ * If there is a problem creating the cache tree, then we
+ * need to expand to a full index since we cannot satisfy
+ * the current request as a sparse index.
+ */
+ if (cache_tree_update(istate, WRITE_TREE_MISSING_OK))
+ pl = NULL;
+ }If a user is in a conflict state and modifies their sparse-checkout cone, then we will hit this "recompute the cache-tree" state, fail, and cause full index expansion. I think that combination (have a conflict AND modify sparse-checkout cone) is rare enough to not optimize for (yet).
Does that make the situation more clear?
Thanks, -Stolee