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

[PATCH 18/19] update-index: test the system before enabling untracked cache

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Oct 27, 2014, 12:10 UTC
Message-ID
<1414411846-4450-19-git-send-email-pclouds@gmail.com>
In-Reply-To
<1414411846-4450-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-update-index.txt |   6 ++
 builtin/update-index.c             | 146 +++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+)
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 16f2686..fab1fea 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -180,6 +180,12 @@ may not support it yet.
 	system must change `st_mtime` field of a directory if files
 	are added or deleted in that directory.
 
+--force-untracked-cache::
+	For safety, `--untracked-cache` performs tests on the working
+	directory to make sure untracked cache can be used. These
+	tests can take a few seconds. `--force-untracked-cache` can be
+	used to skip the tests.
+
 \--::
 	Do not interpret any more arguments as options.
 
diff --git a/builtin/update-index.c b/builtin/update-index.c
index e57e2d7..471c0b4 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -48,6 +48,145 @@ static void report(const char *fmt, ...)
 	va_end(vp);
 }
 
+static void remove_test_directory(void)
+{
+	struct strbuf sb = STRBUF_INIT;
+	strbuf_addstr(&sb, "dir-mtime-test");
+	remove_dir_recursively(&sb, 0);
+	strbuf_release(&sb);
+}
+
+static void xmkdir(const char *path)
+{
+	if (mkdir(path, 0700))
+		die_errno(_("failed to create directory %s"), path);
+}
+
+static int xstat(const char *path, struct stat *st)
+{
+	if (stat(path, st))
+		die_errno(_("failed to stat %s"), path);
+	return 0;
+}
+
+static int create_file(const char *path)
+{
+	int fd = open(path, O_CREAT | O_RDWR, 0644);
+	if (fd < 0)
+		die_errno(_("failed to create file %s"), path);
+	return fd;
+}
+
+static void xunlink(const char *path)
+{
+	if (unlink(path))
+		die_errno(_("failed to delete file %s"), path);
+}
+
+static void xrmdir(const char *path)
+{
+	if (rmdir(path))
+		die_errno(_("failed to delete directory %s"), path);
+}
+
+static void avoid_racy(void)
+{
+	/*
+	 * not use if we could usleep(10) if USE_NSEC is defined. The
+	 * field nsec could be there, but the OS could choose to
+	 * ignore it?
+	 */
+	sleep(1);
+}
+
+static int test_if_untracked_cache_is_supported(void)
+{
+	struct stat st;
+	struct stat_data base;
+	int fd;
+
+	fprintf(stderr, _("Testing "));
+	xmkdir("dir-mtime-test");
+	atexit(remove_test_directory);
+	xstat("dir-mtime-test", &st);
+	fill_stat_data(&base, &st);
+	fputc('.', stderr);
+
+	avoid_racy();
+	fd = create_file("dir-mtime-test/newfile");
+	xstat("dir-mtime-test", &st);
+	if (!match_stat_data(&base, &st)) {
+		fputc('\n', stderr);
+		fprintf_ln(stderr,_("directory stat info does not "
+				    "change after adding a new file"));
+		return 0;
+	}
+	fill_stat_data(&base, &st);
+	fputc('.', stderr);
+
+	avoid_racy();
+	xmkdir("dir-mtime-test/new-dir");
+	xstat("dir-mtime-test", &st);
+	if (!match_stat_data(&base, &st)) {
+		fputc('\n', stderr);
+		fprintf_ln(stderr, _("directory stat info does not change "
+				     "after adding a new directory"));
+		return 0;
+	}
+	fill_stat_data(&base, &st);
+	fputc('.', stderr);
+
+	avoid_racy();
+	write_or_die(fd, "data", 4);
+	close(fd);
+	xstat("dir-mtime-test", &st);
+	if (match_stat_data(&base, &st)) {
+		fputc('\n', stderr);
+		fprintf_ln(stderr, _("directory stat info changes "
+				     "after updating a file"));
+		return 0;
+	}
+	fputc('.', stderr);
+
+	avoid_racy();
+	close(create_file("dir-mtime-test/new-dir/new"));
+	xstat("dir-mtime-test", &st);
+	if (match_stat_data(&base, &st)) {
+		fputc('\n', stderr);
+		fprintf_ln(stderr, _("directory stat info changes after "
+				     "adding a file inside subdirectory"));
+		return 0;
+	}
+	fputc('.', stderr);
+
+	avoid_racy();
+	xunlink("dir-mtime-test/newfile");
+	xstat("dir-mtime-test", &st);
+	if (!match_stat_data(&base, &st)) {
+		fputc('\n', stderr);
+		fprintf_ln(stderr, _("directory stat info does not "
+				     "change after deleting a file"));
+		return 0;
+	}
+	fill_stat_data(&base, &st);
+	fputc('.', stderr);
+
+	avoid_racy();
+	xunlink("dir-mtime-test/new-dir/new");
+	xrmdir("dir-mtime-test/new-dir");
+	xstat("dir-mtime-test", &st);
+	if (!match_stat_data(&base, &st)) {
+		fputc('\n', stderr);
+		fprintf_ln(stderr, _("directory stat info does not "
+				     "change after deleting a directory"));
+		return 0;
+	}
+
+	xrmdir("dir-mtime-test");
+	fprintf_ln(stderr, _(" OK"));
+	return 1;
+}
+
 static int mark_ce_flags(const char *path, int flag, int mark)
 {
 	int namelen = strlen(path);
@@ -835,6 +974,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 			N_("enable or disable split index")),
 		OPT_BOOL(0, "untracked-cache", &untracked_cache,
 			N_("enable/disable untracked cache")),
