Inter-revision diff: patch 7

Comparing v2 (message) to v8 (message)

--- v2
+++ v8
@@ -1,114 +1,66 @@
 From: Derrick Stolee <dstolee@microsoft.com>
 
-By testing 'git -c core.fsmonitor= status -uno', we can check for the
-simplest index operations that can be made sparse-aware. The necessary
-implementation details are already integrated with sparse-checkout, so
-modify command_requires_full_index to be zero for cmd_status().
+As we further integrate the sparse-index into unpack-trees, we need to
+ensure that we compare sparse directory entries correctly with other
+entries. This affects searching for an exact path as well as sorting
+index entries.
 
-In refresh_index(), we loop through the index entries to refresh their
-stat() information. However, sparse directories have no stat()
-information to populate. Ignore these entries.
+Sparse directory entries contain the trailing directory separator. This
+is important for the sorting, in particular. Thus, within
+do_compare_entry() we stop using S_IFREG in all cases, since sparse
+directories should use S_IFDIR to indicate that the comparison should
+treat the entry name as a dirctory.
 
-This allows 'git status' to no longer expand a sparse index to a full
-one. This is further tested by dropping the "-uno" option and adding an
-untracked file into the worktree.
-
-The performance test p2000-sparse-checkout-operations.sh demonstrates
-these improvements:
-
-Test                                  HEAD~1           HEAD
------------------------------------------------------------------------------
-2000.2: git status (full-index-v3)    0.31(0.30+0.05)  0.31(0.29+0.06) +0.0%
-2000.3: git status (full-index-v4)    0.31(0.29+0.07)  0.34(0.30+0.08) +9.7%
-2000.4: git status (sparse-index-v3)  2.35(2.28+0.10)  0.04(0.04+0.05) -98.3%
-2000.5: git status (sparse-index-v4)  2.35(2.24+0.15)  0.05(0.04+0.06) -97.9%
-
-Note that since HEAD~1 was expanding the sparse index by parsing trees,
-it was artificially slower than the full index case. Thus, the 98%
-improvement is misleading, and instead we should celebrate the 0.34s to
-0.05s improvement of 85%. This is more indicative of the peformance
-gains we are expecting by using a sparse index.
-
-Note: we are dropping the assignment of core.fsmonitor here. This is not
-necessary for the test script as we are not altering the config any
-other way. Correct integration with FS Monitor will be validated in
-later changes.
+Within compare_entry(), it first calls do_compare_entry() to check the
+leading portion of the name. When the input path is a directory name, we
+could match exactly already. Thus, we should return 0 if we have an
+exact string match on a sparse directory entry. The final check is a
+length comparison between the strings.
 
 Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
 ---
- builtin/commit.c                         |  3 +++
- read-cache.c                             | 10 ++++++++--
- t/t1092-sparse-checkout-compatibility.sh | 13 +++++++++----
- 3 files changed, 20 insertions(+), 6 deletions(-)
+ unpack-trees.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
 
