git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 01/24] dir.c: optionally compute sha-1 of a .gitignore file

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 8, 2015, 08:55 UTC
Message-ID
<1423385748-19825-2-git-send-email-pclouds@gmail.com>
In-Reply-To
<1423385748-19825-1-git-send-email-pclouds@gmail.com>

This is not used anywhere yet. But the goal is to compare quickly if a .gitignore file has changed when we have the SHA-1 of both old (cached somewhere) and new (from index or a tree) versions.

Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 dir.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
 dir.h |  6 ++++++
 2 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/dir.c b/dir.c
index fcb6872..4cc936b 100644
--- a/dir.c
+++ b/dir.c
@@ -466,7 +466,8 @@ void add_exclude(const char *string, const char *base,
 	x->el = el;
 }
 
-static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
+static void *read_skip_worktree_file_from_index(const char *path, size_t *size,
+						struct sha1_stat *sha1_stat)
 {
 	int pos, len;
 	unsigned long sz;
@@ -485,6 +486,10 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
 		return NULL;
 	}
 	*size = xsize_t(sz);
+	if (sha1_stat) {
+		memset(&sha1_stat->stat, 0, sizeof(sha1_stat->stat));
+		hashcpy(sha1_stat->sha1, active_cache[pos]->sha1);
+	}
 	return data;
 }
 
@@ -529,11 +534,18 @@ static void trim_trailing_spaces(char *buf)
 		*last_space = '\0';
 }
 
