Merge branch 'nd/fetch-into-shallow'
When there is no sufficient overlap between old and new history during a fetch into a shallow repository, we unnecessarily sent objects the sending side knows the receiving end has. * nd/fetch-into-shallow: Add testcase for needless objects during a shallow fetch list-objects: mark more commits as edges in mark_edges_uninteresting list-objects: reduce one argument in mark_edges_uninteresting upload-pack: delegate rev walking in shallow fetch to pack-objects shallow: add setup_temporary_shallow() shallow: only add shallow graft points to new shallow file move setup_alternate_shallow and write_shallow_commits to shallow.c
This commit is contained in:
126
upload-pack.c
126
upload-pack.c
@ -69,87 +69,28 @@ static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
|
||||
return sz;
|
||||
}
|
||||
|
||||
static FILE *pack_pipe = NULL;
|
||||
static void show_commit(struct commit *commit, void *data)
|
||||
{
|
||||
if (commit->object.flags & BOUNDARY)
|
||||
fputc('-', pack_pipe);
|
||||
if (fputs(sha1_to_hex(commit->object.sha1), pack_pipe) < 0)
|
||||
die("broken output pipe");
|
||||
fputc('\n', pack_pipe);
|
||||
fflush(pack_pipe);
|
||||
free(commit->buffer);
|
||||
commit->buffer = NULL;
|
||||
}
|
||||
|
||||
static void show_object(struct object *obj,
|
||||
const struct name_path *path, const char *component,
|
||||
void *cb_data)
|
||||
{
|
||||
show_object_with_name(pack_pipe, obj, path, component);
|
||||
}
|
||||
|
||||
static void show_edge(struct commit *commit)
|
||||
{
|
||||
fprintf(pack_pipe, "-%s\n", sha1_to_hex(commit->object.sha1));
|
||||
}
|
||||
|
||||
static int do_rev_list(int in, int out, void *user_data)
|
||||
{
|
||||
int i;
|
||||
struct rev_info revs;
|
||||
|
||||
pack_pipe = xfdopen(out, "w");
|
||||
init_revisions(&revs, NULL);
|
||||
revs.tag_objects = 1;
|
||||
revs.tree_objects = 1;
|
||||
revs.blob_objects = 1;
|
||||
if (use_thin_pack)
|
||||
revs.edge_hint = 1;
|
||||
|
||||
for (i = 0; i < want_obj.nr; i++) {
|
||||
struct object *o = want_obj.objects[i].item;
|
||||
/* why??? */
|
||||
o->flags &= ~UNINTERESTING;
|
||||
add_pending_object(&revs, o, NULL);
|
||||
}
|
||||
for (i = 0; i < have_obj.nr; i++) {
|
||||
struct object *o = have_obj.objects[i].item;
|
||||
o->flags |= UNINTERESTING;
|
||||
add_pending_object(&revs, o, NULL);
|
||||
}
|
||||
setup_revisions(0, NULL, &revs, NULL);
|
||||
if (prepare_revision_walk(&revs))
|
||||
die("revision walk setup failed");
|
||||
mark_edges_uninteresting(revs.commits, &revs, show_edge);
|
||||
if (use_thin_pack)
|
||||
for (i = 0; i < extra_edge_obj.nr; i++)
|
||||
fprintf(pack_pipe, "-%s\n", sha1_to_hex(
|
||||
extra_edge_obj.objects[i].item->sha1));
|
||||
traverse_commit_list(&revs, show_commit, show_object, NULL);
|
||||
fflush(pack_pipe);
|
||||
fclose(pack_pipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void create_pack_file(void)
|
||||
{
|
||||
struct async rev_list;
|
||||
struct child_process pack_objects;
|
||||
char data[8193], progress[128];
|
||||
char abort_msg[] = "aborting due to possible repository "
|
||||
"corruption on the remote side.";
|
||||
int buffered = -1;
|
||||
ssize_t sz;
|
||||
const char *argv[10];
|
||||
int arg = 0;
|
||||
const char *argv[12];
|
||||
int i, arg = 0;
|
||||
FILE *pipe_fd;
|
||||
char *shallow_file = NULL;
|
||||
|
||||
argv[arg++] = "pack-objects";
|
||||
if (!shallow_nr) {
|
||||
argv[arg++] = "--revs";
|
||||
if (use_thin_pack)
|
||||
argv[arg++] = "--thin";
|
||||
if (shallow_nr) {
|
||||
shallow_file = setup_temporary_shallow();
|
||||
argv[arg++] = "--shallow-file";
|
||||
argv[arg++] = shallow_file;
|
||||
}
|
||||
argv[arg++] = "pack-objects";
|
||||
argv[arg++] = "--revs";
|
||||
if (use_thin_pack)
|
||||
argv[arg++] = "--thin";
|
||||
|
||||
argv[arg++] = "--stdout";
|
||||
if (!no_progress)
|
||||
@ -170,29 +111,21 @@ static void create_pack_file(void)
|
||||
if (start_command(&pack_objects))
|
||||
die("git upload-pack: unable to fork git-pack-objects");
|
||||
|
||||
if (shallow_nr) {
|
||||
memset(&rev_list, 0, sizeof(rev_list));
|
||||
rev_list.proc = do_rev_list;
|
||||
rev_list.out = pack_objects.in;
|
||||
if (start_async(&rev_list))
|
||||
die("git upload-pack: unable to fork git-rev-list");
|
||||
}
|
||||
else {
|
||||
FILE *pipe_fd = xfdopen(pack_objects.in, "w");
|
||||
int i;
|
||||
|
||||
for (i = 0; i < want_obj.nr; i++)
|
||||
fprintf(pipe_fd, "%s\n",
|
||||
sha1_to_hex(want_obj.objects[i].item->sha1));
|
||||
fprintf(pipe_fd, "--not\n");
|
||||
for (i = 0; i < have_obj.nr; i++)
|
||||
fprintf(pipe_fd, "%s\n",
|
||||
sha1_to_hex(have_obj.objects[i].item->sha1));
|
||||
fprintf(pipe_fd, "\n");
|
||||
fflush(pipe_fd);
|
||||
fclose(pipe_fd);
|
||||
}
|
||||
pipe_fd = xfdopen(pack_objects.in, "w");
|
||||
|
||||
for (i = 0; i < want_obj.nr; i++)
|
||||
fprintf(pipe_fd, "%s\n",
|
||||
sha1_to_hex(want_obj.objects[i].item->sha1));
|
||||
fprintf(pipe_fd, "--not\n");
|
||||
for (i = 0; i < have_obj.nr; i++)
|
||||
fprintf(pipe_fd, "%s\n",
|
||||
sha1_to_hex(have_obj.objects[i].item->sha1));
|
||||
for (i = 0; i < extra_edge_obj.nr; i++)
|
||||
fprintf(pipe_fd, "%s\n",
|
||||
sha1_to_hex(extra_edge_obj.objects[i].item->sha1));
|
||||
fprintf(pipe_fd, "\n");
|
||||
fflush(pipe_fd);
|
||||
fclose(pipe_fd);
|
||||
|
||||
/* We read from pack_objects.err to capture stderr output for
|
||||
* progress bar, and pack_objects.out to capture the pack data.
|
||||
@ -291,8 +224,11 @@ static void create_pack_file(void)
|
||||
error("git upload-pack: git-pack-objects died with error.");
|
||||
goto fail;
|
||||
}
|
||||
if (shallow_nr && finish_async(&rev_list))
|
||||
goto fail; /* error was already reported */
|
||||
if (shallow_file) {
|
||||
if (*shallow_file)
|
||||
unlink(shallow_file);
|
||||
free(shallow_file);
|
||||
}
|
||||
|
||||
/* flush the data */
|
||||
if (0 <= buffered) {
|
||||
|
||||
Reference in New Issue
Block a user