Skip to content

WIP PC Part 2 #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ LIB_OBJS += ewah/ewah_bitmap.o
LIB_OBJS += ewah/ewah_io.o
LIB_OBJS += ewah/ewah_rlw.o
LIB_OBJS += exec_cmd.o
LIB_OBJS += fetch-object.o
LIB_OBJS += fetch-pack.o
LIB_OBJS += fsck.o
LIB_OBJS += gettext.o
Expand Down
3 changes: 3 additions & 0 deletions builtin/cat-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "tree-walk.h"
#include "sha1-array.h"
#include "packfile.h"
#include "partial-clone-utils.h"

struct batch_options {
int enabled;
Expand Down Expand Up @@ -475,6 +476,8 @@ static int batch_objects(struct batch_options *opt)

for_each_loose_object(batch_loose_object, &sa, 0);
for_each_packed_object(batch_packed_object, &sa, 0);
if (is_partial_clone_registered())
warning("This repository has partial clone enabled. Some objects may not be loaded.");

cb.opt = opt;
cb.expand = &data;
Expand Down
10 changes: 10 additions & 0 deletions builtin/fetch-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
struct oid_array shallow = OID_ARRAY_INIT;
struct string_list deepen_not = STRING_LIST_INIT_DUP;

fetch_if_missing = 0;

packet_trace_identity("fetch-pack");

memset(&args, 0, sizeof(args));
Expand Down Expand Up @@ -143,6 +145,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
args.update_shallow = 1;
continue;
}
if (!strcmp("--from-promisor", arg)) {
args.from_promisor = 1;
continue;
}
if (!strcmp("--no-haves", arg)) {
args.no_haves = 1;
continue;
}
usage(fetch_pack_usage);
}
if (deepen_not.nr)
Expand Down
26 changes: 25 additions & 1 deletion builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
if (obj->flags & REACHABLE)
return 0;
obj->flags |= REACHABLE;

if (is_promisor_object(&obj->oid))
/*
* Further recursion does not need to be performed on this
* object since it is a promisor object (so it does not need to
* be added to "pending").
*/
return 0;

if (!(obj->flags & HAS_OBJ)) {
if (parent && !has_object_file(&obj->oid)) {
printf("broken link from %7s %s\n",
Expand Down Expand Up @@ -208,6 +217,8 @@ static void check_reachable_object(struct object *obj)
* do a full fsck
*/
if (!(obj->flags & HAS_OBJ)) {
if (is_promisor_object(&obj->oid))
return;
if (has_sha1_pack(obj->oid.hash))
return; /* it is in pack - forget about it */
printf("missing %s %s\n", printable_type(obj),
Expand Down Expand Up @@ -398,7 +409,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
xstrfmt("%s@{%"PRItime"}", refname, timestamp));
obj->flags |= USED;
mark_object_reachable(obj);
} else {
} else if (!is_promisor_object(oid)) {
error("%s: invalid reflog entry %s", refname, oid_to_hex(oid));
errors_found |= ERROR_REACHABLE;
}
Expand Down Expand Up @@ -434,6 +445,14 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,

obj = parse_object(oid);
if (!obj) {
if (is_promisor_object(oid)) {
/*
* Increment default_refs anyway, because this is a
* valid ref.
*/
default_refs++;
return 0;
}
error("%s: invalid sha1 pointer %s", refname, oid_to_hex(oid));
errors_found |= ERROR_REACHABLE;
/* We'll continue with the rest despite the error.. */
Expand Down Expand Up @@ -659,6 +678,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
int i;
struct alternate_object_database *alt;

/* fsck knows how to handle missing promisor objects */
fetch_if_missing = 0;

errors_found = 0;
check_replace_refs = 0;

Expand Down Expand Up @@ -731,6 +753,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
struct object *obj = lookup_object(oid.hash);

if (!obj || !(obj->flags & HAS_OBJ)) {
if (is_promisor_object(&oid))
continue;
error("%s: object missing", oid_to_hex(&oid));
errors_found |= ERROR_OBJECT;
continue;
Expand Down
113 changes: 68 additions & 45 deletions builtin/index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -1683,6 +1705,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
keep_msg = "";
} else if (starts_with(arg, "--keep=")) {
keep_msg = arg + 7;
} else if (!strcmp(arg, "--promisor")) {
promisor_msg = "";
} else if (starts_with(arg, "--promisor=")) {
promisor_msg = arg + strlen("--promisor=");
} else if (starts_with(arg, "--threads=")) {
char *end;
nr_threads = strtoul(arg+10, &end, 0);
Expand Down Expand Up @@ -1745,9 +1771,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)
Expand Down Expand Up @@ -1795,13 +1819,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)
Expand Down
12 changes: 11 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,7 @@ extern char *repository_format_partial_clone_filter;
struct repository_format {
int version;
int precious_objects;
char *partial_clone;
int is_bare;
char *work_tree;
char *partial_clone_remote; /* value of extensions.partialcloneremote */
Expand Down Expand Up @@ -1589,7 +1590,8 @@ extern struct packed_git {
unsigned pack_local:1,
pack_keep:1,
freshened:1,
do_not_close:1;
do_not_close:1,
pack_promisor:1;
unsigned char sha1[20];
struct revindex_entry *revindex;
/* something like ".git/objects/pack/xxxxx.pack" */
Expand Down Expand Up @@ -1728,6 +1730,14 @@ struct object_info {
#define OBJECT_INFO_QUICK 8
extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags);

/*
* Set this to 0 to prevent sha1_object_info_extended() from fetching missing
* blobs. This has a difference only if is_partial_clone_registered() is true.
*
* Its default value is 1.
*/
extern int fetch_if_missing;

/* Dumb servers support */
extern int update_server_info(int);

Expand Down
26 changes: 26 additions & 0 deletions fetch-object.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "cache.h"
#include "packfile.h"
#include "pkt-line.h"
#include "strbuf.h"
#include "transport.h"

void fetch_object(const char *remote_name, const unsigned char *sha1)
{
struct remote *remote;
struct transport *transport;
struct ref *ref;
int original_fetch_if_missing = fetch_if_missing;

fetch_if_missing = 0;
remote = remote_get(remote_name);
if (!remote->url[0])
die(_("Remote with no URL"));
transport = transport_get(remote, remote->url[0]);

ref = alloc_ref(sha1_to_hex(sha1));
hashcpy(ref->old_oid.hash, sha1);
transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
transport_set_option(transport, TRANS_OPT_NO_HAVES, "1");
transport_fetch_refs(transport, ref);
fetch_if_missing = original_fetch_if_missing;
}
6 changes: 6 additions & 0 deletions fetch-object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef FETCH_OBJECT_H
#define FETCH_OBJECT_H

extern void fetch_object(const char *remote_name, const unsigned char *sha1);

#endif
Loading