Code

Merge branch 'jc/rerere-remaining' into pu
[git.git] / http-push.c
1 #include "cache.h"
2 #include "commit.h"
3 #include "tag.h"
4 #include "blob.h"
5 #include "http.h"
6 #include "refs.h"
7 #include "diff.h"
8 #include "revision.h"
9 #include "exec_cmd.h"
10 #include "remote.h"
11 #include "list-objects.h"
12 #include "sigchain.h"
13 #include "gettext.h"
15 #include <expat.h>
17 static const char http_push_usage[] =
18 "git http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]\n";
20 #ifndef XML_STATUS_OK
21 enum XML_Status {
22   XML_STATUS_OK = 1,
23   XML_STATUS_ERROR = 0
24 };
25 #define XML_STATUS_OK    1
26 #define XML_STATUS_ERROR 0
27 #endif
29 #define PREV_BUF_SIZE 4096
31 /* DAV methods */
32 #define DAV_LOCK "LOCK"
33 #define DAV_MKCOL "MKCOL"
34 #define DAV_MOVE "MOVE"
35 #define DAV_PROPFIND "PROPFIND"
36 #define DAV_PUT "PUT"
37 #define DAV_UNLOCK "UNLOCK"
38 #define DAV_DELETE "DELETE"
40 /* DAV lock flags */
41 #define DAV_PROP_LOCKWR (1u << 0)
42 #define DAV_PROP_LOCKEX (1u << 1)
43 #define DAV_LOCK_OK (1u << 2)
45 /* DAV XML properties */
46 #define DAV_CTX_LOCKENTRY ".multistatus.response.propstat.prop.supportedlock.lockentry"
47 #define DAV_CTX_LOCKTYPE_WRITE ".multistatus.response.propstat.prop.supportedlock.lockentry.locktype.write"
48 #define DAV_CTX_LOCKTYPE_EXCLUSIVE ".multistatus.response.propstat.prop.supportedlock.lockentry.lockscope.exclusive"
49 #define DAV_ACTIVELOCK_OWNER ".prop.lockdiscovery.activelock.owner.href"
50 #define DAV_ACTIVELOCK_TIMEOUT ".prop.lockdiscovery.activelock.timeout"
51 #define DAV_ACTIVELOCK_TOKEN ".prop.lockdiscovery.activelock.locktoken.href"
52 #define DAV_PROPFIND_RESP ".multistatus.response"
53 #define DAV_PROPFIND_NAME ".multistatus.response.href"
54 #define DAV_PROPFIND_COLLECTION ".multistatus.response.propstat.prop.resourcetype.collection"
56 /* DAV request body templates */
57 #define PROPFIND_SUPPORTEDLOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:prop xmlns:R=\"%s\">\n<D:supportedlock/>\n</D:prop>\n</D:propfind>"
58 #define PROPFIND_ALL_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:allprop/>\n</D:propfind>"
59 #define LOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:lockinfo xmlns:D=\"DAV:\">\n<D:lockscope><D:exclusive/></D:lockscope>\n<D:locktype><D:write/></D:locktype>\n<D:owner>\n<D:href>mailto:%s</D:href>\n</D:owner>\n</D:lockinfo>"
61 #define LOCK_TIME 600
62 #define LOCK_REFRESH 30
64 /* bits #0-15 in revision.h */
66 #define LOCAL    (1u<<16)
67 #define REMOTE   (1u<<17)
68 #define FETCHING (1u<<18)
69 #define PUSHING  (1u<<19)
71 /* We allow "recursive" symbolic refs. Only within reason, though */
72 #define MAXDEPTH 5
74 static int pushing;
75 static int aborted;
76 static signed char remote_dir_exists[256];
78 static int push_verbosely;
79 static int push_all = MATCH_REFS_NONE;
80 static int force_all;
81 static int dry_run;
82 static int helper_status;
84 static struct object_list *objects;
86 struct repo
87 {
88         char *url;
89         char *path;
90         int path_len;
91         int has_info_refs;
92         int can_update_info_refs;
93         int has_info_packs;
94         struct packed_git *packs;
95         struct remote_lock *locks;
96 };
98 static struct repo *repo;
100 enum transfer_state {
101         NEED_FETCH,
102         RUN_FETCH_LOOSE,
103         RUN_FETCH_PACKED,
104         NEED_PUSH,
105         RUN_MKCOL,
106         RUN_PUT,
107         RUN_MOVE,
108         ABORTED,
109         COMPLETE
110 };
112 struct transfer_request
114         struct object *obj;
115         char *url;
116         char *dest;
117         struct remote_lock *lock;
118         struct curl_slist *headers;
119         struct buffer buffer;
120         enum transfer_state state;
121         CURLcode curl_result;
122         char errorstr[CURL_ERROR_SIZE];
123         long http_code;
124         void *userData;
125         struct active_request_slot *slot;
126         struct transfer_request *next;
127 };
129 static struct transfer_request *request_queue_head;
131 struct xml_ctx
133         char *name;
134         int len;
135         char *cdata;
136         void (*userFunc)(struct xml_ctx *ctx, int tag_closed);
137         void *userData;
138 };
140 struct remote_lock
142         char *url;
143         char *owner;
144         char *token;
145         char tmpfile_suffix[41];
146         time_t start_time;
147         long timeout;
148         int refreshing;
149         struct remote_lock *next;
150 };
152 /* Flags that control remote_ls processing */
153 #define PROCESS_FILES (1u << 0)
154 #define PROCESS_DIRS  (1u << 1)
155 #define RECURSIVE     (1u << 2)
157 /* Flags that remote_ls passes to callback functions */
158 #define IS_DIR (1u << 0)
160 struct remote_ls_ctx
162         char *path;
163         void (*userFunc)(struct remote_ls_ctx *ls);
164         void *userData;
165         int flags;
166         char *dentry_name;
167         int dentry_flags;
168         struct remote_ls_ctx *parent;
169 };
171 /* get_dav_token_headers options */
172 enum dav_header_flag {
173         DAV_HEADER_IF = (1u << 0),
174         DAV_HEADER_LOCK = (1u << 1),
175         DAV_HEADER_TIMEOUT = (1u << 2)
176 };
178 static char *xml_entities(char *s)
180         struct strbuf buf = STRBUF_INIT;
181         while (*s) {
182                 size_t len = strcspn(s, "\"<>&");
183                 strbuf_add(&buf, s, len);
184                 s += len;
185                 switch (*s) {
186                 case '"':
187                         strbuf_addstr(&buf, "&quot;");
188                         break;
189                 case '<':
190                         strbuf_addstr(&buf, "&lt;");
191                         break;
192                 case '>':
193                         strbuf_addstr(&buf, "&gt;");
194                         break;
195                 case '&':
196                         strbuf_addstr(&buf, "&amp;");
197                         break;
198                 case 0:
199                         return strbuf_detach(&buf, NULL);
200                 }
201                 s++;
202         }
203         return strbuf_detach(&buf, NULL);
206 static struct curl_slist *get_dav_token_headers(struct remote_lock *lock, enum dav_header_flag options)
208         struct strbuf buf = STRBUF_INIT;
209         struct curl_slist *dav_headers = NULL;
211         if (options & DAV_HEADER_IF) {
212                 strbuf_addf(&buf, "If: (<%s>)", lock->token);
213                 dav_headers = curl_slist_append(dav_headers, buf.buf);
214                 strbuf_reset(&buf);
215         }
216         if (options & DAV_HEADER_LOCK) {
217                 strbuf_addf(&buf, "Lock-Token: <%s>", lock->token);
218                 dav_headers = curl_slist_append(dav_headers, buf.buf);
219                 strbuf_reset(&buf);
220         }
221         if (options & DAV_HEADER_TIMEOUT) {
222                 strbuf_addf(&buf, "Timeout: Second-%ld", lock->timeout);
223                 dav_headers = curl_slist_append(dav_headers, buf.buf);
224                 strbuf_reset(&buf);
225         }
226         strbuf_release(&buf);
228         return dav_headers;
231 static void finish_request(struct transfer_request *request);
232 static void release_request(struct transfer_request *request);
234 static void process_response(void *callback_data)
236         struct transfer_request *request =
237                 (struct transfer_request *)callback_data;
239         finish_request(request);
242 #ifdef USE_CURL_MULTI
244 static void start_fetch_loose(struct transfer_request *request)
246         struct active_request_slot *slot;
247         struct http_object_request *obj_req;
249         obj_req = new_http_object_request(repo->url, request->obj->sha1);
250         if (obj_req == NULL) {
251                 request->state = ABORTED;
252                 return;
253         }
255         slot = obj_req->slot;
256         slot->callback_func = process_response;
257         slot->callback_data = request;
258         request->slot = slot;
259         request->userData = obj_req;
261         /* Try to get the request started, abort the request on error */
262         request->state = RUN_FETCH_LOOSE;
263         if (!start_active_slot(slot)) {
264                 fprintf(stderr, "Unable to start GET request\n");
265                 repo->can_update_info_refs = 0;
266                 release_http_object_request(obj_req);
267                 release_request(request);
268         }
271 static void start_mkcol(struct transfer_request *request)
273         char *hex = sha1_to_hex(request->obj->sha1);
274         struct active_request_slot *slot;
276         request->url = get_remote_object_url(repo->url, hex, 1);
278         slot = get_active_slot();
279         slot->callback_func = process_response;
280         slot->callback_data = request;
281         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
282         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
283         curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
284         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
285         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
287         if (start_active_slot(slot)) {
288                 request->slot = slot;
289                 request->state = RUN_MKCOL;
290         } else {
291                 request->state = ABORTED;
292                 free(request->url);
293                 request->url = NULL;
294         }
296 #endif
298 static void start_fetch_packed(struct transfer_request *request)
300         struct packed_git *target;
302         struct transfer_request *check_request = request_queue_head;
303         struct http_pack_request *preq;
305         target = find_sha1_pack(request->obj->sha1, repo->packs);
306         if (!target) {
307                 fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", sha1_to_hex(request->obj->sha1));
308                 repo->can_update_info_refs = 0;
309                 release_request(request);
310                 return;
311         }
313         fprintf(stderr, "Fetching pack %s\n", sha1_to_hex(target->sha1));
314         fprintf(stderr, " which contains %s\n", sha1_to_hex(request->obj->sha1));
316         preq = new_http_pack_request(target, repo->url);
317         if (preq == NULL) {
318                 release_http_pack_request(preq);
319                 repo->can_update_info_refs = 0;
320                 return;
321         }
322         preq->lst = &repo->packs;
324         /* Make sure there isn't another open request for this pack */
325         while (check_request) {
326                 if (check_request->state == RUN_FETCH_PACKED &&
327                     !strcmp(check_request->url, preq->url)) {
328                         release_http_pack_request(preq);
329                         release_request(request);
330                         return;
331                 }
332                 check_request = check_request->next;
333         }
335         preq->slot->callback_func = process_response;
336         preq->slot->callback_data = request;
337         request->slot = preq->slot;
338         request->userData = preq;
340         /* Try to get the request started, abort the request on error */
341         request->state = RUN_FETCH_PACKED;
342         if (!start_active_slot(preq->slot)) {
343                 fprintf(stderr, "Unable to start GET request\n");
344                 release_http_pack_request(preq);
345                 repo->can_update_info_refs = 0;
346                 release_request(request);
347         }
350 static void start_put(struct transfer_request *request)
352         char *hex = sha1_to_hex(request->obj->sha1);
353         struct active_request_slot *slot;
354         struct strbuf buf = STRBUF_INIT;
355         enum object_type type;
356         char hdr[50];
357         void *unpacked;
358         unsigned long len;
359         int hdrlen;
360         ssize_t size;
361         z_stream stream;
363         unpacked = read_sha1_file(request->obj->sha1, &type, &len);
364         hdrlen = sprintf(hdr, "%s %lu", typename(type), len) + 1;
366         /* Set it up */
367         memset(&stream, 0, sizeof(stream));
368         deflateInit(&stream, zlib_compression_level);
369         size = deflateBound(&stream, len + hdrlen);
370         strbuf_init(&request->buffer.buf, size);
371         request->buffer.posn = 0;
373         /* Compress it */
374         stream.next_out = (unsigned char *)request->buffer.buf.buf;
375         stream.avail_out = size;
377         /* First header.. */
378         stream.next_in = (void *)hdr;
379         stream.avail_in = hdrlen;
380         while (deflate(&stream, 0) == Z_OK)
381                 /* nothing */;
383         /* Then the data itself.. */
384         stream.next_in = unpacked;
385         stream.avail_in = len;
386         while (deflate(&stream, Z_FINISH) == Z_OK)
387                 /* nothing */;
388         deflateEnd(&stream);
389         free(unpacked);
391         request->buffer.buf.len = stream.total_out;
393         strbuf_addstr(&buf, "Destination: ");
394         append_remote_object_url(&buf, repo->url, hex, 0);
395         request->dest = strbuf_detach(&buf, NULL);
397         append_remote_object_url(&buf, repo->url, hex, 0);
398         strbuf_add(&buf, request->lock->tmpfile_suffix, 41);
399         request->url = strbuf_detach(&buf, NULL);
401         slot = get_active_slot();
402         slot->callback_func = process_response;
403         slot->callback_data = request;
404         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &request->buffer);
405         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.buf.len);
406         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
407 #ifndef NO_CURL_IOCTL
408         curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
409         curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, &request->buffer);
410 #endif
411         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
412         curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
413         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
414         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
415         curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
416         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
418         if (start_active_slot(slot)) {
419                 request->slot = slot;
420                 request->state = RUN_PUT;
421         } else {
422                 request->state = ABORTED;
423                 free(request->url);
424                 request->url = NULL;
425         }
428 static void start_move(struct transfer_request *request)
430         struct active_request_slot *slot;
431         struct curl_slist *dav_headers = NULL;
433         slot = get_active_slot();
434         slot->callback_func = process_response;
435         slot->callback_data = request;
436         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
437         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MOVE);
438         dav_headers = curl_slist_append(dav_headers, request->dest);
439         dav_headers = curl_slist_append(dav_headers, "Overwrite: T");
440         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
441         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
442         curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
444         if (start_active_slot(slot)) {
445                 request->slot = slot;
446                 request->state = RUN_MOVE;
447         } else {
448                 request->state = ABORTED;
449                 free(request->url);
450                 request->url = NULL;
451         }
454 static int refresh_lock(struct remote_lock *lock)
456         struct active_request_slot *slot;
457         struct slot_results results;
458         struct curl_slist *dav_headers;
459         int rc = 0;
461         lock->refreshing = 1;
463         dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF | DAV_HEADER_TIMEOUT);
465         slot = get_active_slot();
466         slot->results = &results;
467         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
468         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
469         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
470         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
471         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
473         if (start_active_slot(slot)) {
474                 run_active_slot(slot);
475                 if (results.curl_result != CURLE_OK) {
476                         fprintf(stderr, "LOCK HTTP error %ld\n",
477                                 results.http_code);
478                 } else {
479                         lock->start_time = time(NULL);
480                         rc = 1;
481                 }
482         }
484         lock->refreshing = 0;
485         curl_slist_free_all(dav_headers);
487         return rc;
490 static void check_locks(void)
492         struct remote_lock *lock = repo->locks;
493         time_t current_time = time(NULL);
494         int time_remaining;
496         while (lock) {
497                 time_remaining = lock->start_time + lock->timeout -
498                         current_time;
499                 if (!lock->refreshing && time_remaining < LOCK_REFRESH) {
500                         if (!refresh_lock(lock)) {
501                                 fprintf(stderr,
502                                         "Unable to refresh lock for %s\n",
503                                         lock->url);
504                                 aborted = 1;
505                                 return;
506                         }
507                 }
508                 lock = lock->next;
509         }
512 static void release_request(struct transfer_request *request)
514         struct transfer_request *entry = request_queue_head;
516         if (request == request_queue_head) {
517                 request_queue_head = request->next;
518         } else {
519                 while (entry->next != NULL && entry->next != request)
520                         entry = entry->next;
521                 if (entry->next == request)
522                         entry->next = entry->next->next;
523         }
525         free(request->url);
526         free(request);
529 static void finish_request(struct transfer_request *request)
531         struct http_pack_request *preq;
532         struct http_object_request *obj_req;
534         request->curl_result = request->slot->curl_result;
535         request->http_code = request->slot->http_code;
536         request->slot = NULL;
538         /* Keep locks active */
539         check_locks();
541         if (request->headers != NULL)
542                 curl_slist_free_all(request->headers);
544         /* URL is reused for MOVE after PUT */
545         if (request->state != RUN_PUT) {
546                 free(request->url);
547                 request->url = NULL;
548         }
550         if (request->state == RUN_MKCOL) {
551                 if (request->curl_result == CURLE_OK ||
552                     request->http_code == 405) {
553                         remote_dir_exists[request->obj->sha1[0]] = 1;
554                         start_put(request);
555                 } else {
556                         fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
557                                 sha1_to_hex(request->obj->sha1),
558                                 request->curl_result, request->http_code);
559                         request->state = ABORTED;
560                         aborted = 1;
561                 }
562         } else if (request->state == RUN_PUT) {
563                 if (request->curl_result == CURLE_OK) {
564                         start_move(request);
565                 } else {
566                         fprintf(stderr, "PUT %s failed, aborting (%d/%ld)\n",
567                                 sha1_to_hex(request->obj->sha1),
568                                 request->curl_result, request->http_code);
569                         request->state = ABORTED;
570                         aborted = 1;
571                 }
572         } else if (request->state == RUN_MOVE) {
573                 if (request->curl_result == CURLE_OK) {
574                         if (push_verbosely)
575                                 fprintf(stderr, "    sent %s\n",
576                                         sha1_to_hex(request->obj->sha1));
577                         request->obj->flags |= REMOTE;
578                         release_request(request);
579                 } else {
580                         fprintf(stderr, "MOVE %s failed, aborting (%d/%ld)\n",
581                                 sha1_to_hex(request->obj->sha1),
582                                 request->curl_result, request->http_code);
583                         request->state = ABORTED;
584                         aborted = 1;
585                 }
586         } else if (request->state == RUN_FETCH_LOOSE) {
587                 obj_req = (struct http_object_request *)request->userData;
589                 if (finish_http_object_request(obj_req) == 0)
590                         if (obj_req->rename == 0)
591                                 request->obj->flags |= (LOCAL | REMOTE);
593                 /* Try fetching packed if necessary */
594                 if (request->obj->flags & LOCAL) {
595                         release_http_object_request(obj_req);
596                         release_request(request);
597                 } else
598                         start_fetch_packed(request);
600         } else if (request->state == RUN_FETCH_PACKED) {
601                 int fail = 1;
602                 if (request->curl_result != CURLE_OK) {
603                         fprintf(stderr, "Unable to get pack file %s\n%s",
604                                 request->url, curl_errorstr);
605                 } else {
606                         preq = (struct http_pack_request *)request->userData;
608                         if (preq) {
609                                 if (finish_http_pack_request(preq) == 0)
610                                         fail = 0;
611                                 release_http_pack_request(preq);
612                         }
613                 }
614                 if (fail)
615                         repo->can_update_info_refs = 0;
616                 release_request(request);
617         }
620 #ifdef USE_CURL_MULTI
621 static int is_running_queue;
622 static int fill_active_slot(void *unused)
624         struct transfer_request *request;
626         if (aborted || !is_running_queue)
627                 return 0;
629         for (request = request_queue_head; request; request = request->next) {
630                 if (request->state == NEED_FETCH) {
631                         start_fetch_loose(request);
632                         return 1;
633                 } else if (pushing && request->state == NEED_PUSH) {
634                         if (remote_dir_exists[request->obj->sha1[0]] == 1) {
635                                 start_put(request);
636                         } else {
637                                 start_mkcol(request);
638                         }
639                         return 1;
640                 }
641         }
642         return 0;
644 #endif
646 static void get_remote_object_list(unsigned char parent);
648 static void add_fetch_request(struct object *obj)
650         struct transfer_request *request;
652         check_locks();
654         /*
655          * Don't fetch the object if it's known to exist locally
656          * or is already in the request queue
657          */
658         if (remote_dir_exists[obj->sha1[0]] == -1)
659                 get_remote_object_list(obj->sha1[0]);
660         if (obj->flags & (LOCAL | FETCHING))
661                 return;
663         obj->flags |= FETCHING;
664         request = xmalloc(sizeof(*request));
665         request->obj = obj;
666         request->url = NULL;
667         request->lock = NULL;
668         request->headers = NULL;
669         request->state = NEED_FETCH;
670         request->next = request_queue_head;
671         request_queue_head = request;
673 #ifdef USE_CURL_MULTI
674         fill_active_slots();
675         step_active_slots();
676 #endif
679 static int add_send_request(struct object *obj, struct remote_lock *lock)
681         struct transfer_request *request = request_queue_head;
682         struct packed_git *target;
684         /* Keep locks active */
685         check_locks();
687         /*
688          * Don't push the object if it's known to exist on the remote
689          * or is already in the request queue
690          */
691         if (remote_dir_exists[obj->sha1[0]] == -1)
692                 get_remote_object_list(obj->sha1[0]);
693         if (obj->flags & (REMOTE | PUSHING))
694                 return 0;
695         target = find_sha1_pack(obj->sha1, repo->packs);
696         if (target) {
697                 obj->flags |= REMOTE;
698                 return 0;
699         }
701         obj->flags |= PUSHING;
702         request = xmalloc(sizeof(*request));
703         request->obj = obj;
704         request->url = NULL;
705         request->lock = lock;
706         request->headers = NULL;
707         request->state = NEED_PUSH;
708         request->next = request_queue_head;
709         request_queue_head = request;
711 #ifdef USE_CURL_MULTI
712         fill_active_slots();
713         step_active_slots();
714 #endif
716         return 1;
719 static int fetch_indices(void)
721         int ret;
723         if (push_verbosely)
724                 fprintf(stderr, "Getting pack list\n");
726         switch (http_get_info_packs(repo->url, &repo->packs)) {
727         case HTTP_OK:
728         case HTTP_MISSING_TARGET:
729                 ret = 0;
730                 break;
731         default:
732                 ret = -1;
733         }
735         return ret;
738 static void one_remote_object(const char *hex)
740         unsigned char sha1[20];
741         struct object *obj;
743         if (get_sha1_hex(hex, sha1) != 0)
744                 return;
746         obj = lookup_object(sha1);
747         if (!obj)
748                 obj = parse_object(sha1);
750         /* Ignore remote objects that don't exist locally */
751         if (!obj)
752                 return;
754         obj->flags |= REMOTE;
755         if (!object_list_contains(objects, obj))
756                 object_list_insert(obj, &objects);
759 static void handle_lockprop_ctx(struct xml_ctx *ctx, int tag_closed)
761         int *lock_flags = (int *)ctx->userData;
763         if (tag_closed) {
764                 if (!strcmp(ctx->name, DAV_CTX_LOCKENTRY)) {
765                         if ((*lock_flags & DAV_PROP_LOCKEX) &&
766                             (*lock_flags & DAV_PROP_LOCKWR)) {
767                                 *lock_flags |= DAV_LOCK_OK;
768                         }
769                         *lock_flags &= DAV_LOCK_OK;
770                 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_WRITE)) {
771                         *lock_flags |= DAV_PROP_LOCKWR;
772                 } else if (!strcmp(ctx->name, DAV_CTX_LOCKTYPE_EXCLUSIVE)) {
773                         *lock_flags |= DAV_PROP_LOCKEX;
774                 }
775         }
778 static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
780         struct remote_lock *lock = (struct remote_lock *)ctx->userData;
781         git_SHA_CTX sha_ctx;
782         unsigned char lock_token_sha1[20];
784         if (tag_closed && ctx->cdata) {
785                 if (!strcmp(ctx->name, DAV_ACTIVELOCK_OWNER)) {
786                         lock->owner = xmalloc(strlen(ctx->cdata) + 1);
787                         strcpy(lock->owner, ctx->cdata);
788                 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
789                         if (!prefixcmp(ctx->cdata, "Second-"))
790                                 lock->timeout =
791                                         strtol(ctx->cdata + 7, NULL, 10);
792                 } else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
793                         lock->token = xmalloc(strlen(ctx->cdata) + 1);
794                         strcpy(lock->token, ctx->cdata);
796                         git_SHA1_Init(&sha_ctx);
797                         git_SHA1_Update(&sha_ctx, lock->token, strlen(lock->token));
798                         git_SHA1_Final(lock_token_sha1, &sha_ctx);
800                         lock->tmpfile_suffix[0] = '_';
801                         memcpy(lock->tmpfile_suffix + 1, sha1_to_hex(lock_token_sha1), 40);
802                 }
803         }
806 static void one_remote_ref(char *refname);
808 static void
809 xml_start_tag(void *userData, const char *name, const char **atts)
811         struct xml_ctx *ctx = (struct xml_ctx *)userData;
812         const char *c = strchr(name, ':');
813         int new_len;
815         if (c == NULL)
816                 c = name;
817         else
818                 c++;
820         new_len = strlen(ctx->name) + strlen(c) + 2;
822         if (new_len > ctx->len) {
823                 ctx->name = xrealloc(ctx->name, new_len);
824                 ctx->len = new_len;
825         }
826         strcat(ctx->name, ".");
827         strcat(ctx->name, c);
829         free(ctx->cdata);
830         ctx->cdata = NULL;
832         ctx->userFunc(ctx, 0);
835 static void
836 xml_end_tag(void *userData, const char *name)
838         struct xml_ctx *ctx = (struct xml_ctx *)userData;
839         const char *c = strchr(name, ':');
840         char *ep;
842         ctx->userFunc(ctx, 1);
844         if (c == NULL)
845                 c = name;
846         else
847                 c++;
849         ep = ctx->name + strlen(ctx->name) - strlen(c) - 1;
850         *ep = 0;
853 static void
854 xml_cdata(void *userData, const XML_Char *s, int len)
856         struct xml_ctx *ctx = (struct xml_ctx *)userData;
857         free(ctx->cdata);
858         ctx->cdata = xmemdupz(s, len);
861 static struct remote_lock *lock_remote(const char *path, long timeout)
863         struct active_request_slot *slot;
864         struct slot_results results;
865         struct buffer out_buffer = { STRBUF_INIT, 0 };
866         struct strbuf in_buffer = STRBUF_INIT;
867         char *url;
868         char *ep;
869         char timeout_header[25];
870         struct remote_lock *lock = NULL;
871         struct curl_slist *dav_headers = NULL;
872         struct xml_ctx ctx;
873         char *escaped;
875         url = xmalloc(strlen(repo->url) + strlen(path) + 1);
876         sprintf(url, "%s%s", repo->url, path);
878         /* Make sure leading directories exist for the remote ref */
879         ep = strchr(url + strlen(repo->url) + 1, '/');
880         while (ep) {
881                 char saved_character = ep[1];
882                 ep[1] = '\0';
883                 slot = get_active_slot();
884                 slot->results = &results;
885                 curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
886                 curl_easy_setopt(slot->curl, CURLOPT_URL, url);
887                 curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
888                 curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
889                 if (start_active_slot(slot)) {
890                         run_active_slot(slot);
891                         if (results.curl_result != CURLE_OK &&
892                             results.http_code != 405) {
893                                 fprintf(stderr,
894                                         "Unable to create branch path %s\n",
895                                         url);
896                                 free(url);
897                                 return NULL;
898                         }
899                 } else {
900                         fprintf(stderr, "Unable to start MKCOL request\n");
901                         free(url);
902                         return NULL;
903                 }
904                 ep[1] = saved_character;
905                 ep = strchr(ep + 1, '/');
906         }
908         escaped = xml_entities(git_default_email);
909         strbuf_addf(&out_buffer.buf, LOCK_REQUEST, escaped);
910         free(escaped);
912         sprintf(timeout_header, "Timeout: Second-%ld", timeout);
913         dav_headers = curl_slist_append(dav_headers, timeout_header);
914         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
916         slot = get_active_slot();
917         slot->results = &results;
918         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
919         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);
920         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
921 #ifndef NO_CURL_IOCTL
922         curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
923         curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, &out_buffer);
924 #endif
925         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
926         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
927         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
928         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
929         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_LOCK);
930         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
932         lock = xcalloc(1, sizeof(*lock));
933         lock->timeout = -1;
935         if (start_active_slot(slot)) {
936                 run_active_slot(slot);
937                 if (results.curl_result == CURLE_OK) {
938                         XML_Parser parser = XML_ParserCreate(NULL);
939                         enum XML_Status result;
940                         ctx.name = xcalloc(10, 1);
941                         ctx.len = 0;
942                         ctx.cdata = NULL;
943                         ctx.userFunc = handle_new_lock_ctx;
944                         ctx.userData = lock;
945                         XML_SetUserData(parser, &ctx);
946                         XML_SetElementHandler(parser, xml_start_tag,
947                                               xml_end_tag);
948                         XML_SetCharacterDataHandler(parser, xml_cdata);
949                         result = XML_Parse(parser, in_buffer.buf,
950                                            in_buffer.len, 1);
951                         free(ctx.name);
952                         if (result != XML_STATUS_OK) {
953                                 fprintf(stderr, "XML error: %s\n",
954                                         XML_ErrorString(
955                                                 XML_GetErrorCode(parser)));
956                                 lock->timeout = -1;
957                         }
958                         XML_ParserFree(parser);
959                 }
960         } else {
961                 fprintf(stderr, "Unable to start LOCK request\n");
962         }
964         curl_slist_free_all(dav_headers);
965         strbuf_release(&out_buffer.buf);
966         strbuf_release(&in_buffer);
968         if (lock->token == NULL || lock->timeout <= 0) {
969                 free(lock->token);
970                 free(lock->owner);
971                 free(url);
972                 free(lock);
973                 lock = NULL;
974         } else {
975                 lock->url = url;
976                 lock->start_time = time(NULL);
977                 lock->next = repo->locks;
978                 repo->locks = lock;
979         }
981         return lock;
984 static int unlock_remote(struct remote_lock *lock)
986         struct active_request_slot *slot;
987         struct slot_results results;
988         struct remote_lock *prev = repo->locks;
989         struct curl_slist *dav_headers;
990         int rc = 0;
992         dav_headers = get_dav_token_headers(lock, DAV_HEADER_LOCK);
994         slot = get_active_slot();
995         slot->results = &results;
996         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
997         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
998         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_UNLOCK);
999         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1001         if (start_active_slot(slot)) {
1002                 run_active_slot(slot);
1003                 if (results.curl_result == CURLE_OK)
1004                         rc = 1;
1005                 else
1006                         fprintf(stderr, "UNLOCK HTTP error %ld\n",
1007                                 results.http_code);
1008         } else {
1009                 fprintf(stderr, "Unable to start UNLOCK request\n");
1010         }
1012         curl_slist_free_all(dav_headers);
1014         if (repo->locks == lock) {
1015                 repo->locks = lock->next;
1016         } else {
1017                 while (prev && prev->next != lock)
1018                         prev = prev->next;
1019                 if (prev)
1020                         prev->next = prev->next->next;
1021         }
1023         free(lock->owner);
1024         free(lock->url);
1025         free(lock->token);
1026         free(lock);
1028         return rc;
1031 static void remove_locks(void)
1033         struct remote_lock *lock = repo->locks;
1035         fprintf(stderr, "Removing remote locks...\n");
1036         while (lock) {
1037                 struct remote_lock *next = lock->next;
1038                 unlock_remote(lock);
1039                 lock = next;
1040         }
1043 static void remove_locks_on_signal(int signo)
1045         remove_locks();
1046         sigchain_pop(signo);
1047         raise(signo);
1050 static void remote_ls(const char *path, int flags,
1051                       void (*userFunc)(struct remote_ls_ctx *ls),
1052                       void *userData);
1054 static void process_ls_object(struct remote_ls_ctx *ls)
1056         unsigned int *parent = (unsigned int *)ls->userData;
1057         char *path = ls->dentry_name;
1058         char *obj_hex;
1060         if (!strcmp(ls->path, ls->dentry_name) && (ls->flags & IS_DIR)) {
1061                 remote_dir_exists[*parent] = 1;
1062                 return;
1063         }
1065         if (strlen(path) != 49)
1066                 return;
1067         path += 8;
1068         obj_hex = xmalloc(strlen(path));
1069         /* NB: path is not null-terminated, can not use strlcpy here */
1070         memcpy(obj_hex, path, 2);
1071         strcpy(obj_hex + 2, path + 3);
1072         one_remote_object(obj_hex);
1073         free(obj_hex);
1076 static void process_ls_ref(struct remote_ls_ctx *ls)
1078         if (!strcmp(ls->path, ls->dentry_name) && (ls->dentry_flags & IS_DIR)) {
1079                 fprintf(stderr, "  %s\n", ls->dentry_name);
1080                 return;
1081         }
1083         if (!(ls->dentry_flags & IS_DIR))
1084                 one_remote_ref(ls->dentry_name);
1087 static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
1089         struct remote_ls_ctx *ls = (struct remote_ls_ctx *)ctx->userData;
1091         if (tag_closed) {
1092                 if (!strcmp(ctx->name, DAV_PROPFIND_RESP) && ls->dentry_name) {
1093                         if (ls->dentry_flags & IS_DIR) {
1095                                 /* ensure collection names end with slash */
1096                                 str_end_url_with_slash(ls->dentry_name, &ls->dentry_name);
1098                                 if (ls->flags & PROCESS_DIRS) {
1099                                         ls->userFunc(ls);
1100                                 }
1101                                 if (strcmp(ls->dentry_name, ls->path) &&
1102                                     ls->flags & RECURSIVE) {
1103                                         remote_ls(ls->dentry_name,
1104                                                   ls->flags,
1105                                                   ls->userFunc,
1106                                                   ls->userData);
1107                                 }
1108                         } else if (ls->flags & PROCESS_FILES) {
1109                                 ls->userFunc(ls);
1110                         }
1111                 } else if (!strcmp(ctx->name, DAV_PROPFIND_NAME) && ctx->cdata) {
1112                         char *path = ctx->cdata;
1113                         if (*ctx->cdata == 'h') {
1114                                 path = strstr(path, "//");
1115                                 if (path) {
1116                                         path = strchr(path+2, '/');
1117                                 }
1118                         }
1119                         if (path) {
1120                                 const char *url = repo->url;
1121                                 if (repo->path)
1122                                         url = repo->path;
1123                                 if (strncmp(path, url, repo->path_len))
1124                                         error("Parsed path '%s' does not match url: '%s'\n",
1125                                               path, url);
1126                                 else {
1127                                         path += repo->path_len;
1128                                         ls->dentry_name = xstrdup(path);
1129                                 }
1130                         }
1131                 } else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
1132                         ls->dentry_flags |= IS_DIR;
1133                 }
1134         } else if (!strcmp(ctx->name, DAV_PROPFIND_RESP)) {
1135                 free(ls->dentry_name);
1136                 ls->dentry_name = NULL;
1137                 ls->dentry_flags = 0;
1138         }
1141 /*
1142  * NEEDSWORK: remote_ls() ignores info/refs on the remote side.  But it
1143  * should _only_ heed the information from that file, instead of trying to
1144  * determine the refs from the remote file system (badly: it does not even
1145  * know about packed-refs).
1146  */
1147 static void remote_ls(const char *path, int flags,
1148                       void (*userFunc)(struct remote_ls_ctx *ls),
1149                       void *userData)
1151         char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
1152         struct active_request_slot *slot;
1153         struct slot_results results;
1154         struct strbuf in_buffer = STRBUF_INIT;
1155         struct buffer out_buffer = { STRBUF_INIT, 0 };
1156         struct curl_slist *dav_headers = NULL;
1157         struct xml_ctx ctx;
1158         struct remote_ls_ctx ls;
1160         ls.flags = flags;
1161         ls.path = xstrdup(path);
1162         ls.dentry_name = NULL;
1163         ls.dentry_flags = 0;
1164         ls.userData = userData;
1165         ls.userFunc = userFunc;
1167         sprintf(url, "%s%s", repo->url, path);
1169         strbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);
1171         dav_headers = curl_slist_append(dav_headers, "Depth: 1");
1172         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1174         slot = get_active_slot();
1175         slot->results = &results;
1176         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1177         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);
1178         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1179 #ifndef NO_CURL_IOCTL
1180         curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
1181         curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, &out_buffer);
1182 #endif
1183         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
1184         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1185         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1186         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1187         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
1188         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1190         if (start_active_slot(slot)) {
1191                 run_active_slot(slot);
1192                 if (results.curl_result == CURLE_OK) {
1193                         XML_Parser parser = XML_ParserCreate(NULL);
1194                         enum XML_Status result;
1195                         ctx.name = xcalloc(10, 1);
1196                         ctx.len = 0;
1197                         ctx.cdata = NULL;
1198                         ctx.userFunc = handle_remote_ls_ctx;
1199                         ctx.userData = &ls;
1200                         XML_SetUserData(parser, &ctx);
1201                         XML_SetElementHandler(parser, xml_start_tag,
1202                                               xml_end_tag);
1203                         XML_SetCharacterDataHandler(parser, xml_cdata);
1204                         result = XML_Parse(parser, in_buffer.buf,
1205                                            in_buffer.len, 1);
1206                         free(ctx.name);
1208                         if (result != XML_STATUS_OK) {
1209                                 fprintf(stderr, "XML error: %s\n",
1210                                         XML_ErrorString(
1211                                                 XML_GetErrorCode(parser)));
1212                         }
1213                         XML_ParserFree(parser);
1214                 }
1215         } else {
1216                 fprintf(stderr, "Unable to start PROPFIND request\n");
1217         }
1219         free(ls.path);
1220         free(url);
1221         strbuf_release(&out_buffer.buf);
1222         strbuf_release(&in_buffer);
1223         curl_slist_free_all(dav_headers);
1226 static void get_remote_object_list(unsigned char parent)
1228         char path[] = "objects/XX/";
1229         static const char hex[] = "0123456789abcdef";
1230         unsigned int val = parent;
1232         path[8] = hex[val >> 4];
1233         path[9] = hex[val & 0xf];
1234         remote_dir_exists[val] = 0;
1235         remote_ls(path, (PROCESS_FILES | PROCESS_DIRS),
1236                   process_ls_object, &val);
1239 static int locking_available(void)
1241         struct active_request_slot *slot;
1242         struct slot_results results;
1243         struct strbuf in_buffer = STRBUF_INIT;
1244         struct buffer out_buffer = { STRBUF_INIT, 0 };
1245         struct curl_slist *dav_headers = NULL;
1246         struct xml_ctx ctx;
1247         int lock_flags = 0;
1248         char *escaped;
1250         escaped = xml_entities(repo->url);
1251         strbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, escaped);
1252         free(escaped);
1254         dav_headers = curl_slist_append(dav_headers, "Depth: 0");
1255         dav_headers = curl_slist_append(dav_headers, "Content-Type: text/xml");
1257         slot = get_active_slot();
1258         slot->results = &results;
1259         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1260         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);
1261         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1262 #ifndef NO_CURL_IOCTL
1263         curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
1264         curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, &out_buffer);
1265 #endif
1266         curl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);
1267         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1268         curl_easy_setopt(slot->curl, CURLOPT_URL, repo->url);
1269         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1270         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PROPFIND);
1271         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1273         if (start_active_slot(slot)) {
1274                 run_active_slot(slot);
1275                 if (results.curl_result == CURLE_OK) {
1276                         XML_Parser parser = XML_ParserCreate(NULL);
1277                         enum XML_Status result;
1278                         ctx.name = xcalloc(10, 1);
1279                         ctx.len = 0;
1280                         ctx.cdata = NULL;
1281                         ctx.userFunc = handle_lockprop_ctx;
1282                         ctx.userData = &lock_flags;
1283                         XML_SetUserData(parser, &ctx);
1284                         XML_SetElementHandler(parser, xml_start_tag,
1285                                               xml_end_tag);
1286                         result = XML_Parse(parser, in_buffer.buf,
1287                                            in_buffer.len, 1);
1288                         free(ctx.name);
1290                         if (result != XML_STATUS_OK) {
1291                                 fprintf(stderr, "XML error: %s\n",
1292                                         XML_ErrorString(
1293                                                 XML_GetErrorCode(parser)));
1294                                 lock_flags = 0;
1295                         }
1296                         XML_ParserFree(parser);
1297                         if (!lock_flags)
1298                                 error("no DAV locking support on %s",
1299                                       repo->url);
1301                 } else {
1302                         error("Cannot access URL %s, return code %d",
1303                               repo->url, results.curl_result);
1304                         lock_flags = 0;
1305                 }
1306         } else {
1307                 error("Unable to start PROPFIND request on %s", repo->url);
1308         }
1310         strbuf_release(&out_buffer.buf);
1311         strbuf_release(&in_buffer);
1312         curl_slist_free_all(dav_headers);
1314         return lock_flags;
1317 static struct object_list **add_one_object(struct object *obj, struct object_list **p)
1319         struct object_list *entry = xmalloc(sizeof(struct object_list));
1320         entry->item = obj;
1321         entry->next = *p;
1322         *p = entry;
1323         return &entry->next;
1326 static struct object_list **process_blob(struct blob *blob,
1327                                          struct object_list **p,
1328                                          struct name_path *path,
1329                                          const char *name)
1331         struct object *obj = &blob->object;
1333         obj->flags |= LOCAL;
1335         if (obj->flags & (UNINTERESTING | SEEN))
1336                 return p;
1338         obj->flags |= SEEN;
1339         return add_one_object(obj, p);
1342 static struct object_list **process_tree(struct tree *tree,
1343                                          struct object_list **p,
1344                                          struct name_path *path,
1345                                          const char *name)
1347         struct object *obj = &tree->object;
1348         struct tree_desc desc;
1349         struct name_entry entry;
1350         struct name_path me;
1352         obj->flags |= LOCAL;
1354         if (obj->flags & (UNINTERESTING | SEEN))
1355                 return p;
1356         if (parse_tree(tree) < 0)
1357                 die("bad tree object %s", sha1_to_hex(obj->sha1));
1359         obj->flags |= SEEN;
1360         name = xstrdup(name);
1361         p = add_one_object(obj, p);
1362         me.up = path;
1363         me.elem = name;
1364         me.elem_len = strlen(name);
1366         init_tree_desc(&desc, tree->buffer, tree->size);
1368         while (tree_entry(&desc, &entry))
1369                 switch (object_type(entry.mode)) {
1370                 case OBJ_TREE:
1371                         p = process_tree(lookup_tree(entry.sha1), p, &me, name);
1372                         break;
1373                 case OBJ_BLOB:
1374                         p = process_blob(lookup_blob(entry.sha1), p, &me, name);
1375                         break;
1376                 default:
1377                         /* Subproject commit - not in this repository */
1378                         break;
1379                 }
1381         free(tree->buffer);
1382         tree->buffer = NULL;
1383         return p;
1386 static int get_delta(struct rev_info *revs, struct remote_lock *lock)
1388         int i;
1389         struct commit *commit;
1390         struct object_list **p = &objects;
1391         int count = 0;
1393         while ((commit = get_revision(revs)) != NULL) {
1394                 p = process_tree(commit->tree, p, NULL, "");
1395                 commit->object.flags |= LOCAL;
1396                 if (!(commit->object.flags & UNINTERESTING))
1397                         count += add_send_request(&commit->object, lock);
1398         }
1400         for (i = 0; i < revs->pending.nr; i++) {
1401                 struct object_array_entry *entry = revs->pending.objects + i;
1402                 struct object *obj = entry->item;
1403                 const char *name = entry->name;
1405                 if (obj->flags & (UNINTERESTING | SEEN))
1406                         continue;
1407                 if (obj->type == OBJ_TAG) {
1408                         obj->flags |= SEEN;
1409                         p = add_one_object(obj, p);
1410                         continue;
1411                 }
1412                 if (obj->type == OBJ_TREE) {
1413                         p = process_tree((struct tree *)obj, p, NULL, name);
1414                         continue;
1415                 }
1416                 if (obj->type == OBJ_BLOB) {
1417                         p = process_blob((struct blob *)obj, p, NULL, name);
1418                         continue;
1419                 }
1420                 die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
1421         }
1423         while (objects) {
1424                 if (!(objects->item->flags & UNINTERESTING))
1425                         count += add_send_request(objects->item, lock);
1426                 objects = objects->next;
1427         }
1429         return count;
1432 static int update_remote(unsigned char *sha1, struct remote_lock *lock)
1434         struct active_request_slot *slot;
1435         struct slot_results results;
1436         struct buffer out_buffer = { STRBUF_INIT, 0 };
1437         struct curl_slist *dav_headers;
1439         dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF);
1441         strbuf_addf(&out_buffer.buf, "%s\n", sha1_to_hex(sha1));
1443         slot = get_active_slot();
1444         slot->results = &results;
1445         curl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);
1446         curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);
1447         curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1448 #ifndef NO_CURL_IOCTL
1449         curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
1450         curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, &out_buffer);
1451 #endif
1452         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1453         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
1454         curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1455         curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1456         curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
1457         curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
1459         if (start_active_slot(slot)) {
1460                 run_active_slot(slot);
1461                 strbuf_release(&out_buffer.buf);
1462                 if (results.curl_result != CURLE_OK) {
1463                         fprintf(stderr,
1464                                 "PUT error: curl result=%d, HTTP code=%ld\n",
1465                                 results.curl_result, results.http_code);
1466                         /* We should attempt recovery? */
1467                         return 0;
1468                 }
1469         } else {
1470                 strbuf_release(&out_buffer.buf);
1471                 fprintf(stderr, "Unable to start PUT request\n");
1472                 return 0;
1473         }
1475         return 1;
1478 static struct ref *remote_refs;
1480 static void one_remote_ref(char *refname)
1482         struct ref *ref;
1483         struct object *obj;
1485         ref = alloc_ref(refname);
1487         if (http_fetch_ref(repo->url, ref) != 0) {
1488                 fprintf(stderr,
1489                         "Unable to fetch ref %s from %s\n",
1490                         refname, repo->url);
1491                 free(ref);
1492                 return;
1493         }
1495         /*
1496          * Fetch a copy of the object if it doesn't exist locally - it
1497          * may be required for updating server info later.
1498          */
1499         if (repo->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
1500                 obj = lookup_unknown_object(ref->old_sha1);
1501                 if (obj) {
1502                         fprintf(stderr, "  fetch %s for %s\n",
1503                                 sha1_to_hex(ref->old_sha1), refname);
1504                         add_fetch_request(obj);
1505                 }
1506         }
1508         ref->next = remote_refs;
1509         remote_refs = ref;
1512 static void get_dav_remote_heads(void)
1514         remote_ls("refs/", (PROCESS_FILES | PROCESS_DIRS | RECURSIVE), process_ls_ref, NULL);
1517 static void add_remote_info_ref(struct remote_ls_ctx *ls)
1519         struct strbuf *buf = (struct strbuf *)ls->userData;
1520         struct object *o;
1521         int len;
1522         char *ref_info;
1523         struct ref *ref;
1525         ref = alloc_ref(ls->dentry_name);
1527         if (http_fetch_ref(repo->url, ref) != 0) {
1528                 fprintf(stderr,
1529                         "Unable to fetch ref %s from %s\n",
1530                         ls->dentry_name, repo->url);
1531                 aborted = 1;
1532                 free(ref);
1533                 return;
1534         }
1536         o = parse_object(ref->old_sha1);
1537         if (!o) {
1538                 fprintf(stderr,
1539                         "Unable to parse object %s for remote ref %s\n",
1540                         sha1_to_hex(ref->old_sha1), ls->dentry_name);
1541                 aborted = 1;
1542                 free(ref);
1543                 return;
1544         }
1546         len = strlen(ls->dentry_name) + 42;
1547         ref_info = xcalloc(len + 1, 1);
1548         sprintf(ref_info, "%s   %s\n",
1549                 sha1_to_hex(ref->old_sha1), ls->dentry_name);
1550         fwrite_buffer(ref_info, 1, len, buf);
1551         free(ref_info);
1553         if (o->type == OBJ_TAG) {
1554                 o = deref_tag(o, ls->dentry_name, 0);
1555                 if (o) {
1556                         len = strlen(ls->dentry_name) + 45;
1557                         ref_info = xcalloc(len + 1, 1);
1558                         sprintf(ref_info, "%s   %s^{}\n",
1559                                 sha1_to_hex(o->sha1), ls->dentry_name);
1560                         fwrite_buffer(ref_info, 1, len, buf);
1561                         free(ref_info);
1562                 }
1563         }
1564         free(ref);
1567 static void update_remote_info_refs(struct remote_lock *lock)
1569         struct buffer buffer = { STRBUF_INIT, 0 };
1570         struct active_request_slot *slot;
1571         struct slot_results results;
1572         struct curl_slist *dav_headers;
1574         remote_ls("refs/", (PROCESS_FILES | RECURSIVE),
1575                   add_remote_info_ref, &buffer.buf);
1576         if (!aborted) {
1577                 dav_headers = get_dav_token_headers(lock, DAV_HEADER_IF);
1579                 slot = get_active_slot();
1580                 slot->results = &results;
1581                 curl_easy_setopt(slot->curl, CURLOPT_INFILE, &buffer);
1582                 curl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.buf.len);
1583                 curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);
1584 #ifndef NO_CURL_IOCTL
1585                 curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
1586                 curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, &buffer);
1587 #endif
1588                 curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1589                 curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);
1590                 curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, dav_headers);
1591                 curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 1);
1592                 curl_easy_setopt(slot->curl, CURLOPT_PUT, 1);
1593                 curl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);
1595                 if (start_active_slot(slot)) {
1596                         run_active_slot(slot);
1597                         if (results.curl_result != CURLE_OK) {
1598                                 fprintf(stderr,
1599                                         "PUT error: curl result=%d, HTTP code=%ld\n",
1600                                         results.curl_result, results.http_code);
1601                         }
1602                 }
1603         }
1604         strbuf_release(&buffer.buf);
1607 static int remote_exists(const char *path)
1609         char *url = xmalloc(strlen(repo->url) + strlen(path) + 1);
1610         int ret;
1612         sprintf(url, "%s%s", repo->url, path);
1614         switch (http_get_strbuf(url, NULL, 0)) {
1615         case HTTP_OK:
1616                 ret = 1;
1617                 break;
1618         case HTTP_MISSING_TARGET:
1619                 ret = 0;
1620                 break;
1621         case HTTP_ERROR:
1622                 http_error(url, HTTP_ERROR);
1623         default:
1624                 ret = -1;
1625         }
1626         free(url);
1627         return ret;
1630 static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
1632         char *url;
1633         struct strbuf buffer = STRBUF_INIT;
1635         url = xmalloc(strlen(repo->url) + strlen(path) + 1);
1636         sprintf(url, "%s%s", repo->url, path);
1638         if (http_get_strbuf(url, &buffer, 0) != HTTP_OK)
1639                 die("Couldn't get %s for remote symref\n%s", url,
1640                     curl_errorstr);
1641         free(url);
1643         free(*symref);
1644         *symref = NULL;
1645         hashclr(sha1);
1647         if (buffer.len == 0)
1648                 return;
1650         /* If it's a symref, set the refname; otherwise try for a sha1 */
1651         if (!prefixcmp((char *)buffer.buf, "ref: ")) {
1652                 *symref = xmemdupz((char *)buffer.buf + 5, buffer.len - 6);
1653         } else {
1654                 get_sha1_hex(buffer.buf, sha1);
1655         }
1657         strbuf_release(&buffer);
1660 static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1)
1662         struct commit *head = lookup_commit(head_sha1);
1663         struct commit *branch = lookup_commit(branch_sha1);
1664         struct commit_list *merge_bases = get_merge_bases(head, branch, 1);
1666         return (merge_bases && !merge_bases->next && merge_bases->item == branch);
1669 static int delete_remote_branch(char *pattern, int force)
1671         struct ref *refs = remote_refs;
1672         struct ref *remote_ref = NULL;
1673         unsigned char head_sha1[20];
1674         char *symref = NULL;
1675         int match;
1676         int patlen = strlen(pattern);
1677         int i;
1678         struct active_request_slot *slot;
1679         struct slot_results results;
1680         char *url;
1682         /* Find the remote branch(es) matching the specified branch name */
1683         for (match = 0; refs; refs = refs->next) {
1684                 char *name = refs->name;
1685                 int namelen = strlen(name);
1686                 if (namelen < patlen ||
1687                     memcmp(name + namelen - patlen, pattern, patlen))
1688                         continue;
1689                 if (namelen != patlen && name[namelen - patlen - 1] != '/')
1690                         continue;
1691                 match++;
1692                 remote_ref = refs;
1693         }
1694         if (match == 0)
1695                 return error("No remote branch matches %s", pattern);
1696         if (match != 1)
1697                 return error("More than one remote branch matches %s",
1698                              pattern);
1700         /*
1701          * Remote HEAD must be a symref (not exactly foolproof; a remote
1702          * symlink to a symref will look like a symref)
1703          */
1704         fetch_symref("HEAD", &symref, head_sha1);
1705         if (!symref)
1706                 return error("Remote HEAD is not a symref");
1708         /* Remote branch must not be the remote HEAD */
1709         for (i=0; symref && i<MAXDEPTH; i++) {
1710                 if (!strcmp(remote_ref->name, symref))
1711                         return error("Remote branch %s is the current HEAD",
1712                                      remote_ref->name);
1713                 fetch_symref(symref, &symref, head_sha1);
1714         }
1716         /* Run extra sanity checks if delete is not forced */
1717         if (!force) {
1718                 /* Remote HEAD must resolve to a known object */
1719                 if (symref)
1720                         return error("Remote HEAD symrefs too deep");
1721                 if (is_null_sha1(head_sha1))
1722                         return error("Unable to resolve remote HEAD");
1723                 if (!has_sha1_file(head_sha1))
1724                         return error("Remote HEAD resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", sha1_to_hex(head_sha1));
1726                 /* Remote branch must resolve to a known object */
1727                 if (is_null_sha1(remote_ref->old_sha1))
1728                         return error("Unable to resolve remote branch %s",
1729                                      remote_ref->name);
1730                 if (!has_sha1_file(remote_ref->old_sha1))
1731                         return error("Remote branch %s resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", remote_ref->name, sha1_to_hex(remote_ref->old_sha1));
1733                 /* Remote branch must be an ancestor of remote HEAD */
1734                 if (!verify_merge_base(head_sha1, remote_ref->old_sha1)) {
1735                         return error("The branch '%s' is not an ancestor "
1736                                      "of your current HEAD.\n"
1737                                      "If you are sure you want to delete it,"
1738                                      " run:\n\t'git http-push -D %s %s'",
1739                                      remote_ref->name, repo->url, pattern);
1740                 }
1741         }
1743         /* Send delete request */
1744         fprintf(stderr, "Removing remote branch '%s'\n", remote_ref->name);
1745         if (dry_run)
1746                 return 0;
1747         url = xmalloc(strlen(repo->url) + strlen(remote_ref->name) + 1);
1748         sprintf(url, "%s%s", repo->url, remote_ref->name);
1749         slot = get_active_slot();
1750         slot->results = &results;
1751         curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
1752         curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
1753         curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1754         curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_DELETE);
1755         if (start_active_slot(slot)) {
1756                 run_active_slot(slot);
1757                 free(url);
1758                 if (results.curl_result != CURLE_OK)
1759                         return error("DELETE request failed (%d/%ld)\n",
1760                                      results.curl_result, results.http_code);
1761         } else {
1762                 free(url);
1763                 return error("Unable to start DELETE request");
1764         }
1766         return 0;
1769 static void run_request_queue(void)
1771 #ifdef USE_CURL_MULTI
1772         is_running_queue = 1;
1773         fill_active_slots();
1774         add_fill_function(NULL, fill_active_slot);
1775 #endif
1776         do {
1777                 finish_all_active_slots();
1778 #ifdef USE_CURL_MULTI
1779                 fill_active_slots();
1780 #endif
1781         } while (request_queue_head && !aborted);
1783 #ifdef USE_CURL_MULTI
1784         is_running_queue = 0;
1785 #endif
1788 int main(int argc, char **argv)
1790         struct transfer_request *request;
1791         struct transfer_request *next_request;
1792         int nr_refspec = 0;
1793         char **refspec = NULL;
1794         struct remote_lock *ref_lock = NULL;
1795         struct remote_lock *info_ref_lock = NULL;
1796         struct rev_info revs;
1797         int delete_branch = 0;
1798         int force_delete = 0;
1799         int objects_to_send;
1800         int rc = 0;
1801         int i;
1802         int new_refs;
1803         struct ref *ref, *local_refs;
1804         struct remote *remote;
1806         git_setup_gettext();
1808         git_extract_argv0_path(argv[0]);
1810         repo = xcalloc(sizeof(*repo), 1);
1812         argv++;
1813         for (i = 1; i < argc; i++, argv++) {
1814                 char *arg = *argv;
1816                 if (*arg == '-') {
1817                         if (!strcmp(arg, "--all")) {
1818                                 push_all = MATCH_REFS_ALL;
1819                                 continue;
1820                         }
1821                         if (!strcmp(arg, "--force")) {
1822                                 force_all = 1;
1823                                 continue;
1824                         }
1825                         if (!strcmp(arg, "--dry-run")) {
1826                                 dry_run = 1;
1827                                 continue;
1828                         }
1829                         if (!strcmp(arg, "--helper-status")) {
1830                                 helper_status = 1;
1831                                 continue;
1832                         }
1833                         if (!strcmp(arg, "--verbose")) {
1834                                 push_verbosely = 1;
1835                                 http_is_verbose = 1;
1836                                 continue;
1837                         }
1838                         if (!strcmp(arg, "-d")) {
1839                                 delete_branch = 1;
1840                                 continue;
1841                         }
1842                         if (!strcmp(arg, "-D")) {
1843                                 delete_branch = 1;
1844                                 force_delete = 1;
1845                                 continue;
1846                         }
1847                         if (!strcmp(arg, "-h"))
1848                                 usage(http_push_usage);
1849                 }
1850                 if (!repo->url) {
1851                         char *path = strstr(arg, "//");
1852                         str_end_url_with_slash(arg, &repo->url);
1853                         repo->path_len = strlen(repo->url);
1854                         if (path) {
1855                                 repo->path = strchr(path+2, '/');
1856                                 if (repo->path)
1857                                         repo->path_len = strlen(repo->path);
1858                         }
1859                         continue;
1860                 }
1861                 refspec = argv;
1862                 nr_refspec = argc - i;
1863                 break;
1864         }
1866 #ifndef USE_CURL_MULTI
1867         die("git-push is not available for http/https repository when not compiled with USE_CURL_MULTI");
1868 #endif
1870         if (!repo->url)
1871                 usage(http_push_usage);
1873         if (delete_branch && nr_refspec != 1)
1874                 die("You must specify only one branch name when deleting a remote branch");
1876         setup_git_directory();
1878         memset(remote_dir_exists, -1, 256);
1880         /*
1881          * Create a minimum remote by hand to give to http_init(),
1882          * primarily to allow it to look at the URL.
1883          */
1884         remote = xcalloc(sizeof(*remote), 1);
1885         ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc);
1886         remote->url[remote->url_nr++] = repo->url;
1887         http_init(remote);
1889 #ifdef USE_CURL_MULTI
1890         is_running_queue = 0;
1891 #endif
1893         /* Verify DAV compliance/lock support */
1894         if (!locking_available()) {
1895                 rc = 1;
1896                 goto cleanup;
1897         }
1899         sigchain_push_common(remove_locks_on_signal);
1901         /* Check whether the remote has server info files */
1902         repo->can_update_info_refs = 0;
1903         repo->has_info_refs = remote_exists("info/refs");
1904         repo->has_info_packs = remote_exists("objects/info/packs");
1905         if (repo->has_info_refs) {
1906                 info_ref_lock = lock_remote("info/refs", LOCK_TIME);
1907                 if (info_ref_lock)
1908                         repo->can_update_info_refs = 1;
1909                 else {
1910                         error("cannot lock existing info/refs");
1911                         rc = 1;
1912                         goto cleanup;
1913                 }
1914         }
1915         if (repo->has_info_packs)
1916                 fetch_indices();
1918         /* Get a list of all local and remote heads to validate refspecs */
1919         local_refs = get_local_heads();
1920         fprintf(stderr, "Fetching remote heads...\n");
1921         get_dav_remote_heads();
1922         run_request_queue();
1924         /* Remove a remote branch if -d or -D was specified */
1925         if (delete_branch) {
1926                 if (delete_remote_branch(refspec[0], force_delete) == -1) {
1927                         fprintf(stderr, "Unable to delete remote branch %s\n",
1928                                 refspec[0]);
1929                         if (helper_status)
1930                                 printf("error %s cannot remove\n", refspec[0]);
1931                 }
1932                 goto cleanup;
1933         }
1935         /* match them up */
1936         if (match_refs(local_refs, &remote_refs,
1937                        nr_refspec, (const char **) refspec, push_all)) {
1938                 rc = -1;
1939                 goto cleanup;
1940         }
1941         if (!remote_refs) {
1942                 fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
1943                 if (helper_status)
1944                         printf("error null no match\n");
1945                 rc = 0;
1946                 goto cleanup;
1947         }
1949         new_refs = 0;
1950         for (ref = remote_refs; ref; ref = ref->next) {
1951                 char old_hex[60], *new_hex;
1952                 const char *commit_argv[5];
1953                 int commit_argc;
1954                 char *new_sha1_hex, *old_sha1_hex;
1956                 if (!ref->peer_ref)
1957                         continue;
1959                 if (is_null_sha1(ref->peer_ref->new_sha1)) {
1960                         if (delete_remote_branch(ref->name, 1) == -1) {
1961                                 error("Could not remove %s", ref->name);
1962                                 if (helper_status)
1963                                         printf("error %s cannot remove\n", ref->name);
1964                                 rc = -4;
1965                         }
1966                         else if (helper_status)
1967                                 printf("ok %s\n", ref->name);
1968                         new_refs++;
1969                         continue;
1970                 }
1972                 if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
1973                         if (push_verbosely)
1974                                 fprintf(stderr, "'%s': up-to-date\n", ref->name);
1975                         if (helper_status)
1976                                 printf("ok %s up to date\n", ref->name);
1977                         continue;
1978                 }
1980                 if (!force_all &&
1981                     !is_null_sha1(ref->old_sha1) &&
1982                     !ref->force) {
1983                         if (!has_sha1_file(ref->old_sha1) ||
1984                             !ref_newer(ref->peer_ref->new_sha1,
1985                                        ref->old_sha1)) {
1986                                 /*
1987                                  * We do not have the remote ref, or
1988                                  * we know that the remote ref is not
1989                                  * an ancestor of what we are trying to
1990                                  * push.  Either way this can be losing
1991                                  * commits at the remote end and likely
1992                                  * we were not up to date to begin with.
1993                                  */
1994                                 error("remote '%s' is not an ancestor of\n"
1995                                       "local '%s'.\n"
1996                                       "Maybe you are not up-to-date and "
1997                                       "need to pull first?",
1998                                       ref->name,
1999                                       ref->peer_ref->name);
2000                                 if (helper_status)
2001                                         printf("error %s non-fast forward\n", ref->name);
2002                                 rc = -2;
2003                                 continue;
2004                         }
2005                 }
2006                 hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
2007                 new_refs++;
2008                 strcpy(old_hex, sha1_to_hex(ref->old_sha1));
2009                 new_hex = sha1_to_hex(ref->new_sha1);
2011                 fprintf(stderr, "updating '%s'", ref->name);
2012                 if (strcmp(ref->name, ref->peer_ref->name))
2013                         fprintf(stderr, " using '%s'", ref->peer_ref->name);
2014                 fprintf(stderr, "\n  from %s\n  to   %s\n", old_hex, new_hex);
2015                 if (dry_run) {
2016                         if (helper_status)
2017                                 printf("ok %s\n", ref->name);
2018                         continue;
2019                 }
2021                 /* Lock remote branch ref */
2022                 ref_lock = lock_remote(ref->name, LOCK_TIME);
2023                 if (ref_lock == NULL) {
2024                         fprintf(stderr, "Unable to lock remote branch %s\n",
2025                                 ref->name);
2026                         if (helper_status)
2027                                 printf("error %s lock error\n", ref->name);
2028                         rc = 1;
2029                         continue;
2030                 }
2032                 /* Set up revision info for this refspec */
2033                 commit_argc = 3;
2034                 new_sha1_hex = xstrdup(sha1_to_hex(ref->new_sha1));
2035                 old_sha1_hex = NULL;
2036                 commit_argv[1] = "--objects";
2037                 commit_argv[2] = new_sha1_hex;
2038                 if (!push_all && !is_null_sha1(ref->old_sha1)) {
2039                         old_sha1_hex = xmalloc(42);
2040                         sprintf(old_sha1_hex, "^%s",
2041                                 sha1_to_hex(ref->old_sha1));
2042                         commit_argv[3] = old_sha1_hex;
2043                         commit_argc++;
2044                 }
2045                 commit_argv[commit_argc] = NULL;
2046                 init_revisions(&revs, setup_git_directory());
2047                 setup_revisions(commit_argc, commit_argv, &revs, NULL);
2048                 revs.edge_hint = 0; /* just in case */
2049                 free(new_sha1_hex);
2050                 if (old_sha1_hex) {
2051                         free(old_sha1_hex);
2052                         commit_argv[1] = NULL;
2053                 }
2055                 /* Generate a list of objects that need to be pushed */
2056                 pushing = 0;
2057                 if (prepare_revision_walk(&revs))
2058                         die("revision walk setup failed");
2059                 mark_edges_uninteresting(revs.commits, &revs, NULL);
2060                 objects_to_send = get_delta(&revs, ref_lock);
2061                 finish_all_active_slots();
2063                 /* Push missing objects to remote, this would be a
2064                    convenient time to pack them first if appropriate. */
2065                 pushing = 1;
2066                 if (objects_to_send)
2067                         fprintf(stderr, "    sending %d objects\n",
2068                                 objects_to_send);
2070                 run_request_queue();
2072                 /* Update the remote branch if all went well */
2073                 if (aborted || !update_remote(ref->new_sha1, ref_lock))
2074                         rc = 1;
2076                 if (!rc)
2077                         fprintf(stderr, "    done\n");
2078                 if (helper_status)
2079                         printf("%s %s\n", !rc ? "ok" : "error", ref->name);
2080                 unlock_remote(ref_lock);
2081                 check_locks();
2082         }
2084         /* Update remote server info if appropriate */
2085         if (repo->has_info_refs && new_refs) {
2086                 if (info_ref_lock && repo->can_update_info_refs) {
2087                         fprintf(stderr, "Updating remote server info\n");
2088                         if (!dry_run)
2089                                 update_remote_info_refs(info_ref_lock);
2090                 } else {
2091                         fprintf(stderr, "Unable to update server info\n");
2092                 }
2093         }
2095  cleanup:
2096         if (info_ref_lock)
2097                 unlock_remote(info_ref_lock);
2098         free(repo);
2100         http_cleanup();
2102         request = request_queue_head;
2103         while (request != NULL) {
2104                 next_request = request->next;
2105                 release_request(request);
2106                 request = next_request;
2107         }
2109         return rc;