Merge branch 'jh/fsck-promisors'
In preparation for implementing narrow/partial clone, the machinery for checking object connectivity used by gc and fsck has been taught that a missing object is OK when it is referenced by a packfile specially marked as coming from trusted repository that promises to make them available on-demand and lazily. * jh/fsck-promisors: gc: do not repack promisor packfiles rev-list: support termination at promisor objects sha1_file: support lazily fetching missing objects introduce fetch-object: fetch one promisor object index-pack: refactor writing of .keep files fsck: support promisor objects as CLI argument fsck: support referenced promisor objects fsck: support refs pointing to promisor objects fsck: introduce partialclone extension extension.partialclone: introduce partial clone extension
This commit is contained in:
@ -1389,15 +1389,60 @@ static void fix_unresolved_deltas(struct sha1file *f)
|
||||
free(sorted_by_pos);
|
||||
}
|
||||
|
||||
static const char *derive_filename(const char *pack_name, const char *suffix,
|
||||
struct strbuf *buf)
|
||||
{
|
||||
size_t len;
|
||||
if (!strip_suffix(pack_name, ".pack", &len))
|
||||
die(_("packfile name '%s' does not end with '.pack'"),
|
||||
pack_name);
|
||||
strbuf_add(buf, pack_name, len);
|
||||
strbuf_addch(buf, '.');
|
||||
strbuf_addstr(buf, suffix);
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
static void write_special_file(const char *suffix, const char *msg,
|
||||
const char *pack_name, const unsigned char *sha1,
|
||||
const char **report)
|
||||
{
|
||||
struct strbuf name_buf = STRBUF_INIT;
|
||||
const char *filename;
|
||||
int fd;
|
||||
int msg_len = strlen(msg);
|
||||
|
||||
if (pack_name)
|
||||
filename = derive_filename(pack_name, suffix, &name_buf);
|
||||
else
|
||||
filename = odb_pack_name(&name_buf, sha1, suffix);
|
||||
|
||||
fd = odb_pack_keep(filename);
|
||||
if (fd < 0) {
|
||||
if (errno != EEXIST)
|
||||
die_errno(_("cannot write %s file '%s'"),
|
||||
suffix, filename);
|
||||
} else {
|
||||
if (msg_len > 0) {
|
||||
write_or_die(fd, msg, msg_len);
|
||||
write_or_die(fd, "\n", 1);
|
||||
}
|
||||
if (close(fd) != 0)
|
||||
die_errno(_("cannot close written %s file '%s'"),
|
||||
suffix, filename);
|
||||
if (report)
|
||||
*report = suffix;
|
||||
}
|
||||
strbuf_release(&name_buf);
|
||||
}
|
||||
|
||||
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,
|
||||
const char *keep_msg, const char *promisor_msg,
|
||||
unsigned char *sha1)
|
||||
{
|
||||
const char *report = "pack";
|
||||
struct strbuf pack_name = STRBUF_INIT;
|
||||
struct strbuf index_name = STRBUF_INIT;
|
||||
struct strbuf keep_name_buf = STRBUF_INIT;
|
||||
int err;
|
||||
|
||||
if (!from_stdin) {
|
||||
@ -1409,28 +1454,12 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
die_errno(_("error while closing pack file"));
|
||||
}
|
||||
|
||||
if (keep_msg) {
|
||||
int keep_fd, keep_msg_len = strlen(keep_msg);
|
||||
|
||||
if (!keep_name)
|
||||
keep_name = odb_pack_name(&keep_name_buf, sha1, "keep");
|
||||
|
||||
keep_fd = odb_pack_keep(keep_name);
|
||||
if (keep_fd < 0) {
|
||||
if (errno != EEXIST)
|
||||
die_errno(_("cannot write keep file '%s'"),
|
||||
keep_name);
|
||||
} else {
|
||||
if (keep_msg_len > 0) {
|
||||
write_or_die(keep_fd, keep_msg, keep_msg_len);
|
||||
write_or_die(keep_fd, "\n", 1);
|
||||
}
|
||||
if (close(keep_fd) != 0)
|
||||
die_errno(_("cannot close written keep file '%s'"),
|
||||
keep_name);
|
||||
report = "keep";
|
||||
}
|
||||
}
|
||||
if (keep_msg)
|
||||
write_special_file("keep", keep_msg, final_pack_name, sha1,
|
||||
&report);
|
||||
if (promisor_msg)
|
||||
write_special_file("promisor", promisor_msg, final_pack_name,
|
||||
sha1, NULL);
|
||||
|
||||
if (final_pack_name != curr_pack_name) {
|
||||
if (!final_pack_name)
|
||||
@ -1472,7 +1501,6 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
||||
|
||||
strbuf_release(&index_name);
|
||||
strbuf_release(&pack_name);
|
||||
strbuf_release(&keep_name_buf);
|
||||
}
|
||||
|
||||
static int git_index_pack_config(const char *k, const char *v, void *cb)
|
||||
@ -1615,32 +1643,26 @@ static void show_pack_info(int stat_only)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *derive_filename(const char *pack_name, const char *suffix,
|
||||
struct strbuf *buf)
|
||||
{
|
||||
size_t len;
|
||||
if (!strip_suffix(pack_name, ".pack", &len))
|
||||
die(_("packfile name '%s' does not end with '.pack'"),
|
||||
pack_name);
|
||||
strbuf_add(buf, pack_name, len);
|
||||
strbuf_addstr(buf, suffix);
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
|
||||
const char *curr_index;
|
||||
const char *index_name = NULL, *pack_name = NULL;
|
||||
const char *keep_name = NULL, *keep_msg = NULL;
|
||||
struct strbuf index_name_buf = STRBUF_INIT,
|
||||
keep_name_buf = STRBUF_INIT;
|
||||
const char *keep_msg = NULL;
|
||||
const char *promisor_msg = NULL;
|
||||
struct strbuf index_name_buf = STRBUF_INIT;
|
||||
struct pack_idx_entry **idx_objects;
|
||||
struct pack_idx_option opts;
|
||||
unsigned char pack_sha1[20];
|
||||
unsigned foreign_nr = 1; /* zero is a "good" value, assume bad */
|
||||
int report_end_of_input = 0;
|
||||
|
||||
/*
|
||||
* index-pack never needs to fetch missing objects, since it only
|
||||
* accesses the repo to do hash collision checks
|
||||
*/
|
||||
fetch_if_missing = 0;
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
usage(index_pack_usage);
|
||||
|
||||
@ -1678,6 +1700,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
||||
stat_only = 1;
|
||||
} else if (skip_to_optional_arg(arg, "--keep", &keep_msg)) {
|
||||
; /* nothing to do */
|
||||
} else if (skip_to_optional_arg(arg, "--promisor", &promisor_msg)) {
|
||||
; /* already parsed */
|
||||
} else if (starts_with(arg, "--threads=")) {
|
||||
char *end;
|
||||
nr_threads = strtoul(arg+10, &end, 0);
|
||||
@ -1740,9 +1764,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
||||
if (from_stdin && !startup_info->have_repository)
|
||||
die(_("--stdin requires a git repository"));
|
||||
if (!index_name && pack_name)
|
||||
index_name = derive_filename(pack_name, ".idx", &index_name_buf);
|
||||
if (keep_msg && !keep_name && pack_name)
|
||||
keep_name = derive_filename(pack_name, ".keep", &keep_name_buf);
|
||||
index_name = derive_filename(pack_name, "idx", &index_name_buf);
|
||||
|
||||
if (verify) {
|
||||
if (!index_name)
|
||||
@ -1790,13 +1812,12 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
||||
if (!verify)
|
||||
final(pack_name, curr_pack,
|
||||
index_name, curr_index,
|
||||
keep_name, keep_msg,
|
||||
keep_msg, promisor_msg,
|
||||
pack_sha1);
|
||||
else
|
||||
close(input_fd);
|
||||
free(objects);
|
||||
strbuf_release(&index_name_buf);
|
||||
strbuf_release(&keep_name_buf);
|
||||
if (pack_name == NULL)
|
||||
free((void *) curr_pack);
|
||||
if (index_name == NULL)
|
||||
|
||||
Reference in New Issue
Block a user