summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 01cff2d)
raw | patch | inline | side by side (parent: 01cff2d)
author | Shawn Pearce <spearce@spearce.org> | |
Sun, 29 Oct 2006 09:41:59 +0000 (04:41 -0500) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Sun, 29 Oct 2006 21:45:03 +0000 (13:45 -0800) |
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>
`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>
Documentation/git-index-pack.txt | patch | blob | history | |
index-pack.c | patch | blob | history |
index 9fa4847d56be0844b91a7cbe76ead6c45a9e5bed..1235416e09d405b3bec118f6abe8e65e551fb696 100644 (file)
SYNOPSIS
--------
'git-index-pack' [-v] [-o <index-file>] <pack-file>
-'git-index-pack' --stdin [--fix-thin] [-v] [-o <index-file>] [<pack-file>]
+'git-index-pack' --stdin [--fix-thin] [--keep] [-v] [-o <index-file>] [<pack-file>]
DESCRIPTION
instead and a copy is then written to <pack-file>. If
<pack-file> is not specified, the pack is written to
objects/pack/ directory of the current git repository with
- a default name determined from the pack content.
+ a default name determined from the pack content. If
+ <pack-file> is not specified consider using --keep to
+ prevent a race condition between this process and
+ gitlink::git-repack[1] .
--fix-thin::
It is possible for gitlink:git-pack-objects[1] to build
and they must be included in the pack for that pack to be self
contained and indexable. Without this option any attempt to
index a thin pack will fail. This option only makes sense in
- conjonction with --stdin.
+ conjunction with --stdin.
+
+--keep::
+ Before moving the index into its final destination
+ create an empty .keep file for the associated pack file.
+ This option is usually necessary with --stdin to prevent a
+ simultaneous gitlink:git-repack[1] process from deleting
+ the newly constructed pack and index before refs can be
+ updated to use objects contained in the pack.
+
+--keep='why'::
+ Like --keep create a .keep file before moving the index into
+ its final destination, but rather than creating an empty file
+ place 'why' followed by an LF into the .keep file. The 'why'
+ message can later be searched for within all .keep files to
+ locate any which have outlived their usefulness.
Author
diff --git a/index-pack.c b/index-pack.c
index 866a0540560c085cd9feadb277b5b5e1e7891310..b37dd787296e908b843049a660e3e0f5cd80e01e 100644 (file)
--- a/index-pack.c
+++ b/index-pack.c
#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];
}
}
+ 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",
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++) {
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")) {
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();
}
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));