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

[4/5] Add option for hardlinkable cache of extracted blobs

From
Daniel Barkalow <barkalow@iabervon.org>
Date
Apr 17, 2005, 15:35 UTC
Message-ID
<Pine.LNX.4.21.0504171131230.30848-100000@iabervon.org>
In-Reply-To
<Pine.LNX.4.21.0504171108060.30848-100000@iabervon.org>

This adds an option (compile time, defined in the Makefile) to have a cache of extracted blobs so that different working directories can hardlink against them instead of creating new files for every checkout. You should only use this if you're sure the programs you use break links on modification and you care about storing many large working directories with few changes at the same time.

Signed-Off-By: Daniel Barkalow <barkalow@iabervon.org>
Index: Makefile
===================================================================
--- 157b46ce1d82b3579e2e1258927b0d9bdbc033ab/Makefile  (mode:100644 sha1:940ef8578cf469354002cd8feaec25d907015267)
+++ 08f7700831e056ad710af69f91e3a8a705b6b2b1/Makefile  (mode:100644 sha1:a60fa46404c0487158d232bd021e4798bc8df8de)
@@ -2,6 +2,9 @@
 # 1461501637330902918203684832716283019655932542976 hashes do not give you
 # enough guarantees about no collisions between objects ever hapenning.
 #
+# -DUSE_HARDLINK_CACHE if you want a cache of files to be hardlinked
+# to for unmodified checked out files.
+#
 # -DNSEC if you want git to care about sub-second file mtimes and ctimes.
 # Note that you need some new glibc (at least >2.2.4) for this, and it will
 # BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely randomly
Index: checkout-cache.c
===================================================================
--- 157b46ce1d82b3579e2e1258927b0d9bdbc033ab/checkout-cache.c  (mode:100644 sha1:5d3028df0a45329e45fff2006719c9267adeb946)
+++ 08f7700831e056ad710af69f91e3a8a705b6b2b1/checkout-cache.c  (mode:100644 sha1:338588259e17dd235fdc7db759d770004a760e15)
@@ -34,6 +34,10 @@
  */
 #include "cache.h"
 
+#ifdef USE_HARDLINK_CACHE
+#define HARDLINK_CACHE ".git/blobs"
+#endif /* USE_HARDLINK_CACHE */
+
 static int force = 0, quiet = 0;
 
 static void create_directories(const char *path)
@@ -67,6 +71,80 @@
 	return fd;
 }
 
+#ifdef HARDLINK_CACHE
+
+/*
+ * NOTE! This returns a statically allocated buffer, so you have to be
+ * careful about using it. Do a "strdup()" if you need to save the
+ * filename.
+ */
+char *sha1_blob_cache_file_name(const unsigned char *sha1)
+{
+	int i;
+	static char *name, *base;
+
+	if (!base) {
+		char *sha1_file_directory = HARDLINK_CACHE;
+		int len = strlen(sha1_file_directory);
+		base = malloc(len + 60);
+		memcpy(base, sha1_file_directory, len);
+		memset(base+len, 0, 60);
+		base[len] = '/';
+		base[len+3] = '/';
+		name = base + len + 1;
+	}
+	for (i = 0; i < 20; i++) {
+		static char hex[] = "0123456789abcdef";
+		unsigned int val = sha1[i];
+		char *pos = name + i*2 + (i > 0);
+		*pos++ = hex[val >> 4];
+		*pos = hex[val & 0xf];
+	}
+	return base;
+}
+
+static int write_entry(struct cache_entry *ce)
+{
+	int fd;
+	void *new;
+	unsigned long size;
+	long wrote;
+	char type[20];
+	char *cache_name;
+	struct stat st;
+
+	cache_name = sha1_blob_cache_file_name(ce->sha1);
+
+	if (stat(cache_name, &st)) {
+		new = read_sha1_file(ce->sha1, type, &size);
+		if (!new || strcmp(type, "blob")) {
+			return error("checkout-cache: unable to read sha1 file of %s (%s)",
+				     ce->name, sha1_to_hex(ce->sha1));
+		}
+		fd = create_file(cache_name, ntohl(ce->ce_mode));
+		if (fd < 0) {
+			free(new);
+			return error("checkout-cache: unable to create %s (%s)",
+				     ce->name, strerror(errno));
+		}
+		wrote = write(fd, new, size);
+		close(fd);
+		free(new);
+		if (wrote != size)
+			return error("checkout-cache: unable to write %s", 
+				     ce->name);
+	}
+	if (link(cache_name, ce->name)) {
+		if (errno == ENOENT) {
+			create_directories(ce->name);
+			link(cache_name, ce->name);
+		}
+	}
+	return 0;
+}
+
+#else
+
 static int write_entry(struct cache_entry *ce)
 {
 	int fd;
@@ -94,6 +172,8 @@
 	return 0;
 }
 
+#endif
+
 static int checkout_entry(struct cache_entry *ce)
 {
 	struct stat st;
Previous: Daniel BarkalowNext: Petr Baudis
Message 33 of 37 in “[0/5] Patch set for various things”
  1. Daniel BarkalowApr 17, 2005
  2. 1/5 Parsing code in revision.hDaniel Barkalow, Apr 17, 2005
  3. Petr BaudisApr 17, 2005
  4. Daniel BarkalowApr 17, 2005
  5. Linus TorvaldsApr 17, 2005
  6. Petr BaudisApr 17, 2005
  7. Linus TorvaldsApr 17, 2005
  8. Daniel BarkalowApr 17, 2005
  9. Linus TorvaldsApr 17, 2005
  10. Daniel BarkalowApr 17, 2005
  11. 2/5 Add merge-baseDaniel Barkalow, Apr 17, 2005
  12. Petr BaudisApr 17, 2005
  13. Daniel BarkalowApr 17, 2005
  14. 1/5 Add merge-baseDaniel Barkalow, Apr 17, 2005
  15. Petr BaudisApr 17, 2005
  16. Daniel BarkalowApr 17, 2005
  17. 3/5 Add http-pullDaniel Barkalow, Apr 17, 2005
  18. Petr BaudisApr 17, 2005
  19. Daniel BarkalowApr 17, 2005
  20. Petr BaudisApr 17, 2005
  21. Daniel BarkalowApr 17, 2005
  22. Petr BaudisApr 17, 2005
  23. Brad RobertsApr 21, 2005
  24. Daniel BarkalowApr 21, 2005
  25. tony.luck@intel.comApr 21, 2005
  26. Daniel BarkalowApr 22, 2005
  27. Petr BaudisApr 22, 2005
  28. Daniel BarkalowApr 22, 2005
  29. Petr BaudisApr 22, 2005
  30. Daniel BarkalowApr 22, 2005
  31. Martin SchlemmerApr 22, 2005
  32. 1/5 Add http-pullDaniel Barkalow, Apr 17, 2005
  33. 4/5 Add option for hardlinkable cache of extracted blobsDaniel Barkalow, Apr 17, 2005
  34. Petr BaudisApr 17, 2005
  35. Daniel BarkalowApr 17, 2005
  36. Paul JacksonApr 17, 2005
  37. 5/5 Add commit-id to versionDaniel Barkalow, Apr 17, 2005

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.