All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 03/20] prep_exclude: remove the artificial PATH_MAX limit
Date: Wed,  7 May 2014 21:51:43 +0700	[thread overview]
Message-ID: <1399474320-6840-4-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1399474320-6840-1-git-send-email-pclouds@gmail.com>

This also fixes the problem of silently ignoring .gitignore if the
full path exceeds PATH_MAX. Now add_excludes_from_file() will report
if it gets ENAMETOOLONG.
---
 dir.c | 47 ++++++++++++++++++++++++++++-------------------
 dir.h |  2 +-
 2 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/dir.c b/dir.c
index 7a83f70..c081754 100644
--- a/dir.c
+++ b/dir.c
@@ -795,12 +795,12 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 	 */
 	while ((stk = dir->exclude_stack) != NULL) {
 		if (stk->baselen <= baselen &&
-		    !strncmp(dir->basebuf, base, stk->baselen))
+		    !strncmp(dir->basebuf.buf, base, stk->baselen))
 			break;
 		el = &group->el[dir->exclude_stack->exclude_ix];
 		dir->exclude_stack = stk->prev;
 		dir->exclude = NULL;
-		free((char *)el->src); /* see strdup() below */
+		free((char *)el->src); /* see strbuf_detach() below */
 		clear_exclude_list(el);
 		free(stk);
 		group->nr--;
@@ -810,8 +810,17 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 	if (dir->exclude)
 		return;
 
+	/*
+	 * Lazy initialization. All call sites currently just
+	 * memset(dir, 0, sizeof(*dir)) before use. Changing all of
+	 * them seems lots of work for little benefit.
+	 */
+	if (!dir->basebuf.alloc)
+		strbuf_init(&dir->basebuf, PATH_MAX);
+
 	/* Read from the parent directories and push them down. */
 	current = stk ? stk->baselen : -1;
+	strbuf_setlen(&dir->basebuf, current < 0 ? 0 : current);
 	while (current < baselen) {
 		struct exclude_stack *stk = xcalloc(1, sizeof(*stk));
 		const char *cp;
@@ -829,48 +838,47 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 		stk->baselen = cp - base;
 		stk->exclude_ix = group->nr;
 		el = add_exclude_list(dir, EXC_DIRS, NULL);
-		memcpy(dir->basebuf + current, base + current,
-		       stk->baselen - current);
+		strbuf_add(&dir->basebuf, base + current, stk->baselen - current);
+		assert(stk->baselen == dir->basebuf.len);
 
 		/* Abort if the directory is excluded */
 		if (stk->baselen) {
 			int dt = DT_DIR;
-			dir->basebuf[stk->baselen - 1] = 0;
+			dir->basebuf.buf[stk->baselen - 1] = 0;
 			dir->exclude = last_exclude_matching_from_lists(dir,
-				dir->basebuf, stk->baselen - 1,
-				dir->basebuf + current, &dt);
-			dir->basebuf[stk->baselen - 1] = '/';
+				dir->basebuf.buf, stk->baselen - 1,
+				dir->basebuf.buf + current, &dt);
+			dir->basebuf.buf[stk->baselen - 1] = '/';
 			if (dir->exclude &&
 			    dir->exclude->flags & EXC_FLAG_NEGATIVE)
 				dir->exclude = NULL;
 			if (dir->exclude) {
-				dir->basebuf[stk->baselen] = 0;
 				dir->exclude_stack = stk;
 				return;
 			}
 		}
 
-		/* Try to read per-directory file unless path is too long */
-		if (dir->exclude_per_dir &&
-		    stk->baselen + strlen(dir->exclude_per_dir) < PATH_MAX) {
-			strcpy(dir->basebuf + stk->baselen,
-					dir->exclude_per_dir);
+		/* Try to read per-directory file */
+		if (dir->exclude_per_dir) {
 			/*
 			 * dir->basebuf gets reused by the traversal, but we
 			 * need fname to remain unchanged to ensure the src
 			 * member of each struct exclude correctly
 			 * back-references its source file.  Other invocations
 			 * of add_exclude_list provide stable strings, so we
-			 * strdup() and free() here in the caller.
+			 * strbuf_detach() and free() here in the caller.
 			 */
-			el->src = strdup(dir->basebuf);
-			add_excludes_from_file_to_list(dir->basebuf,
-					dir->basebuf, stk->baselen, el, 1);
+			struct strbuf sb = STRBUF_INIT;
+			strbuf_addbuf(&sb, &dir->basebuf);
+			strbuf_addstr(&sb, dir->exclude_per_dir);
+			el->src = strbuf_detach(&sb, NULL);
+			add_excludes_from_file_to_list(el->src, el->src,
+						       stk->baselen, el, 1);
 		}
 		dir->exclude_stack = stk;
 		current = stk->baselen;
 	}
-	dir->basebuf[baselen] = '\0';
+	strbuf_setlen(&dir->basebuf, baselen);
 }
 
 /*
@@ -1668,4 +1676,5 @@ void clear_directory(struct dir_struct *dir)
 		free(stk);
 		stk = prev;
 	}
+	strbuf_release(&dir->basebuf);
 }
diff --git a/dir.h b/dir.h
index 02e3710..6c45e9d 100644
--- a/dir.h
+++ b/dir.h
@@ -119,7 +119,7 @@ struct dir_struct {
 	 */
 	struct exclude_stack *exclude_stack;
 	struct exclude *exclude;
-	char basebuf[PATH_MAX];
+	struct strbuf basebuf;
 };
 
 /*
-- 
1.9.1.346.ga2b5940

  parent reply	other threads:[~2014-05-07 14:52 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-07 14:51 [PATCH 00/20] Untracked cache to speed up "git status" Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 01/20] dir.c: coding style fix Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 02/20] dir.h: move struct exclude declaration to top level Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` Nguyễn Thái Ngọc Duy [this message]
2014-05-07 14:51 ` [PATCH 04/20] dir.c: optionally compute sha-1 of a .gitignore file Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 05/20] untracked cache: record .gitignore information and dir hierarchy Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 06/20] untracked cache: initial untracked cache validation Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 07/20] untracked cache: invalidate dirs recursively if .gitignore changes Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 08/20] untracked cache: record/validate dir mtime and reuse cached output Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 09/20] untracked cache: mark what dirs should be recursed/saved Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 10/20] untracked cache: don't open non-existent .gitignore Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 11/20] untracked cache: save to an index extension Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 12/20] untracked cache: load from UNTR " Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 13/20] untracked cache: invalidate at index addition or removal Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 14/20] untracked cache: print untracked statistics with $GIT_TRACE_UNTRACKED Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 15/20] read-cache.c: split racy stat test to a separate function Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 16/20] untracked cache: avoid racy timestamps Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 17/20] status: support untracked cache Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 18/20] update-index: manually enable or disable " Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 19/20] update-index: test the system before enabling " Nguyễn Thái Ngọc Duy
2014-05-07 14:52 ` [PATCH 20/20] t7063: tests for " Nguyễn Thái Ngọc Duy

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=1399474320-6840-4-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.