Merge branch 'wc/rebase-insn'
[gitweb.git] / http-push.c
index c7471fa11d962afe79518d3916b542e1a2290604..78283b4de3b9111d87368df747daa96b5f6c09c3 100644 (file)
@@ -1,7 +1,6 @@
 #include "cache.h"
 #include "commit.h"
 #include "pack.h"
-#include "fetch.h"
 #include "tag.h"
 #include "blob.h"
 #include "http.h"
@@ -14,7 +13,7 @@
 #include <expat.h>
 
 static const char http_push_usage[] =
-"git-http-push [--all] [--force] [--verbose] <remote> [<head>...]\n";
+"git-http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]\n";
 
 #ifndef XML_STATUS_OK
 enum XML_Status {
@@ -79,8 +78,9 @@ static struct curl_slist *no_pragma_header;
 static struct curl_slist *default_headers;
 
 static int push_verbosely;
-static int push_all;
+static int push_all = MATCH_REFS_NONE;
 static int force_all;
+static int dry_run;
 
 static struct object_list *objects;
 
@@ -433,7 +433,7 @@ static void start_fetch_packed(struct transfer_request *request)
        packfile = fopen(request->tmpfile, "a");
        if (!packfile) {
                fprintf(stderr, "Unable to open local file %s for pack",
-                       filename);
+                       request->tmpfile);
                remote->can_update_info_refs = 0;
                free(url);
                return;
@@ -795,7 +795,7 @@ static void finish_request(struct transfer_request *request)
 }
 
 #ifdef USE_CURL_MULTI
-int fill_active_slot(void)
+static int fill_active_slot(void *unused)
 {
        struct transfer_request *request = request_queue_head;
 
@@ -941,7 +941,7 @@ static int fetch_index(unsigned char *sha1)
        indexfile = fopen(tmpfile, "a");
        if (!indexfile)
                return error("Unable to open local file %s for pack index",
-                            filename);
+                            tmpfile);
 
        slot = get_active_slot();
        slot->results = &results;
@@ -1260,10 +1260,7 @@ xml_cdata(void *userData, const XML_Char *s, int len)
 {
        struct xml_ctx *ctx = (struct xml_ctx *)userData;
        free(ctx->cdata);
-       ctx->cdata = xmalloc(len + 1);
-       /* NB: 's' is not null-terminated, can not use strlcpy here */
-       memcpy(ctx->cdata, s, len);
-       ctx->cdata[len] = '\0';
+       ctx->cdata = xmemdupz(s, len);
 }
 
 static struct remote_lock *lock_remote(const char *path, long timeout)
@@ -2161,9 +2158,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
 
        /* If it's a symref, set the refname; otherwise try for a sha1 */
        if (!prefixcmp((char *)buffer.buffer, "ref: ")) {
-               *symref = xmalloc(buffer.posn - 5);
-               memcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 6);
-               (*symref)[buffer.posn - 6] = '\0';
+               *symref = xmemdupz((char *)buffer.buffer + 5, buffer.posn - 6);
        } else {
                get_sha1_hex(buffer.buffer, sha1);
        }
@@ -2246,7 +2241,11 @@ static int delete_remote_branch(char *pattern, int force)
 
                /* Remote branch must be an ancestor of remote HEAD */
                if (!verify_merge_base(head_sha1, remote_ref->old_sha1)) {
-                       return error("The branch '%s' is not a strict subset of your current HEAD.\nIf you are sure you want to delete it, run:\n\t'git http-push -D %s %s'", remote_ref->name, remote->url, pattern);
+                       return error("The branch '%s' is not an ancestor "
+                                    "of your current HEAD.\n"
+                                    "If you are sure you want to delete it,"
+                                    " run:\n\t'git http-push -D %s %s'",
+                                    remote_ref->name, remote->url, pattern);
                }
        }
 
@@ -2301,13 +2300,17 @@ int main(int argc, char **argv)
 
                if (*arg == '-') {
                        if (!strcmp(arg, "--all")) {
-                               push_all = 1;
+                               push_all = MATCH_REFS_ALL;
                                continue;
                        }
                        if (!strcmp(arg, "--force")) {
                                force_all = 1;
                                continue;
                        }
+                       if (!strcmp(arg, "--dry-run")) {
+                               dry_run = 1;
+                               continue;
+                       }
                        if (!strcmp(arg, "--verbose")) {
                                push_verbosely = 1;
                                continue;
@@ -2390,7 +2393,7 @@ int main(int argc, char **argv)
        if (!remote_tail)
                remote_tail = &remote_refs;
        if (match_refs(local_refs, remote_refs, &remote_tail,
-                      nr_refspec, refspec, push_all))
+                      nr_refspec, (const char **) refspec, push_all))
                return -1;
        if (!remote_refs) {
                fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
@@ -2418,16 +2421,17 @@ int main(int argc, char **argv)
                        if (!has_sha1_file(ref->old_sha1) ||
                            !ref_newer(ref->peer_ref->new_sha1,
                                       ref->old_sha1)) {
-                               /* We do not have the remote ref, or
+                               /*
+                                * We do not have the remote ref, or
                                 * we know that the remote ref is not
                                 * an ancestor of what we are trying to
                                 * push.  Either way this can be losing
                                 * commits at the remote end and likely
                                 * we were not up to date to begin with.
                                 */
-                               error("remote '%s' is not a strict "
-                                     "subset of local ref '%s'. "
-                                     "maybe you are not up-to-date and "
+                               error("remote '%s' is not an ancestor of\n"
+                                     "local '%s'.\n"
+                                     "Maybe you are not up-to-date and "
                                      "need to pull first?",
                                      ref->name,
                                      ref->peer_ref->name);
@@ -2449,7 +2453,8 @@ int main(int argc, char **argv)
                if (strcmp(ref->name, ref->peer_ref->name))
                        fprintf(stderr, " using '%s'", ref->peer_ref->name);
                fprintf(stderr, "\n  from %s\n  to   %s\n", old_hex, new_hex);
-
+               if (dry_run)
+                       continue;
 
                /* Lock remote branch ref */
                ref_lock = lock_remote(ref->name, LOCK_TIME);
@@ -2496,6 +2501,7 @@ int main(int argc, char **argv)
                                objects_to_send);
 #ifdef USE_CURL_MULTI
                fill_active_slots();
+               add_fill_function(NULL, fill_active_slot);
 #endif
                finish_all_active_slots();
 
@@ -2516,7 +2522,8 @@ int main(int argc, char **argv)
        if (remote->has_info_refs && new_refs) {
                if (info_ref_lock && remote->can_update_info_refs) {
                        fprintf(stderr, "Updating remote server info\n");
-                       update_remote_info_refs(info_ref_lock);
+                       if (!dry_run)
+                               update_remote_info_refs(info_ref_lock);
                } else {
                        fprintf(stderr, "Unable to update server info\n");
                }