Skip to content

Commit cdab485

Browse files
pcloudsgitster
authored andcommitted
upload-pack: delegate rev walking in shallow fetch to pack-objects
upload-pack has a special revision walking code for shallow recipients. It works almost like the similar code in pack-objects except: 1. in upload-pack, graft points could be added for deepening; 2. also when the repository is deepened, the shallow point will be moved further away from the tip, but the old shallow point will be marked as edge to produce more efficient packs. See 6523078 (make shallow repository deepening more network efficient - 2009-09-03). Pass the file to pack-objects via --shallow-file. This will override $GIT_DIR/shallow and give pack-objects the exact repository shape that upload-pack has. mark edge commits by revision command arguments. Even if old shallow points are passed as "--not" revisions as in this patch, they will not be picked up by mark_edges_uninteresting() because this function looks up to parents for edges, while in this case the edge is the children, in the opposite direction. This will be fixed in an later patch when all given uninteresting commits are marked as edges. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 08ea65a commit cdab485

File tree

2 files changed

+32
-99
lines changed

2 files changed

+32
-99
lines changed

t/t5530-upload-pack-error.sh

-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ test_expect_success 'upload-pack fails due to error in rev-list' '
5454
printf "0032want %s\n0034shallow %s00000009done\n0000" \
5555
$(git rev-parse HEAD) $(git rev-parse HEAD^) >input &&
5656
test_must_fail git upload-pack . <input >/dev/null 2>output.err &&
57-
# pack-objects survived
58-
grep "Total.*, reused" output.err &&
59-
# but there was an error, which must have been in rev-list
6057
grep "bad tree object" output.err
6158
'
6259

upload-pack.c

+32-96
Original file line numberDiff line numberDiff line change
@@ -68,87 +68,28 @@ static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
6868
return sz;
6969
}
7070

