git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>,
	skillzero@gmail.com
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH nd/sparse] Support directory exclusion from index
Date: Sat, 31 Oct 2009 21:09:23 +0700	[thread overview]
Message-ID: <1256998163-979-1-git-send-email-pclouds@gmail.com> (raw)

The function excluded_from_list (or its public API excluded) is
currently used to mark what entry is included in sparse checkout.
Because index does not have directories, the pattern "foo", while
would match directory "foo" on working directory, would not match
against index.

To overcome this, if a pattern does not match, check if it matches
parent directories too before moving on to the next pattern. This
behavior only applies to index matching.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 There is subtle difference, which might break things. When working
 with file system, it checks top-down, parent directories first.
 I do bottom-up.

 If/you/have/deep/directories sparse checkout may become slow.

 And my test broke :(

 dir.c                                |   24 ++++++++++++++++++++++--
 t/t1009-read-tree-sparse-checkout.sh |    4 ++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/dir.c b/dir.c
index 3a8d3e6..82227e5 100644
--- a/dir.c
+++ b/dir.c
@@ -334,13 +334,15 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 }
 
 /* Scan the list and let the last match determine the fate.
+ * dtype == NULL means matching against index, not working directory.
  * Return 1 for exclude, 0 for include and -1 for undecided.
  */
-int excluded_from_list(const char *pathname,
-		       int pathlen, const char *basename, int *dtype,
+int excluded_from_list(const char *pathname_,
+		       int pathlen_, const char *basename_, int *dtype,
 		       struct exclude_list *el)
 {
 	int i;
+	char buf[PATH_MAX];
 
 	if (el->nr) {
 		for (i = el->nr - 1; 0 <= i; i--) {
@@ -348,6 +350,11 @@ int excluded_from_list(const char *pathname,
 			const char *exclude = x->pattern;
 			int to_exclude = x->to_exclude;
 
+			const char *pathname = pathname_;
+			const char *basename = basename_;
+			int pathlen = pathlen_;
+
+recheck:
 			if (x->flags & EXC_FLAG_MUSTBEDIR) {
 				if (!dtype) {
 					if (!prefixcmp(pathname, exclude))
@@ -398,6 +405,19 @@ int excluded_from_list(const char *pathname,
 					    return to_exclude;
 				}
 			}
+
+			if (!dtype) { /* matching against index */
+				basename = strrchr(pathname, '/');
+				if (basename) {
+					pathlen = basename-pathname;
+					memcpy(buf, pathname, pathlen);
+					buf[pathlen] = '\0';
+					pathname = buf;
+					basename = strrchr(pathname, '/');
+					basename = (basename) ? basename+1 : pathname;
+					goto recheck;
+				}
+			}
 		}
 	}
 	return -1; /* undecided */
diff --git a/t/t1009-read-tree-sparse-checkout.sh b/t/t1009-read-tree-sparse-checkout.sh
index 62246db..b57d237 100755
--- a/t/t1009-read-tree-sparse-checkout.sh
+++ b/t/t1009-read-tree-sparse-checkout.sh
@@ -84,13 +84,13 @@ cat >expected.swt <<EOF
 H init.t
 H sub/added
 EOF
-test_expect_failure 'match directories without trailing slash' '
+test_expect_success 'match directories without trailing slash' '
 	echo init.t > .git/info/sparse-checkout &&
 	echo sub >> .git/info/sparse-checkout &&
 	git read-tree -m -u HEAD &&
 	git ls-files -t > result &&
 	test_cmp expected.swt result &&
-	test ! -f init.t &&
+	test -f init.t &&
 	test -f sub/added
 '
 
-- 
1.6.5.2.216.g9c1ec

                 reply	other threads:[~2009-10-31 14:09 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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

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

  git send-email \
    --in-reply-to=1256998163-979-1-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=skillzero@gmail.com \
    /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.
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 NNTP newsgroup(s).