Teach git-index-pack how to keep a pack file.
To prevent a race condition between `index-pack --stdin` and `repack -a -d` where the repack deletes the newly created pack file before any refs are updated to reference objects contained within it we mark the pack file as one that should be kept. This removes it from the list of packs that `repack -a -d` will consider for removal. Callers such as `receive-pack` which want to invoke `index-pack` should use this new --keep option to prevent the newly created pack and index file pair from being deleted before they have finished any related ref updates. Only after all ref updates have been finished should the associated .keep file be removed. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:

committed by
Junio C Hamano

parent
01cff2d2ca
commit
b807770924
43
index-pack.c
43
index-pack.c
@ -10,7 +10,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
static const char index_pack_usage[] =
|
||||
"git-index-pack [-v] [-o <index-file>] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
|
||||
"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
|
||||
|
||||
struct object_entry
|
||||
{
|
||||
@ -754,6 +754,7 @@ static const char *write_index_file(const char *index_name, unsigned char *sha1)
|
||||
|
||||
static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
const char *final_index_name, const char *curr_index_name,
|
||||
const char *keep_name, const char *keep_msg,
|
||||
unsigned char *sha1)
|
||||
{
|
||||
char name[PATH_MAX];
|
||||
@ -780,6 +781,23 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
}
|
||||
}
|
||||
|
||||
if (keep_msg) {
|
||||
int keep_fd, keep_msg_len = strlen(keep_msg);
|
||||
if (!keep_name) {
|
||||
snprintf(name, sizeof(name), "%s/pack/pack-%s.keep",
|
||||
get_object_directory(), sha1_to_hex(sha1));
|
||||
keep_name = name;
|
||||
}
|
||||
keep_fd = open(keep_name, O_RDWR | O_CREAT, 0600);
|
||||
if (keep_fd < 0)
|
||||
die("cannot write keep file");
|
||||
if (keep_msg_len > 0) {
|
||||
write_or_die(keep_fd, keep_msg, keep_msg_len);
|
||||
write_or_die(keep_fd, "\n", 1);
|
||||
}
|
||||
close(keep_fd);
|
||||
}
|
||||
|
||||
if (final_pack_name != curr_pack_name) {
|
||||
if (!final_pack_name) {
|
||||
snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
|
||||
@ -807,7 +825,8 @@ int main(int argc, char **argv)
|
||||
int i, fix_thin_pack = 0;
|
||||
const char *curr_pack, *pack_name = NULL;
|
||||
const char *curr_index, *index_name = NULL;
|
||||
char *index_name_buf = NULL;
|
||||
const char *keep_name = NULL, *keep_msg = NULL;
|
||||
char *index_name_buf = NULL, *keep_name_buf = NULL;
|
||||
unsigned char sha1[20];
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
@ -818,6 +837,10 @@ int main(int argc, char **argv)
|
||||
from_stdin = 1;
|
||||
} else if (!strcmp(arg, "--fix-thin")) {
|
||||
fix_thin_pack = 1;
|
||||
} else if (!strcmp(arg, "--keep")) {
|
||||
keep_msg = "";
|
||||
} else if (!strncmp(arg, "--keep=", 7)) {
|
||||
keep_msg = arg + 7;
|
||||
} else if (!strcmp(arg, "-v")) {
|
||||
verbose = 1;
|
||||
} else if (!strcmp(arg, "-o")) {
|
||||
@ -848,6 +871,16 @@ int main(int argc, char **argv)
|
||||
strcpy(index_name_buf + len - 5, ".idx");
|
||||
index_name = index_name_buf;
|
||||
}
|
||||
if (keep_msg && !keep_name && pack_name) {
|
||||
int len = strlen(pack_name);
|
||||
if (!has_extension(pack_name, ".pack"))
|
||||
die("packfile name '%s' does not end with '.pack'",
|
||||
pack_name);
|
||||
keep_name_buf = xmalloc(len);
|
||||
memcpy(keep_name_buf, pack_name, len - 5);
|
||||
strcpy(keep_name_buf + len - 5, ".keep");
|
||||
keep_name = keep_name_buf;
|
||||
}
|
||||
|
||||
curr_pack = open_pack_file(pack_name);
|
||||
parse_pack_header();
|
||||
@ -880,9 +913,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
free(deltas);
|
||||
curr_index = write_index_file(index_name, sha1);
|
||||
final(pack_name, curr_pack, index_name, curr_index, sha1);
|
||||
final(pack_name, curr_pack,
|
||||
index_name, curr_index,
|
||||
keep_name, keep_msg,
|
||||
sha1);
|
||||
free(objects);
|
||||
free(index_name_buf);
|
||||
free(keep_name_buf);
|
||||
|
||||
if (!from_stdin)
|
||||
printf("%s\n", sha1_to_hex(sha1));
|
||||
|
Reference in New Issue
Block a user