71-
static FILE *pack_pipe = NULL;
72-
static void show_commit(struct commit *commit, void *data)
73-
{
74-
if (commit->object.flags & BOUNDARY)
75-
fputc('-', pack_pipe);
76-
if (fputs(sha1_to_hex(commit->object.sha1), pack_pipe) < 0)
77-
die("broken output pipe");
78-
fputc('\n', pack_pipe);
79-
fflush(pack_pipe);
80-
free(commit->buffer);
81-
commit->buffer = NULL;
82-
}
83-
84-
static void show_object(struct object *obj,
85-
const struct name_path *path, const char *component,
86-
void *cb_data)
87-
{
88-
show_object_with_name(pack_pipe, obj, path, component);
89-
}
90-
91-
static void show_edge(struct commit *commit)
92-
{
93-
fprintf(pack_pipe, "-%s\n", sha1_to_hex(commit->object.sha1));
94-
}
95-
96-
static int do_rev_list(int in, int out, void *user_data)
97-
{
98-
int i;
99-
struct rev_info revs;
100-
101-
pack_pipe = xfdopen(out, "w");
102-
init_revisions(&revs, NULL);
103-
revs.tag_objects = 1;
104-
revs.tree_objects = 1;
105-
revs.blob_objects = 1;
106-
if (use_thin_pack)
107-
revs.edge_hint = 1;
108-
109-
for (i = 0; i < want_obj.nr; i++) {
110-
struct object *o = want_obj.objects[i].item;
111-
/* why??? */
112-
o->flags &= ~UNINTERESTING;
113-
add_pending_object(&revs, o, NULL);
114-
}
115-
for (i = 0; i < have_obj.nr; i++) {
116-
struct object *o = have_obj.objects[i].item;
117-
o->flags |= UNINTERESTING;
118-
add_pending_object(&revs, o, NULL);
119-
}
120-
setup_revisions(0, NULL, &revs, NULL);
121-
if (prepare_revision_walk(&revs))
122-
die("revision walk setup failed");
123-
mark_edges_uninteresting(revs.commits, &revs, show_edge);
124-
if (use_thin_pack)
125-
for (i = 0; i < extra_edge_obj.nr; i++)
126-
fprintf(pack_pipe, "-%s\n", sha1_to_hex(
127-
extra_edge_obj.objects[i].item->sha1));
128-
traverse_commit_list(&revs, show_commit, show_object, NULL);
129-
fflush(pack_pipe);
130-
fclose(pack_pipe);
131-
return 0;
132-
}
133-
13471
static void create_pack_file(void)
13572
{
136-
struct async rev_list;
13773
struct child_process pack_objects;
13874
char data[8193], progress[128];
13975
char abort_msg[] = "aborting due to possible repository "
14076
"corruption on the remote side.";
14177
int buffered = -1;
14278
ssize_t sz;
143-
const char *argv[10];
144-
int arg = 0;
79+
const char *argv[12];
80+
int i, arg = 0;
81+
FILE *pipe_fd;
82+
char *shallow_file = NULL;
14583

146-
argv[arg++] = "pack-objects";
147-
if (!shallow_nr) {
148-
argv[arg++] = "--revs";
149-
if (use_thin_pack)
150-
argv[arg++] = "--thin";
84+
if (shallow_nr) {
85+
shallow_file = setup_temporary_shallow();
86+
argv[arg++] = "--shallow-file";
87+
argv[arg++] = shallow_file;
15188
}
89+
argv[arg++] = "pack-objects";
90+
argv[arg++] = "--revs";
91+
if (use_thin_pack)
92+
argv[arg++] = "--thin";
15293

15394
argv[arg++] = "--stdout";
15495
if (!no_progress)
@@ -169,29 +110,21 @@ static void create_pack_file(void)
169110
if (start_command(&pack_objects))
170111
die("git upload-pack: unable to fork git-pack-objects");
171112

172-
if (shallow_nr) {
173-
memset(&rev_list, 0, sizeof(rev_list));
174-
rev_list.proc = do_rev_list;
175-
rev_list.out = pack_objects.in;
176-
if (start_async(&rev_list))
177-
die("git upload-pack: unable to fork git-rev-list");
178-
}
179-
else {
180-
FILE *pipe_fd = xfdopen(pack_objects.in, "w");
181-
int i;
182-
183-
for (i = 0; i < want_obj.nr; i++)
184-
fprintf(pipe_fd, "%s\n",
185-
sha1_to_hex(want_obj.objects[i].item->sha1));
186-
fprintf(pipe_fd, "--not\n");
187-
for (i = 0; i < have_obj.nr; i++)
188-
fprintf(pipe_fd, "%s\n",
189-
sha1_to_hex(have_obj.objects[i].item->sha1));
190-
fprintf(pipe_fd, "\n");
191-
fflush(pipe_fd);
192-
fclose(pipe_fd);
193-
}
194-
113+
pipe_fd = xfdopen(pack_objects.in, "w");
114+
115+
for (i = 0; i < want_obj.nr; i++)
116+
fprintf(pipe_fd, "%s\n",
117+
sha1_to_hex(want_obj.objects[i].item->sha1));
118+
fprintf(pipe_fd, "--not\n");
119+
for (i = 0; i < have_obj.nr; i++)
120+
fprintf(pipe_fd, "%s\n",
121+
sha1_to_hex(have_obj.objects[i].item->sha1));
122+
for (i = 0; i < extra_edge_obj.nr; i++)
123+
fprintf(pipe_fd, "%s\n",
124+
sha1_to_hex(extra_edge_obj.objects[i].item->sha1));
125+
fprintf(pipe_fd, "\n");
126+
fflush(pipe_fd);
127+
fclose(pipe_fd);
195128

196129
/* We read from pack_objects.err to capture stderr output for
197130
* progress bar, and pack_objects.out to capture the pack data.
@@ -290,8 +223,11 @@ static void create_pack_file(void)
290223
error("git upload-pack: git-pack-objects died with error.");
291224
goto fail;
292225
}
293-
if (shallow_nr && finish_async(&rev_list))
294-
goto fail; /* error was already reported */
226+
if (shallow_file) {
227+
if (*shallow_file)
228+
unlink(shallow_file);
229+
free(shallow_file);
230+
}
295231

296232
/* flush the data */
297233
if (0 <= buffered) {

0 commit comments

Comments
 (0)