[PATCH] Make sure objects/pack exists before creating a new pack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In a repository created with git older than f49fb35 (git-init-db: create
"pack" subdirectory under objects, 2005-06-27), objects/pack/ directory is
not created upon initialization.  It was Ok because subdirectories are
created as needed inside directories init-db creates.

8b4eb6b (Do not perform cross-directory renames when creating packs,
2008-09-22) moved the location temporary pack files are created from
objects/ directory to objects/pack/ directory; this move broke many
operations in such a repository, because it was not careful enough to make
sure leading directories exist.

Introduce odb_mkstemp() which is a specialized version of mkstemp() to
refactor the code and teach it to create a leading directories properly
to fix this buglet.

Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---

 * I don't know why, but I somehow found doing this patch highly amusing.

 builtin-pack-objects.c |    5 ++---
 fast-import.c          |   10 ++++------
 git-compat-util.h      |    1 +
 index-pack.c           |    5 ++---
 pack-write.c           |    4 +---
 wrapper.c              |   17 +++++++++++++++++
 6 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index cb51916..bcefa52 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -488,9 +488,8 @@ static void write_pack_file(void)
 		} else {
 			char tmpname[PATH_MAX];
 			int fd;
-			snprintf(tmpname, sizeof(tmpname),
-				 "%s/pack/tmp_pack_XXXXXX", get_object_directory());
-			fd = xmkstemp(tmpname);
+			fd = odb_mkstemp(tmpname, sizeof(tmpname),
+					 "pack/tmp_pack_XXXXXX");
 			pack_tmp_name = xstrdup(tmpname);
 			f = sha1fd(fd, pack_tmp_name);
 		}
diff --git a/fast-import.c b/fast-import.c
index 3ef3413..99e4df4 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -817,9 +817,8 @@ static void start_packfile(void)
 	struct pack_header hdr;
 	int pack_fd;
 
-	snprintf(tmpfile, sizeof(tmpfile),
-		"%s/pack/tmp_pack_XXXXXX", get_object_directory());
-	pack_fd = xmkstemp(tmpfile);
+	pack_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),
+			      "pack/tmp_pack_XXXXXX");
 	p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);
 	strcpy(p->pack_name, tmpfile);
 	p->pack_fd = pack_fd;
@@ -879,9 +878,8 @@ static char *create_index(void)
 		c = next;
 	}
 
-	snprintf(tmpfile, sizeof(tmpfile),
-		"%s/pack/tmp_idx_XXXXXX", get_object_directory());
-	idx_fd = xmkstemp(tmpfile);
+	idx_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),
+			     "pack/tmp_idx_XXXXXX");
 	f = sha1fd(idx_fd, tmpfile);
 	sha1write(f, array, 256 * sizeof(int));
 	git_SHA1_Init(&ctx);
diff --git a/git-compat-util.h b/git-compat-util.h
index 079cbe9..c1744b9 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -303,6 +303,7 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len);
 extern int xdup(int fd);
 extern FILE *xfdopen(int fd, const char *mode);
 extern int xmkstemp(char *template);
+extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
 
 static inline size_t xsize_t(off_t len)
 {
diff --git a/index-pack.c b/index-pack.c
index f7a3807..0350c29 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -172,9 +172,8 @@ static char *open_pack_file(char *pack_name)
 		input_fd = 0;
 		if (!pack_name) {
 			static char tmpfile[PATH_MAX];
-			snprintf(tmpfile, sizeof(tmpfile),
-				 "%s/pack/tmp_pack_XXXXXX", get_object_directory());
-			output_fd = xmkstemp(tmpfile);
+			output_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),
+						"pack/tmp_pack_XXXXXX");
 			pack_name = xstrdup(tmpfile);
 		} else
 			output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
diff --git a/pack-write.c b/pack-write.c
index b426006..3ab55b9 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -44,9 +44,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,
 
 	if (!index_name) {
 		static char tmpfile[PATH_MAX];
-		snprintf(tmpfile, sizeof(tmpfile),
-			 "%s/pack/tmp_idx_XXXXXX", get_object_directory());
-		fd = xmkstemp(tmpfile);
+		fd = odb_mkstemp(tmpfile, sizeof(tmpfile), "pack/tmp_idx_XXXXXX");
 		index_name = xstrdup(tmpfile);
 	} else {
 		unlink(index_name);
diff --git a/wrapper.c b/wrapper.c
index c85ca52..371cee1 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -197,6 +197,23 @@ int xmkstemp(char *template)
 	return fd;
 }
 
+int odb_mkstemp(char *template, size_t limit, const char *pattern)
+{
+	int fd;
+
+	snprintf(template, limit, "%s/%s",
+		 get_object_directory(), pattern);
+	fd = mkstemp(template);
+	if (0 <= fd)
+		return fd;
+
+	/* slow path */
+	safe_create_leading_directories(template);
+	snprintf(template, limit, "%s/%s",
+		 get_object_directory(), pattern);
+	return xmkstemp(template);
+}
+
 /*
  * zlib wrappers to make sure we don't silently miss errors
  * at init time.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux