Skip to content

Commit a2d725b

Browse files
iabervongitster
authored andcommitted
Use an external program to implement fetching with curl
Use the transport native helper mechanism to fetch by http (and ftp, etc). Signed-off-by: Daniel Barkalow <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6eb996b commit a2d725b

File tree

3 files changed

+145
-135
lines changed

3 files changed

+145
-135
lines changed

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,7 @@ else
981981
CURL_LIBCURL = -lcurl
982982
endif
983983
BUILTIN_OBJS += builtin-http-fetch.o
984+
PROGRAMS += git-remote-http$X git-remote-https$X git-remote-ftp$X git-http-fetch$X
984985
EXTLIBS += $(CURL_LIBCURL)
985986
LIB_OBJS += http.o http-walker.o
986987
curl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p)
@@ -1491,6 +1492,10 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
14911492
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
14921493
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
14931494

1495+
git-remote-http$X git-remote-https$X git-remote-ftp$X: remote-curl.o http.o http-walker.o $(GITLIBS)
1496+
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
1497+
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
1498+
14941499
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
14951500
$(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h)
14961501
builtin-revert.o wt-status.o: wt-status.h

remote-curl.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#include "cache.h"
2+
#include "remote.h"
3+
#include "strbuf.h"
4+
#include "walker.h"
5+
#include "http.h"
6+
7+
static struct ref *get_refs(struct walker *walker, const char *url)
8+
{
9+
struct strbuf buffer = STRBUF_INIT;
10+
char *data, *start, *mid;
11+
char *ref_name;
12+
char *refs_url;
13+
int i = 0;
14+
int http_ret;
15+
16+
struct ref *refs = NULL;
17+
struct ref *ref = NULL;
18+
struct ref *last_ref = NULL;
19+
20+
refs_url = xmalloc(strlen(url) + 11);
21+
sprintf(refs_url, "%s/info/refs", url);
22+
23+
http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
24+
switch (http_ret) {
25+
case HTTP_OK:
26+
break;
27+
case HTTP_MISSING_TARGET:
28+
die("%s not found: did you run git update-server-info on the"
29+
" server?", refs_url);
30+
default:
31+
http_error(refs_url, http_ret);
32+
die("HTTP request failed");
33+
}
34+
35+
data = buffer.buf;
36+
start = NULL;
37+
mid = data;
38+
while (i < buffer.len) {
39+
if (!start) {
40+
start = &data[i];
41+
}
42+
if (data[i] == '\t')
43+
mid = &data[i];
44+
if (data[i] == '\n') {
45+
data[i] = 0;
46+
ref_name = mid + 1;
47+
ref = xmalloc(sizeof(struct ref) +
48+
strlen(ref_name) + 1);
49+
memset(ref, 0, sizeof(struct ref));
50+
strcpy(ref->name, ref_name);
51+
get_sha1_hex(start, ref->old_sha1);
52+
if (!refs)
53+
refs = ref;
54+
if (last_ref)
55+
last_ref->next = ref;
56+
last_ref = ref;
57+
start = NULL;
58+
}
59+
i++;
60+
}
61+
62+
strbuf_release(&buffer);
63+
64+
ref = alloc_ref("HEAD");
65+
if (!walker->fetch_ref(walker, ref) &&
66+
!resolve_remote_symref(ref, refs)) {
67+
ref->next = refs;
68+
refs = ref;
69+
} else {
70+
free(ref);
71+
}
72+
73+
strbuf_release(&buffer);
74+
free(refs_url);
75+
return refs;
76+
}
77+
78+
int main(int argc, const char **argv)
79+
{
80+
struct remote *remote;
81+
struct strbuf buf = STRBUF_INIT;
82+
const char *url;
83+
struct walker *walker = NULL;
84+
85+
setup_git_directory();
86+
if (argc < 2) {
87+
fprintf(stderr, "Remote needed\n");
88+
return 1;
89+
}
90+
91+
remote = remote_get(argv[1]);
92+
93+
if (argc > 2) {
94+
url = argv[2];
95+
} else {
96+
url = remote->url[0];
97+
}
98+
99+
do {
100+
if (strbuf_getline(&buf, stdin, '\n') == EOF)
101+
break;
102+
if (!prefixcmp(buf.buf, "fetch ")) {
103+
char *obj = buf.buf + strlen("fetch ");
104+
if (!walker)
105+
walker = get_http_walker(url, remote);
106+
walker->get_all = 1;
107+
walker->get_tree = 1;
108+
walker->get_history = 1;
109+
walker->get_verbosely = 0;
110+
walker->get_recover = 0;
111+
if (walker_fetch(walker, 1, &obj, NULL, NULL))
112+
die("Fetch failed.");
113+
printf("\n");
114+
fflush(stdout);
115+
} else if (!strcmp(buf.buf, "list")) {
116+
struct ref *refs;
117+
struct ref *posn;
118+
if (!walker)
119+
walker = get_http_walker(url, remote);
120+
refs = get_refs(walker, url);
121+
for (posn = refs; posn; posn = posn->next) {
122+
if (posn->symref)
123+
printf("@%s %s\n", posn->symref, posn->name);
124+
else
125+
printf("%s %s\n", sha1_to_hex(posn->old_sha1), posn->name);
126+
}
127+
printf("\n");
128+
fflush(stdout);
129+
} else if (!strcmp(buf.buf, "capabilities")) {
130+
printf("fetch\n");
131+
printf("\n");
132+
fflush(stdout);
133+
} else {
134+
return 1;
135+
}
136+
strbuf_reset(&buf);
137+
} while (1);
138+
return 0;
139+
}