-diff --git a/builtin/commit.c b/builtin/commit.c
-index cf0c36d1dcb2..e529da7beadd 100644
---- a/builtin/commit.c
-+++ b/builtin/commit.c
-@@ -1404,6 +1404,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
- 	if (argc == 2 && !strcmp(argv[1], "-h"))
- 		usage_with_options(builtin_status_usage, builtin_status_options);
+diff --git a/unpack-trees.c b/unpack-trees.c
+index 87c1ed204c8..b113cc750f2 100644
+--- a/unpack-trees.c
++++ b/unpack-trees.c
+@@ -983,6 +983,7 @@ static int do_compare_entry(const struct cache_entry *ce,
+ 	int pathlen, ce_len;
+ 	const char *ce_name;
+ 	int cmp;
++	unsigned ce_mode;
  
-+	prepare_repo_settings(the_repository);
-+	the_repository->settings.command_requires_full_index = 0;
+ 	/*
+ 	 * If we have not precomputed the traverse path, it is quicker
+@@ -1005,7 +1006,8 @@ static int do_compare_entry(const struct cache_entry *ce,
+ 	ce_len -= pathlen;
+ 	ce_name = ce->name + pathlen;
+ 
+-	return df_name_compare(ce_name, ce_len, S_IFREG, name, namelen, mode);
++	ce_mode = S_ISSPARSEDIR(ce->ce_mode) ? S_IFDIR : S_IFREG;
++	return df_name_compare(ce_name, ce_len, ce_mode, name, namelen, mode);
+ }
+ 
+ static int compare_entry(const struct cache_entry *ce, const struct traverse_info *info, const struct name_entry *n)
+@@ -1014,6 +1016,16 @@ static int compare_entry(const struct cache_entry *ce, const struct traverse_inf
+ 	if (cmp)
+ 		return cmp;
+ 
++	/*
++	 * At this point, we know that we have a prefix match. If ce
++	 * is a sparse directory, then allow an exact match. This only
++	 * works when the input name is a directory, since ce->name
++	 * ends in a directory separator.
++	 */
++	if (S_ISSPARSEDIR(ce->ce_mode) &&
++	    ce->ce_namelen == traverse_path_len(info, tree_entry_len(n)) + 1)
++		return 0;
 +
- 	status_init_config(&s, git_status_config);
- 	argc = parse_options(argc, argv, prefix,
- 			     builtin_status_options,
-diff --git a/read-cache.c b/read-cache.c
-index 29ffa9ac5db9..f80e26831b36 100644
---- a/read-cache.c
-+++ b/read-cache.c
-@@ -1578,8 +1578,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
- 	 */
- 	preload_index(istate, pathspec, 0);
- 	trace2_region_enter("index", "refresh", NULL);
--	/* TODO: audit for interaction with sparse-index. */
--	ensure_full_index(istate);
-+
- 	for (i = 0; i < istate->cache_nr; i++) {
- 		struct cache_entry *ce, *new_entry;
- 		int cache_errno = 0;
-@@ -1594,6 +1593,13 @@ int refresh_index(struct index_state *istate, unsigned int flags,
- 		if (ignore_skip_worktree && ce_skip_worktree(ce))
- 			continue;
- 
-+		/*
-+		 * If this entry is a sparse directory, then there isn't
-+		 * any stat() information to update. Ignore the entry.
-+		 */
-+		if (S_ISSPARSEDIR(ce->ce_mode))
-+			continue;
-+
- 		if (pathspec && !ce_path_match(istate, ce, pathspec, seen))
- 			filtered = 1;
- 
-diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
-index 0dc551b25f67..5a8fe88dc894 100755
---- a/t/t1092-sparse-checkout-compatibility.sh
-+++ b/t/t1092-sparse-checkout-compatibility.sh
-@@ -453,12 +453,17 @@ test_expect_success 'sparse-index is expanded and converted back' '
- 	GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
- 		git -C sparse-index -c core.fsmonitor="" reset --hard &&
- 	test_region index convert_to_sparse trace2.txt &&
--	test_region index ensure_full_index trace2.txt &&
-+	test_region index ensure_full_index trace2.txt
-+'
- 
--	rm trace2.txt &&
-+test_expect_success 'sparse-index is not expanded' '
-+	init_repos &&
-+
-+	rm -f trace2.txt &&
-+	echo >>sparse-index/untracked.txt &&
- 	GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
--		git -C sparse-index -c core.fsmonitor="" status -uno &&
--	test_region index ensure_full_index trace2.txt
-+		git -C sparse-index status &&
-+	test_region ! index ensure_full_index trace2.txt
- '
- 
- test_done
+ 	/*
+ 	 * Even if the beginning compared identically, the ce should
+ 	 * compare as bigger than a directory leading up to it!
 -- 
 gitgitgadget
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help