diff options
author | Shawn Pearce <spearce@spearce.org> | 2006-10-29 04:41:59 -0500 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-10-29 13:45:03 -0800 |
commit | b8077709243138c3d8cc1c096c06a95b250a9001 (patch) | |
tree | 5ceb0feedf42c88fafc1210f826678c3c87e488a /index-pack.c | |
parent | 01cff2d2ca77dc050973e1fc4702119a715cc919 (diff) | |
download | git-b8077709243138c3d8cc1c096c06a95b250a9001.tar.gz |
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>
Diffstat (limited to 'index-pack.c')
-rw-r--r-- | index-pack.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/index-pack.c b/index-pack.c index 866a054056..b37dd78729 100644 --- a/index-pack.c +++ b/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)); |