Skip to content

Commit f5d942e

Browse files
pcloudspeff
authored andcommitted
send-pack: move core code to libgit.a
send_pack() is used by transport.c, part of libgit.a while it stays in builtin/send-pack.c. Move it to send-pack.c so that we won't get undefined reference if a program that uses libgit.a happens to pull it in. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Jeff King <[email protected]>
1 parent 4914c96 commit f5d942e

File tree

4 files changed

+350
-333
lines changed

4 files changed

+350
-333
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ LIB_OBJS += rerere.o
798798
LIB_OBJS += resolve-undo.o
799799
LIB_OBJS += revision.o
800800
LIB_OBJS += run-command.o
801+
LIB_OBJS += send-pack.o
801802
LIB_OBJS += sequencer.o
802803
LIB_OBJS += server-info.o
803804
LIB_OBJS += setup.o

builtin/send-pack.c

Lines changed: 0 additions & 333 deletions
Original file line numberDiff line numberDiff line change
@@ -16,164 +16,6 @@ static const char send_pack_usage[] =
1616

1717
static struct send_pack_args args;
1818

19-
static int feed_object(const unsigned char *sha1, int fd, int negative)
20-
{
21-
char buf[42];
22-
23-
if (negative && !has_sha1_file(sha1))
24-
return 1;
25-
26-
memcpy(buf + negative, sha1_to_hex(sha1), 40);
27-
if (negative)
28-
buf[0] = '^';
29-
buf[40 + negative] = '\n';
30-
return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs");
31-
}
32-
33-
/*
34-
* Make a pack stream and spit it out into file descriptor fd
35-
*/
36-
static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args)
37-
{
38-
/*
39-
* The child becomes pack-objects --revs; we feed
40-
* the revision parameters to it via its stdin and
41-
* let its stdout go back to the other end.
42-
*/
43-
const char *argv[] = {
44-
"pack-objects",
45-
"--all-progress-implied",
46-
"--revs",
47-
"--stdout",
48-
NULL,
49-
NULL,
50-
NULL,
51-
NULL,
52-
NULL,
53-
};
54-
struct child_process po;
55-
int i;
56-
57-
i = 4;
58-
if (args->use_thin_pack)
59-
argv[i++] = "--thin";
60-
if (args->use_ofs_delta)
61-
argv[i++] = "--delta-base-offset";
62-
if (args->quiet || !args->progress)
63-
argv[i++] = "-q";
64-
if (args->progress)
65-
argv[i++] = "--progress";
66-
memset(&po, 0, sizeof(po));
67-
po.argv = argv;
68-
po.in = -1;
69-
po.out = args->stateless_rpc ? -1 : fd;
70-
po.git_cmd = 1;
71-
if (start_command(&po))
72-
die_errno("git pack-objects failed");
73-
74-
/*
75-
* We feed the pack-objects we just spawned with revision
76-
* parameters by writing to the pipe.
77-
*/
78-
for (i = 0; i < extra->nr; i++)
79-
if (!feed_object(extra->array[i], po.in, 1))
80-
break;
81-
82-
while (refs) {
83-
if (!is_null_sha1(refs->old_sha1) &&
84-
!feed_object(refs->old_sha1, po.in, 1))
85-
break;
86-
if (!is_null_sha1(refs->new_sha1) &&
87-
!feed_object(refs->new_sha1, po.in, 0))
88-
break;
89-
refs = refs->next;
90-
}
91-
92-
close(po.in);
93-
94-
if (args->stateless_rpc) {
95-
char *buf = xmalloc(LARGE_PACKET_MAX);
96-
while (1) {
97-
ssize_t n = xread(po.out, buf, LARGE_PACKET_MAX);
98-
if (n <= 0)
99-
break;
100-
send_sideband(fd, -1, buf, n, LARGE_PACKET_MAX);
101-
}
102-
free(buf);
103-
close(po.out);
104-
po.out = -1;
105-
}
106-
107-
if (finish_command(&po))
108-
return -1;
109-
return 0;
110-
}
111-
112-
static int receive_status(int in, struct ref *refs)
113-
{
114-
struct ref *hint;
115-
char line[1000];
116-
int ret = 0;
117-
int len = packet_read_line(in, line, sizeof(line));
118-
if (len < 10 || memcmp(line, "unpack ", 7))
119-
return error("did not receive remote status");
120-
if (memcmp(line, "unpack ok\n", 10)) {
121-
char *p = line + strlen(line) - 1;
122-
if (*p == '\n')
123-
*p = '\0';
124-
error("unpack failed: %s", line + 7);
125-
ret = -1;
126-
}
127-
hint = NULL;
128-
while (1) {
129-
char *refname;
130-
char *msg;
131-
len = packet_read_line(in, line, sizeof(line));
132-
if (!len)
133-
break;
134-
if (len < 3 ||
135-
(memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) {
136-
fprintf(stderr, "protocol error: %s\n", line);
137-
ret = -1;
138-
break;
139-
}
140-
141-
line[strlen(line)-1] = '\0';
142-
refname = line + 3;
143-
msg = strchr(refname, ' ');
144-
if (msg)
145-
*msg++ = '\0';
146-
147-
/* first try searching at our hint, falling back to all refs */
148-
if (hint)
149-
hint = find_ref_by_name(hint, refname);
150-
if (!hint)
151-
hint = find_ref_by_name(refs, refname);
152-
if (!hint) {
153-
warning("remote reported status on unknown ref: %s",
154-
refname);
155-
continue;
156-
}
157-
if (hint->status != REF_STATUS_EXPECTING_REPORT) {
158-
warning("remote reported status on unexpected ref: %s",
159-
refname);
160-
continue;
161-
}
162-
163-
if (line[0] == 'o' && line[1] == 'k')
164-
hint->status = REF_STATUS_OK;
165-
else {
166-
hint->status = REF_STATUS_REMOTE_REJECT;
167-
ret = -1;
168-
}
169-
if (msg)
170-
hint->remote_status = xstrdup(msg);
171-
/* start our next search from the next ref */
172-
hint = hint->next;
173-
}
174-
return ret;
175-
}
176-
17719
static void print_helper_status(struct ref *ref)
17820
{
17921
struct strbuf buf = STRBUF_INIT;
@@ -227,181 +69,6 @@ static void print_helper_status(struct ref *ref)
22769
strbuf_release(&buf);
22870
}
22971

230-
static int sideband_demux(int in, int out, void *data)
231-
{
232-
int *fd = data, ret;
233-
#ifdef NO_PTHREADS
234-
close(fd[1]);
235-
#endif
236-
ret = recv_sideband("send-pack", fd[0], out);
237-
close(out);
238-
return ret;
239-
}
240-
241-
int send_pack(struct send_pack_args *args,
242-
int fd[], struct child_process *conn,
243-
struct ref *remote_refs,
244-
struct extra_have_objects *extra_have)
245-
{
246-
int in = fd[0];
247-
int out = fd[1];
248-
struct strbuf req_buf = STRBUF_INIT;
249-
struct ref *ref;
250-
int new_refs;
251-
int allow_deleting_refs = 0;
252-
int status_report = 0;
253-
int use_sideband = 0;
254-
int quiet_supported = 0;
255-
int agent_supported = 0;
256-
unsigned cmds_sent = 0;
257-
int ret;
258-
struct async demux;
259-
260-
/* Does the other end support the reporting? */
261-
if (server_supports("report-status"))
262-
status_report = 1;
263-
if (server_supports("delete-refs"))
264-
allow_deleting_refs = 1;
265-
if (server_supports("ofs-delta"))
266-
args->use_ofs_delta = 1;
267-
if (server_supports("side-band-64k"))
268-
use_sideband = 1;
269-
if (server_supports("quiet"))
270-
quiet_supported = 1;
271-
if (server_supports("agent"))
272-
agent_supported = 1;
273-
274-
if (!remote_refs) {
275-
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
276-
"Perhaps you should specify a branch such as 'master'.\n");
277-
return 0;
278-
}
279-
280-
/*
281-
* Finally, tell the other end!
282-
*/
283-
new_refs = 0;
284-
for (ref = remote_refs; ref; ref = ref->next) {
285-
if (!ref->peer_ref && !args->send_mirror)
286-
continue;
287-
288-
/* Check for statuses set by set_ref_status_for_push() */
289-
switch (ref->status) {
290-
case REF_STATUS_REJECT_NONFASTFORWARD:
291-
case REF_STATUS_UPTODATE:
292-
continue;
293-
default:
294-
; /* do nothing */
295-
}
296-
297-
if (ref->deletion && !allow_deleting_refs) {
298-
ref->status = REF_STATUS_REJECT_NODELETE;
299-
continue;
300-
}
301-
302-
if (!ref->deletion)
303-
new_refs++;
304-
305-
if (args->dry_run) {
306-
ref->status = REF_STATUS_OK;
307-
} else {
308-
char *old_hex = sha1_to_hex(ref->old_sha1);
309-
char *new_hex = sha1_to_hex(ref->new_sha1);
310-
int quiet = quiet_supported && (args->quiet || !args->progress);
311-
312-
if (!cmds_sent && (status_report || use_sideband ||
313-
quiet || agent_supported)) {
314-
packet_buf_write(&req_buf,
315-
"%s %s %s%c%s%s%s%s%s",
316-
old_hex, new_hex, ref->name, 0,
317-
status_report ? " report-status" : "",
318-
use_sideband ? " side-band-64k" : "",
319-
quiet ? " quiet" : "",
320-
agent_supported ? " agent=" : "",
321-
agent_supported ? git_user_agent_sanitized() : ""
322-
);
323-
}
324-
else
325-
packet_buf_write(&req_buf, "%s %s %s",
326-
old_hex, new_hex, ref->name);
327-
ref->status = status_report ?
328-
REF_STATUS_EXPECTING_REPORT :
329-
REF_STATUS_OK;
330-
cmds_sent++;
331-
}
332-
}
333-
334-
if (args->stateless_rpc) {
335-
if (!args->dry_run && cmds_sent) {
336-
packet_buf_flush(&req_buf);
337-
send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX);
338-
}
339-
} else {
340-
safe_write(out, req_buf.buf, req_buf.len);
341-
packet_flush(out);
342-
}
343-
strbuf_release(&req_buf);
344-
345-
if (use_sideband && cmds_sent) {
346-
memset(&demux, 0, sizeof(demux));
347-
demux.proc = sideband_demux;
348-
demux.data = fd;
349-
demux.out = -1;
350-
if (start_async(&demux))
351-
die("send-pack: unable to fork off sideband demultiplexer");
352-
in = demux.out;
353-
}
354-
355-
if (new_refs && cmds_sent) {
356-
if (pack_objects(out, remote_refs, extra_have, args) < 0) {
357-
for (ref = remote_refs; ref; ref = ref->next)
358-
ref->status = REF_STATUS_NONE;
359-
if (args->stateless_rpc)
360-
close(out);
361-
if (git_connection_is_socket(conn))
362-
shutdown(fd[0], SHUT_WR);
363-
if (use_sideband)
364-
finish_async(&demux);
365-
return -1;
366-
}
367-
}
368-
if (args->stateless_rpc && cmds_sent)
369-
packet_flush(out);
370-
371-
if (status_report && cmds_sent)
372-
ret = receive_status(in, remote_refs);
373-
else
374-
ret = 0;
375-
if (args->stateless_rpc)
376-
packet_flush(out);
377-
378-
if (use_sideband && cmds_sent) {
379-
if (finish_async(&demux)) {
380-
error("error in sideband demultiplexer");
381-
ret = -1;
382-
}
383-
close(demux.out);
384-
}
385-
386-
if (ret < 0)
387-
return ret;
388-
389-
if (args->porcelain)
390-
return 0;
391-
392-
for (ref = remote_refs; ref; ref = ref->next) {
393-
switch (ref->status) {
394-
case REF_STATUS_NONE:
395-
case REF_STATUS_UPTODATE:
396-
case REF_STATUS_OK:
397-
break;
398-
default:
399-
return -1;
400-
}
401-
}
402-
return 0;
403-
}
404-
40572
int cmd_send_pack(int argc, const char **argv, const char *prefix)
40673
{
40774
int i, nr_refspecs = 0;

0 commit comments

Comments
 (0)