Skip to content

Commit bb0cebd

Browse files
committed
Merge branch 'jc/maint-1.6.0-pack-directory'
* jc/maint-1.6.0-pack-directory: Make sure objects/pack exists before creating a new pack
2 parents 69707d6 + 6e180cd commit bb0cebd

File tree

7 files changed

+72
-27
lines changed

7 files changed

+72
-27
lines changed

builtin-pack-objects.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,8 @@ static void write_pack_file(void)
488488
} else {
489489
char tmpname[PATH_MAX];
490490
int fd;
491-
snprintf(tmpname, sizeof(tmpname),
492-
"%s/pack/tmp_pack_XXXXXX", get_object_directory());
493-
fd = xmkstemp(tmpname);
491+
fd = odb_mkstemp(tmpname, sizeof(tmpname),
492+
"pack/tmp_pack_XXXXXX");
494493
pack_tmp_name = xstrdup(tmpname);
495494
f = sha1fd(fd, pack_tmp_name);
496495
}

fast-import.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -817,9 +817,8 @@ static void start_packfile(void)
817817
struct pack_header hdr;
818818
int pack_fd;
819819

820-
snprintf(tmpfile, sizeof(tmpfile),
821-
"%s/pack/tmp_pack_XXXXXX", get_object_directory());
822-
pack_fd = xmkstemp(tmpfile);
820+
pack_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),
821+
"pack/tmp_pack_XXXXXX");
823822
p = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);
824823
strcpy(p->pack_name, tmpfile);
825824
p->pack_fd = pack_fd;
@@ -879,9 +878,8 @@ static char *create_index(void)
879878
c = next;
880879
}
881880

882-
snprintf(tmpfile, sizeof(tmpfile),
883-
"%s/pack/tmp_idx_XXXXXX", get_object_directory());
884-
idx_fd = xmkstemp(tmpfile);
881+
idx_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),
882+
"pack/tmp_idx_XXXXXX");
885883
f = sha1fd(idx_fd, tmpfile);
886884
sha1write(f, array, 256 * sizeof(int));
887885
git_SHA1_Init(&ctx);
@@ -907,9 +905,7 @@ static char *keep_pack(char *curr_index_name)
907905
chmod(pack_data->pack_name, 0444);
908906
chmod(curr_index_name, 0444);
909907

910-
snprintf(name, sizeof(name), "%s/pack/pack-%s.keep",
911-
get_object_directory(), sha1_to_hex(pack_data->sha1));
912-
keep_fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
908+
keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
913909
if (keep_fd < 0)
914910
die("cannot create keep file");
915911
write_or_die(keep_fd, keep_msg, strlen(keep_msg));

git-compat-util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len);
303303
extern int xdup(int fd);
304304
extern FILE *xfdopen(int fd, const char *mode);
305305
extern int xmkstemp(char *template);
306+
extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
307+
extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1);
306308

307309
static inline size_t xsize_t(off_t len)
308310
{

index-pack.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,8 @@ static char *open_pack_file(char *pack_name)
172172
input_fd = 0;
173173
if (!pack_name) {
174174
static char tmpfile[PATH_MAX];
175-
snprintf(tmpfile, sizeof(tmpfile),
176-
"%s/pack/tmp_pack_XXXXXX", get_object_directory());
177-
output_fd = xmkstemp(tmpfile);
175+
output_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),
176+
"pack/tmp_pack_XXXXXX");
178177
pack_name = xstrdup(tmpfile);
179178
} else
180179
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
@@ -794,22 +793,24 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
794793

795794
if (keep_msg) {
796795
int keep_fd, keep_msg_len = strlen(keep_msg);
797-
if (!keep_name) {
798-
snprintf(name, sizeof(name), "%s/pack/pack-%s.keep",
799-
get_object_directory(), sha1_to_hex(sha1));
800-
keep_name = name;
801-
}
802-
keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600);
796+
797+
if (!keep_name)
798+
keep_fd = odb_pack_keep(name, sizeof(name), sha1);
799+
else
800+
keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600);
801+
803802
if (keep_fd < 0) {
804803
if (errno != EEXIST)
805-
die("cannot write keep file");
804+
die("cannot write keep file '%s' (%s)",
805+
keep_name, strerror(errno));
806806
} else {
807807
if (keep_msg_len > 0) {
808808
write_or_die(keep_fd, keep_msg, keep_msg_len);
809809
write_or_die(keep_fd, "\n", 1);
810810
}
811811
if (close(keep_fd) != 0)
812-
die("cannot write keep file");
812+
die("cannot close written keep file '%s' (%s)",
813+
keep_name, strerror(errno));
813814
report = "keep";
814815
}
815816
}

pack-write.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,
4444

4545
if (!index_name) {
4646
static char tmpfile[PATH_MAX];
47-
snprintf(tmpfile, sizeof(tmpfile),
48-
"%s/pack/tmp_idx_XXXXXX", get_object_directory());
49-
fd = xmkstemp(tmpfile);
47+
fd = odb_mkstemp(tmpfile, sizeof(tmpfile), "pack/tmp_idx_XXXXXX");
5048
index_name = xstrdup(tmpfile);
5149
} else {
5250
unlink(index_name);
@@ -239,7 +237,7 @@ char *index_pack_lockfile(int ip_out)
239237
char packname[46];
240238

241239
/*
242-
* The first thing we expects from index-pack's output
240+
* The first thing we expect from index-pack's output
243241
* is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where
244242
* %40s is the newly created pack SHA1 name. In the "keep"
245243
* case, we need it to remove the corresponding .keep file

t/t5300-pack-object.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,23 @@ test_expect_success \
180180

181181
unset GIT_OBJECT_DIRECTORY
182182

183+
test_expect_success 'survive missing objects/pack directory' '
184+
(
185+
rm -fr missing-pack &&
186+
mkdir missing-pack &&
187+
cd missing-pack &&
188+
git init &&
189+
GOP=.git/objects/pack
190+
rm -fr $GOP &&
191+
git index-pack --stdin --keep=test <../test-3-${packname_3}.pack &&
192+
test -f $GOP/pack-${packname_3}.pack &&
193+
test_cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack &&
194+
test -f $GOP/pack-${packname_3}.idx &&
195+
test_cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx &&
196+
test -f $GOP/pack-${packname_3}.keep
197+
)
198+
'
199+
183200
test_expect_success \
184201
'verify pack' \
185202
'git verify-pack test-1-${packname_1}.idx \

wrapper.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,35 @@ int git_inflate(z_streamp strm, int flush)
256256
error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
257257
return ret;
258258
}
259+
260+
int odb_mkstemp(char *template, size_t limit, const char *pattern)
261+
{
262+
int fd;
263+
264+
snprintf(template, limit, "%s/%s",
265+
get_object_directory(), pattern);
266+
fd = mkstemp(template);
267+
if (0 <= fd)
268+
return fd;
269+
270+
/* slow path */
271+
safe_create_leading_directories(template);
272+
snprintf(template, limit, "%s/%s",
273+
get_object_directory(), pattern);
274+
return xmkstemp(template);
275+
}
276+
277+
int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)
278+
{
279+
int fd;
280+
281+
snprintf(name, namesz, "%s/pack/pack-%s.keep",
282+
get_object_directory(), sha1_to_hex(sha1));
283+
fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
284+
if (0 <= fd)
285+
return fd;
286+
287+
/* slow path */
288+
safe_create_leading_directories(name);
289+
return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
290+
}

0 commit comments

Comments
 (0)