git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Brandon Williams <bmwill@google.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, j6t@kdbg.org, Brandon Williams <bmwill@google.com>
Subject: [PATCH v2 4/6] ls-files: prevent prune_cache from overeagerly pruning submodules
Date: Thu, 11 May 2017 15:04:25 -0700	[thread overview]
Message-ID: <20170511220427.192627-5-bmwill@google.com> (raw)
In-Reply-To: <20170511220427.192627-1-bmwill@google.com>

Since (ae8d08242 pathspec: pass directory indicator to
match_pathspec_item()) the path matching logic has been able to cope
with submodules without needing to strip off a trailing slash if a path
refers to a submodule.

ls-files is the only caller of 'parse_pathspec()' which relies on the
behavior of the PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP flag because it
uses the result to construct a common prefix of all provided pathspecs
which is then used to prune the index of all entries which don't have
that prefix.  Since submodules entries in the index don't have a
trailing slash 'prune_cache()' will be overeager and prune a submodule
'sub' if the common prefix is 'sub/'.  To correct this behavior, only
prune entries which don't match up to, but not including, a trailing
slash of the common prefix.

This is in preparation to remove the
PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP flag in a later patch.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 builtin/ls-files.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index a6c70dbe9..1f3d47844 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -97,7 +97,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
 {
 	int len = max_prefix_len;
 
-	if (len >= ent->len)
+	if (len > ent->len)
 		die("git ls-files: internal error - directory entry not superset of prefix");
 
 	if (!dir_path_match(ent, &pathspec, len, ps_matched))
@@ -238,7 +238,7 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 		strbuf_addstr(&name, super_prefix);
 	strbuf_addstr(&name, ce->name);
 
-	if (len >= ce_namelen(ce))
+	if (len > ce_namelen(ce))
 		die("git ls-files: internal error - cache entry not superset of prefix");
 
 	if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
@@ -403,6 +403,25 @@ static void prune_cache(const char *prefix, size_t prefixlen)
 	active_nr = last - pos;
 }
 
+static int get_common_prefix_len(const char *common_prefix)
+{
+	int common_prefix_len;
+
+	if (!common_prefix)
+		return 0;
+
+	common_prefix_len = strlen(common_prefix);
+
+	/*
+	 * If the prefix has a trailing slash, strip it so that submodules wont
+	 * be pruned from the index.
+	 */
+	if (common_prefix[common_prefix_len - 1] == '/')
+		common_prefix_len--;
+
+	return common_prefix_len;
+}
+
 /*
  * Read the tree specified with --with-tree option
  * (typically, HEAD) into stage #1 and then
@@ -624,8 +643,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 		    "--error-unmatch");
 
 	parse_pathspec(&pathspec, 0,
-		       PATHSPEC_PREFER_CWD |
-		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
+		       PATHSPEC_PREFER_CWD,
 		       prefix, argv);
 
 	/*
@@ -637,7 +655,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 		max_prefix = NULL;
 	else
 		max_prefix = common_prefix(&pathspec);
-	max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
+	max_prefix_len = get_common_prefix_len(max_prefix);
+
+	prune_cache(max_prefix, max_prefix_len);
 
 	/* Treat unmatching pathspec elements as errors */
 	if (pathspec.nr && error_unmatch)
@@ -651,7 +671,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 	      show_killed || show_modified || show_resolve_undo))
 		show_cached = 1;
 
-	prune_cache(max_prefix, max_prefix_len);
 	if (with_tree) {
 		/*
 		 * Basic sanity check; show-stages and show-unmerged
-- 
2.13.0.rc2.291.g57267f2277-goog


  parent reply	other threads:[~2017-05-11 22:04 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-09 19:17 [PATCH 0/8] convert pathspec.c to take an index parameter Brandon Williams
2017-05-09 19:17 ` [PATCH 1/8] pathspec: provide a more descriptive die message Brandon Williams
2017-05-09 19:17 ` [PATCH 2/8] submodule: add die_in_unpopulated_submodule function Brandon Williams
2017-05-09 19:18 ` [PATCH 3/8] pathspec: change PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE flag Brandon Williams
2017-05-10  5:52   ` Junio C Hamano
2017-05-10 16:16     ` Brandon Williams
2017-05-09 19:18 ` [PATCH 4/8] pathspec: rename PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP Brandon Williams
2017-05-10  5:53   ` Junio C Hamano
2017-05-09 19:18 ` [PATCH 5/8] pathspec: convert strip_submodule_slash to take an index Brandon Williams
2017-05-10  5:55   ` Junio C Hamano
2017-05-09 19:18 ` [PATCH 6/8] pathspec: convert find_pathspecs_matching_against_index " Brandon Williams
2017-05-09 19:18 ` [PATCH 7/8] pathspec: convert init_pathspec_item " Brandon Williams
2017-05-09 19:18 ` [PATCH 8/8] pathspec: convert parse_pathspec " Brandon Williams
2017-05-10  6:04   ` Junio C Hamano
2017-05-10 17:02     ` Brandon Williams
2017-05-11  1:48       ` Junio C Hamano
2017-05-11  5:04         ` Johannes Sixt
2017-05-11  5:13           ` Junio C Hamano
2017-05-11 17:36         ` Brandon Williams
2017-05-12  0:54           ` Junio C Hamano
2017-05-11 22:04 ` [PATCH v2 0/6] convert pathspec.c to take an index parameter Brandon Williams
2017-05-11 22:04   ` [PATCH v2 1/6] pathspec: provide a more descriptive die message Brandon Williams
2017-05-11 22:04   ` [PATCH v2 2/6] submodule: add die_in_unpopulated_submodule function Brandon Williams
2017-05-11 22:04   ` [PATCH v2 3/6] pathspec: remove PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE flag Brandon Williams
2017-05-11 22:04   ` Brandon Williams [this message]
2017-05-11 22:04   ` [PATCH v2 5/6] pathspec: remove PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP Brandon Williams
2017-05-11 22:04   ` [PATCH v2 6/6] pathspec: convert find_pathspecs_matching_against_index to take an index Brandon Williams
2017-05-12  5:27   ` [PATCH v2 0/6] convert pathspec.c to take an index parameter Junio C Hamano
2017-05-12 17:29     ` Brandon Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170511220427.192627-5-bmwill@google.com \
    --to=bmwill@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).