-int add_excludes_from_file_to_list(const char *fname,
-				   const char *base,
-				   int baselen,
-				   struct exclude_list *el,
-				   int check_index)
+/*
+ * Given a file with name "fname", read it (either from disk, or from
+ * the index if "check_index" is non-zero), parse it and store the
+ * exclude rules in "el".
+ *
+ * If "ss" is not NULL, compute SHA-1 of the exclude file and fill
+ * stat data from disk (only valid if add_excludes returns zero). If
+ * ss_valid is non-zero, "ss" must contain good value as input.
+ */
+static int add_excludes(const char *fname, const char *base, int baselen,
+			struct exclude_list *el, int check_index,
+			struct sha1_stat *sha1_stat)
 {
 	struct stat st;
 	int fd, i, lineno = 1;
@@ -547,7 +559,7 @@ int add_excludes_from_file_to_list(const char *fname,
 		if (0 <= fd)
 			close(fd);
 		if (!check_index ||
-		    (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL)
+		    (buf = read_skip_worktree_file_from_index(fname, &size, sha1_stat)) == NULL)
 			return -1;
 		if (size == 0) {
 			free(buf);
@@ -560,6 +572,11 @@ int add_excludes_from_file_to_list(const char *fname,
 	} else {
 		size = xsize_t(st.st_size);
 		if (size == 0) {
+			if (sha1_stat) {
+				fill_stat_data(&sha1_stat->stat, &st);
+				hashcpy(sha1_stat->sha1, EMPTY_BLOB_SHA1_BIN);
+				sha1_stat->valid = 1;
+			}
 			close(fd);
 			return 0;
 		}
@@ -571,6 +588,21 @@ int add_excludes_from_file_to_list(const char *fname,
 		}
 		buf[size++] = '\n';
 		close(fd);
+		if (sha1_stat) {
+			int pos;
+			if (sha1_stat->valid &&
+			    !match_stat_data(&sha1_stat->stat, &st))
+				; /* no content change, ss->sha1 still good */
+			else if (check_index &&
+				 (pos = cache_name_pos(fname, strlen(fname))) >= 0 &&
+				 !ce_stage(active_cache[pos]) &&
+				 ce_uptodate(active_cache[pos]))
+				hashcpy(sha1_stat->sha1, active_cache[pos]->sha1);
+			else
+				hash_sha1_file(buf, size, "blob", sha1_stat->sha1);
+			fill_stat_data(&sha1_stat->stat, &st);
+			sha1_stat->valid = 1;
+		}
 	}
 
 	el->filebuf = buf;
@@ -589,6 +621,13 @@ int add_excludes_from_file_to_list(const char *fname,
 	return 0;
 }
 
+int add_excludes_from_file_to_list(const char *fname, const char *base,
+				   int baselen, struct exclude_list *el,
+				   int check_index)
+{
+	return add_excludes(fname, base, baselen, el, check_index, NULL);
+}
+
 struct exclude_list *add_exclude_list(struct dir_struct *dir,
 				      int group_type, const char *src)
 {
diff --git a/dir.h b/dir.h
index 6c45e9d..cdca71b 100644
--- a/dir.h
+++ b/dir.h
@@ -73,6 +73,12 @@ struct exclude_list_group {
 	struct exclude_list *el;
 };
 
+struct sha1_stat {
+	struct stat_data stat;
+	unsigned char sha1[20];
+	int valid;
+};
+
 struct dir_struct {
 	int nr, alloc;
 	int ignored_nr, ignored_alloc;
-- 
2.3.0.rc1.137.g477eb31
Previous: Nguyễn Thái Ngọc DuyNext: Junio C Hamano
Message 2 of 30 in “nd/untracked-cache updates”
  1. 00/24 nd/untracked-cache updatesNguyễn Thái Ngọc Duy, Feb 8, 2015
  2. 01/24 dir.c: optionally compute sha-1 of a .gitignore fileNguyễn Thái Ngọc Duy, Feb 8, 2015
  3. Junio C HamanoFeb 11, 2015
  4. Duy NguyenFeb 16, 2015
  5. Junio C HamanoFeb 16, 2015
  6. 02/24 untracked cache: record .gitignore information and dir hierarchyNguyễn Thái Ngọc Duy, Feb 8, 2015
  7. 03/24 untracked cache: initial untracked cache validationNguyễn Thái Ngọc Duy, Feb 8, 2015
  8. 04/24 untracked cache: invalidate dirs recursively if .gitignore changesNguyễn Thái Ngọc Duy, Feb 8, 2015
  9. 05/24 untracked cache: make a wrapper around {open,read,close}dir()Nguyễn Thái Ngọc Duy, Feb 8, 2015
  10. 06/24 untracked cache: record/validate dir mtime and reuse cached outputNguyễn Thái Ngọc Duy, Feb 8, 2015
  11. 07/24 untracked cache: mark what dirs should be recursed/savedNguyễn Thái Ngọc Duy, Feb 8, 2015
  12. 08/24 untracked cache: don't open non-existent .gitignoreNguyễn Thái Ngọc Duy, Feb 8, 2015
  13. 09/24 ewah: add convenient wrapper ewah_serialize_strbuf()Nguyễn Thái Ngọc Duy, Feb 8, 2015
  14. 10/24 untracked cache: save to an index extensionNguyễn Thái Ngọc Duy, Feb 8, 2015
  15. Stefan BellerMar 7, 2015
  16. 11/24 untracked cache: load from UNTR index extensionNguyễn Thái Ngọc Duy, Feb 8, 2015
  17. Junio C HamanoFeb 9, 2015
  18. 12/24 untracked cache: invalidate at index addition or removalNguyễn Thái Ngọc Duy, Feb 8, 2015
  19. 13/24 read-cache.c: split racy stat test to a separate functionNguyễn Thái Ngọc Duy, Feb 8, 2015
  20. 14/24 untracked cache: avoid racy timestampsNguyễn Thái Ngọc Duy, Feb 8, 2015
  21. 15/24 untracked cache: print stats with $GIT_TRACE_UNTRACKED_STATSNguyễn Thái Ngọc Duy, Feb 8, 2015
  22. 16/24 untracked cache: mark index dirty if untracked cache is updatedNguyễn Thái Ngọc Duy, Feb 8, 2015
  23. 17/24 untracked-cache: temporarily disable with $GIT_DISABLE_UNTRACKED_CACHENguyễn Thái Ngọc Duy, Feb 8, 2015
  24. 18/24 status: enable untracked cacheNguyễn Thái Ngọc Duy, Feb 8, 2015
  25. 19/24 update-index: manually enable or disable untracked cacheNguyễn Thái Ngọc Duy, Feb 8, 2015
  26. 20/24 update-index: test the system before enabling untracked cacheNguyễn Thái Ngọc Duy, Feb 8, 2015
  27. 21/24 t7063: tests for untracked cacheNguyễn Thái Ngọc Duy, Feb 8, 2015
  28. 22/24 mingw32: add uname()Nguyễn Thái Ngọc Duy, Feb 8, 2015
  29. 23/24 untracked cache: guard and disable on system changesNguyễn Thái Ngọc Duy, Feb 8, 2015
  30. 24/24 git-status.txt: advertisement for untracked cacheNguyễn Thái Ngọc Duy, Feb 8, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.