transport.c

Lines changed: 1 addition & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#include "cache.h"
22
#include "transport.h"
33
#include "run-command.h"
4-
#ifndef NO_CURL
5-
#include "http.h"
6-
#endif
74
#include "pkt-line.h"
85
#include "fetch-pack.h"
96
#include "send-pack.h"
@@ -352,45 +349,6 @@ static int rsync_transport_push(struct transport *transport,
352349
return result;
353350
}
354351

355-
/* Generic functions for using commit walkers */
356-
357-
#ifndef NO_CURL /* http fetch is the only user */
358-
static int fetch_objs_via_walker(struct transport *transport,
359-
int nr_objs, const struct ref **to_fetch)
360-
{
361-
char *dest = xstrdup(transport->url);
362-
struct walker *walker = transport->data;
363-
char **objs = xmalloc(nr_objs * sizeof(*objs));
364-
int i;
365-
366-
walker->get_all = 1;
367-
walker->get_tree = 1;
368-
walker->get_history = 1;
369-
walker->get_verbosely = transport->verbose >= 0;
370-
walker->get_recover = 0;
371-
372-
for (i = 0; i < nr_objs; i++)
373-
objs[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1));
374-
375-
if (walker_fetch(walker, nr_objs, objs, NULL, NULL))
376-
die("Fetch failed.");
377-
378-
for (i = 0; i < nr_objs; i++)
379-
free(objs[i]);
380-
free(objs);
381-
free(dest);
382-
return 0;
383-
}
384-
#endif /* NO_CURL */
385-
386-
static int disconnect_walker(struct transport *transport)
387-
{
388-
struct walker *walker = transport->data;
389-
if (walker)
390-
walker_free(walker);
391-
return 0;
392-
}
393-
394352
#ifndef NO_CURL
395353
static int curl_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags)
396354
{
@@ -432,96 +390,6 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
432390
return !!err;
433391
}
434392

435-
static struct ref *get_refs_via_curl(struct transport *transport, int for_push)
436-
{
437-
struct strbuf buffer = STRBUF_INIT;
438-
char *data, *start, *mid;
439-
char *ref_name;
440-
char *refs_url;
441-
int i = 0;
442-
int http_ret;
443-
444-
struct ref *refs = NULL;
445-
struct ref *ref = NULL;
446-
struct ref *last_ref = NULL;
447-
448-
struct walker *walker;
449-
450-
if (for_push)
451-
return NULL;
452-
453-
if (!transport->data)
454-
transport->data = get_http_walker(transport->url,
455-
transport->remote);
456-
457-
walker = transport->data;
458-
459-
refs_url = xmalloc(strlen(transport->url) + 11);
460-
sprintf(refs_url, "%s/info/refs", transport->url);
461-
462-
http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
463-
switch (http_ret) {
464-
case HTTP_OK:
465-
break;
466-
case HTTP_MISSING_TARGET:
467-
die("%s not found: did you run git update-server-info on the"
468-
" server?", refs_url);
469-
default:
470-
http_error(refs_url, http_ret);
471-
die("HTTP request failed");
472-
}
473-
474-
data = buffer.buf;
475-
start = NULL;
476-
mid = data;
477-
while (i < buffer.len) {
478-
if (!start)
479-
start = &data[i];
480-
if (data[i] == '\t')
481-
mid = &data[i];
482-
if (data[i] == '\n') {
483-
data[i] = 0;
484-
ref_name = mid + 1;
485-
ref = xmalloc(sizeof(struct ref) +
486-
strlen(ref_name) + 1);
487-
memset(ref, 0, sizeof(struct ref));
488-
strcpy(ref->name, ref_name);
489-
get_sha1_hex(start, ref->old_sha1);
490-
if (!refs)
491-
refs = ref;
492-
if (last_ref)
493-
last_ref->next = ref;
494-
last_ref = ref;
495-
start = NULL;
496-
}
497-
i++;
498-
}
499-
500-
strbuf_release(&buffer);
501-
502-
ref = alloc_ref("HEAD");
503-
if (!walker->fetch_ref(walker, ref) &&
504-
!resolve_remote_symref(ref, refs)) {
505-
ref->next = refs;
506-
refs = ref;
507-
} else {
508-
free(ref);
509-
}
510-
511-
strbuf_release(&buffer);
512-
free(refs_url);
513-
return refs;
514-
}
515-
516-
static int fetch_objs_via_curl(struct transport *transport,
517-
int nr_objs, const struct ref **to_fetch)
518-
{
519-
if (!transport->data)
520-
transport->data = get_http_walker(transport->url,
521-
transport->remote);
522-
return fetch_objs_via_walker(transport, nr_objs, to_fetch);
523-
}
524-
525393
#endif
526394

527395
struct bundle_transport_data {
@@ -950,14 +818,12 @@ struct transport *transport_get(struct remote *remote, const char *url)
950818
} else if (!prefixcmp(url, "http://")
951819
|| !prefixcmp(url, "https://")
952820
|| !prefixcmp(url, "ftp://")) {
821+
transport_helper_init(ret);
953822
#ifdef NO_CURL
954823
error("git was compiled without libcurl support.");
955824
#else
956-
ret->get_refs_list = get_refs_via_curl;
957-
ret->fetch = fetch_objs_via_curl;
958825
ret->push = curl_transport_push;
959826
#endif
960-
ret->disconnect = disconnect_walker;
961827

962828
} else if (is_local(url) && is_file(url)) {
963829
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));

0 commit comments

Comments
 (0)