11 static const char fetch_pack_usage
[] =
12 "git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory <refs>...";
13 static const char *exec
= "git-upload-pack";
15 static int find_common(int fd
[2], unsigned char *result_sha1
,
19 static char line
[1000];
20 int count
= 0, flushes
= 0, retval
;
23 revs
= popen("git-rev-list $(git-rev-parse --all)", "r");
25 die("unable to run 'git-rev-list'");
28 for ( ; refs
; refs
= refs
->next
) {
29 unsigned char *remote
= refs
->old_sha1
;
30 unsigned char *local
= refs
->new_sha1
;
32 if (!memcmp(remote
, local
, 20))
34 packet_write(fd
[1], "want %s\n", sha1_to_hex(remote
));
42 while (fgets(line
, sizeof(line
), revs
) != NULL
) {
43 unsigned char sha1
[20];
44 if (get_sha1_hex(line
, sha1
))
45 die("git-fetch-pack: expected object name, got crud");
46 packet_write(fd
[1], "have %s\n", sha1_to_hex(sha1
));
48 fprintf(stderr
, "have %s\n", sha1_to_hex(sha1
));
49 if (!(31 & ++count
)) {
54 * We keep one window "ahead" of the other side, and
55 * will wait for an ACK only on the next one
59 if (get_ack(fd
[0], result_sha1
)) {
63 fprintf(stderr
, "got ack\n");
70 packet_write(fd
[1], "done\n");
72 fprintf(stderr
, "done\n");
75 if (get_ack(fd
[0], result_sha1
)) {
77 fprintf(stderr
, "got ack\n");
84 #define COMPLETE (1U << 0)
85 static struct commit_list
*complete
= NULL
;
87 static int mark_complete(const char *path
, const unsigned char *sha1
)
89 struct object
*o
= parse_object(sha1
);
91 while (o
&& o
->type
== tag_type
) {
93 o
= parse_object(((struct tag
*)o
)->tagged
->sha1
);
95 if (o
->type
== commit_type
) {
96 struct commit
*commit
= (struct commit
*)o
;
97 commit
->object
.flags
|= COMPLETE
;
98 insert_by_date(commit
, &complete
);
103 static void mark_recent_complete_commits(unsigned long cutoff
)
105 while (complete
&& cutoff
<= complete
->item
->date
) {
107 fprintf(stderr
, "Marking %s as complete\n",
108 sha1_to_hex(complete
->item
->object
.sha1
));
109 pop_most_recent_commit(&complete
, COMPLETE
);
113 static int everything_local(struct ref
*refs
)
117 unsigned long cutoff
= 0;
119 track_object_refs
= 0;
120 save_commit_buffer
= 0;
122 for (ref
= refs
; ref
; ref
= ref
->next
) {
125 o
= parse_object(ref
->old_sha1
);
129 /* We already have it -- which may mean that we were
130 * in sync with the other side at some time after
131 * that (it is OK if we guess wrong here).
133 if (o
->type
== commit_type
) {
134 struct commit
*commit
= (struct commit
*)o
;
135 if (!cutoff
|| cutoff
< commit
->date
)
136 cutoff
= commit
->date
;
140 for_each_ref(mark_complete
);
142 mark_recent_complete_commits(cutoff
);
144 for (retval
= 1; refs
; refs
= refs
->next
) {
145 const unsigned char *remote
= refs
->old_sha1
;
146 unsigned char local
[20];
149 o
= parse_object(remote
);
150 if (!o
|| !(o
->flags
& COMPLETE
)) {
155 "want %s (%s)\n", sha1_to_hex(remote
),
160 memcpy(refs
->new_sha1
, local
, 20);
164 "already have %s (%s)\n", sha1_to_hex(remote
),
170 static int fetch_pack(int fd
[2], int nr_match
, char **match
)
173 unsigned char sha1
[20];
177 get_remote_heads(fd
[0], &ref
, nr_match
, match
, 1);
180 die("no matching remote head");
182 if (everything_local(ref
)) {
186 if (find_common(fd
, sha1
, ref
) < 0)
187 fprintf(stderr
, "warning: no common commits\n");
190 die("git-fetch-pack: unable to fork off git-unpack-objects");
195 execlp("git-unpack-objects", "git-unpack-objects",
196 quiet
? "-q" : NULL
, NULL
);
197 die("git-unpack-objects exec failed");
201 while (waitpid(pid
, &status
, 0) < 0) {
203 die("waiting for git-unpack-objects: %s", strerror(errno
));
205 if (WIFEXITED(status
)) {
206 int code
= WEXITSTATUS(status
);
208 die("git-unpack-objects died with error code %d", code
);
212 sha1_to_hex(ref
->old_sha1
), ref
->name
);
217 if (WIFSIGNALED(status
)) {
218 int sig
= WTERMSIG(status
);
219 die("git-unpack-objects died of signal %d", sig
);
221 die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status
);
224 int main(int argc
, char **argv
)
226 int i
, ret
, nr_heads
;
227 char *dest
= NULL
, **heads
;
233 for (i
= 1; i
< argc
; i
++) {
237 if (!strncmp("--exec=", arg
, 7)) {
241 if (!strcmp("-q", arg
)) {
245 if (!strcmp("-v", arg
)) {
249 usage(fetch_pack_usage
);
252 heads
= argv
+ i
+ 1;
253 nr_heads
= argc
- i
- 1;
257 usage(fetch_pack_usage
);
258 pid
= git_connect(fd
, dest
, exec
);
261 ret
= fetch_pack(fd
, nr_heads
, heads
);