+		OPT_SET_INT(0, "force-untracked-cache", &untracked_cache,
+			    N_("enable untracked cache without testing the filesystem"), 2),
 		OPT_END()
 	};
 
@@ -944,6 +1085,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 	if (untracked_cache > 0 && !the_index.untracked) {
 		struct untracked_cache *uc;
 
+		if (untracked_cache < 2) {
+			setup_work_tree();
+			if (!test_if_untracked_cache_is_supported())
+				return 1;
+		}
 		uc = xcalloc(1, sizeof(*uc));
 		uc->exclude_per_dir = ".gitignore";
 		/* should be the same flags used by git-status */
-- 
2.1.0.rc0.78.gc0d8480
Previous: Nguyễn Thái Ngọc DuyNext: Torsten Bögershausen
Message 25 of 65 in “Untracked cache to speed up "git status"”
  1. 00/19 Untracked cache to speed up "git status"Nguyễn Thái Ngọc Duy, Oct 27, 2014
  2. 01/19 dir.c: optionally compute sha-1 of a .gitignore fileNguyễn Thái Ngọc Duy, Oct 27, 2014
  3. Junio C HamanoOct 27, 2014
  4. Duy NguyenOct 28, 2014
  5. Torsten BögershausenOct 28, 2014
  6. Duy NguyenNov 2, 2014
  7. 02/19 untracked cache: record .gitignore information and dir hierarchyNguyễn Thái Ngọc Duy, Oct 27, 2014
  8. Torsten BögershausenOct 28, 2014
  9. 03/19 untracked cache: initial untracked cache validationNguyễn Thái Ngọc Duy, Oct 27, 2014
  10. 04/19 untracked cache: invalidate dirs recursively if .gitignore changesNguyễn Thái Ngọc Duy, Oct 27, 2014
  11. 05/19 untracked cache: make a wrapper around {open,read,close}dir()Nguyễn Thái Ngọc Duy, Oct 27, 2014
  12. 06/19 untracked cache: record/validate dir mtime and reuse cached outputNguyễn Thái Ngọc Duy, Oct 27, 2014
  13. Eric SunshineOct 30, 2014
  14. 07/19 untracked cache: mark what dirs should be recursed/savedNguyễn Thái Ngọc Duy, Oct 27, 2014
  15. 08/19 untracked cache: don't open non-existent .gitignoreNguyễn Thái Ngọc Duy, Oct 27, 2014
  16. 09/19 untracked cache: save to an index extensionNguyễn Thái Ngọc Duy, Oct 27, 2014
  17. 10/19 untracked cache: load from UNTR index extensionNguyễn Thái Ngọc Duy, Oct 27, 2014
  18. 11/19 untracked cache: invalidate at index addition or removalNguyễn Thái Ngọc Duy, Oct 27, 2014
  19. 12/19 read-cache.c: split racy stat test to a separate functionNguyễn Thái Ngọc Duy, Oct 27, 2014
  20. 13/19 untracked cache: avoid racy timestampsNguyễn Thái Ngọc Duy, Oct 27, 2014
  21. 14/19 untracked cache: print stats with $GIT_TRACE_UNTRACKED_STATSNguyễn Thái Ngọc Duy, Oct 27, 2014
  22. 15/19 untracked cache: mark index dirty if untracked cache is updatedNguyễn Thái Ngọc Duy, Oct 27, 2014
  23. 16/19 status: enable untracked cacheNguyễn Thái Ngọc Duy, Oct 27, 2014
  24. 17/19 update-index: manually enable or disable untracked cacheNguyễn Thái Ngọc Duy, Oct 27, 2014
  25. 18/19 update-index: test the system before enabling untracked cacheNguyễn Thái Ngọc Duy, Oct 27, 2014
  26. Torsten BögershausenOct 28, 2014
  27. Duy NguyenNov 3, 2014
  28. Junio C HamanoNov 3, 2014
  29. Eric SunshineOct 28, 2014
  30. 19/19 t7063: tests for untracked cacheNguyễn Thái Ngọc Duy, Oct 27, 2014
  31. 00/22 untracked cache updatesNguyễn Thái Ngọc Duy, Nov 8, 2014
  32. 01/22 dir.c: optionally compute sha-1 of a .gitignore fileNguyễn Thái Ngọc Duy, Nov 8, 2014
  33. David TurnerNov 17, 2014
  34. 02/22 untracked cache: record .gitignore information and dir hierarchyNguyễn Thái Ngọc Duy, Nov 8, 2014
  35. brian m. carlsonNov 8, 2014
  36. David TurnerNov 17, 2014
  37. 03/22 untracked cache: initial untracked cache validationNguyễn Thái Ngọc Duy, Nov 8, 2014
  38. 04/22 untracked cache: invalidate dirs recursively if .gitignore changesNguyễn Thái Ngọc Duy, Nov 8, 2014
  39. 05/22 untracked cache: make a wrapper around {open,read,close}dir()Nguyễn Thái Ngọc Duy, Nov 8, 2014
  40. 06/22 untracked cache: record/validate dir mtime and reuse cached outputNguyễn Thái Ngọc Duy, Nov 8, 2014
  41. 07/22 untracked cache: mark what dirs should be recursed/savedNguyễn Thái Ngọc Duy, Nov 8, 2014
  42. 08/22 untracked cache: don't open non-existent .gitignoreNguyễn Thái Ngọc Duy, Nov 8, 2014
  43. 09/22 untracked cache: save to an index extensionNguyễn Thái Ngọc Duy, Nov 8, 2014
  44. 10/22 untracked cache: load from UNTR index extensionNguyễn Thái Ngọc Duy, Nov 8, 2014
  45. 11/22 untracked cache: invalidate at index addition or removalNguyễn Thái Ngọc Duy, Nov 8, 2014
  46. 12/22 read-cache.c: split racy stat test to a separate functionNguyễn Thái Ngọc Duy, Nov 8, 2014
  47. 13/22 untracked cache: avoid racy timestampsNguyễn Thái Ngọc Duy, Nov 8, 2014
  48. 14/22 untracked cache: print stats with $GIT_TRACE_UNTRACKED_STATSNguyễn Thái Ngọc Duy, Nov 8, 2014
  49. 15/22 untracked cache: mark index dirty if untracked cache is updatedNguyễn Thái Ngọc Duy, Nov 8, 2014
  50. 16/22 untracked-cache: temporarily disable with $GIT_DISABLE_UNTRACKED_CACHENguyễn Thái Ngọc Duy, Nov 8, 2014
  51. 17/22 status: enable untracked cacheNguyễn Thái Ngọc Duy, Nov 8, 2014
  52. 18/22 update-index: manually enable or disable untracked cacheNguyễn Thái Ngọc Duy, Nov 8, 2014
  53. 19/22 update-index: test the system before enabling untracked cacheNguyễn Thái Ngọc Duy, Nov 8, 2014
  54. 20/22 t7063: tests for untracked cacheNguyễn Thái Ngọc Duy, Nov 8, 2014
  55. 21/22 mingw32: add uname()Nguyễn Thái Ngọc Duy, Nov 8, 2014
  56. Eric SunshineNov 9, 2014
  57. Duy NguyenNov 9, 2014
  58. Torsten BögershausenNov 9, 2014
  59. Junio C HamanoNov 9, 2014
  60. 22/22 untracked cache: guard and disable on system changesNguyễn Thái Ngọc Duy, Nov 8, 2014
  61. Eric SunshineNov 9, 2014
  62. Duy NguyenNov 9, 2014
  63. Torsten BögershausenNov 9, 2014
  64. Duy NguyenNov 9, 2014
  65. Torsten BögershausenNov 10, 2014

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.