push_refs_with_export: convert to struct object_id
[gitweb.git] / http-push.c
index 1f3788f634ba29d26a8558b17cab71ac283cdb85..f2db3a6243bb48de4f37febc2da3db7c5d5b9874 100644 (file)
@@ -10,6 +10,7 @@
 #include "remote.h"
 #include "list-objects.h"
 #include "sigchain.h"
+#include "argv-array.h"
 
 #ifdef EXPAT_NEEDS_XMLPARSE_H
 #include <xmlparse.h>
@@ -786,21 +787,21 @@ xml_start_tag(void *userData, const char *name, const char **atts)
 {
        struct xml_ctx *ctx = (struct xml_ctx *)userData;
        const char *c = strchr(name, ':');
-       int new_len;
+       int old_namelen, new_len;
 
        if (c == NULL)
                c = name;
        else
                c++;
 
-       new_len = strlen(ctx->name) + strlen(c) + 2;
+       old_namelen = strlen(ctx->name);
+       new_len = old_namelen + strlen(c) + 2;
 
        if (new_len > ctx->len) {
                ctx->name = xrealloc(ctx->name, new_len);
                ctx->len = new_len;
        }
-       strcat(ctx->name, ".");
-       strcat(ctx->name, c);
+       xsnprintf(ctx->name + old_namelen, ctx->len - old_namelen, ".%s", c);
 
        free(ctx->cdata);
        ctx->cdata = NULL;
@@ -1437,11 +1438,11 @@ static void one_remote_ref(const char *refname)
         * Fetch a copy of the object if it doesn't exist locally - it
         * may be required for updating server info later.
         */
-       if (repo->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
-               obj = lookup_unknown_object(ref->old_sha1);
+       if (repo->can_update_info_refs && !has_object_file(&ref->old_oid)) {
+               obj = lookup_unknown_object(ref->old_oid.hash);
                if (obj) {
                        fprintf(stderr, "  fetch %s for %s\n",
-                               sha1_to_hex(ref->old_sha1), refname);
+                               oid_to_hex(&ref->old_oid), refname);
                        add_fetch_request(obj);
                }
        }
@@ -1459,8 +1460,6 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
 {
        struct strbuf *buf = (struct strbuf *)ls->userData;
        struct object *o;
-       int len;
-       char *ref_info;
        struct ref *ref;
 
        ref = alloc_ref(ls->dentry_name);
@@ -1474,33 +1473,24 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
                return;
        }
 
-       o = parse_object(ref->old_sha1);
+       o = parse_object(ref->old_oid.hash);
        if (!o) {
                fprintf(stderr,
                        "Unable to parse object %s for remote ref %s\n",
-                       sha1_to_hex(ref->old_sha1), ls->dentry_name);
+                       oid_to_hex(&ref->old_oid), ls->dentry_name);
                aborted = 1;
                free(ref);
                return;
        }
 
-       len = strlen(ls->dentry_name) + 42;
-       ref_info = xcalloc(len + 1, 1);
-       sprintf(ref_info, "%s   %s\n",
-               sha1_to_hex(ref->old_sha1), ls->dentry_name);
-       fwrite_buffer(ref_info, 1, len, buf);
-       free(ref_info);
+       strbuf_addf(buf, "%s\t%s\n",
+                   oid_to_hex(&ref->old_oid), ls->dentry_name);
 
        if (o->type == OBJ_TAG) {
                o = deref_tag(o, ls->dentry_name, 0);
-               if (o) {
-                       len = strlen(ls->dentry_name) + 45;
-                       ref_info = xcalloc(len + 1, 1);
-                       sprintf(ref_info, "%s   %s^{}\n",
-                               sha1_to_hex(o->sha1), ls->dentry_name);
-                       fwrite_buffer(ref_info, 1, len, buf);
-                       free(ref_info);
-               }
+               if (o)
+                       strbuf_addf(buf, "%s\t%s^{}\n",
+                                   sha1_to_hex(o->sha1), ls->dentry_name);
        }
        free(ref);
 }
@@ -1591,7 +1581,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
 static int verify_merge_base(unsigned char *head_sha1, struct ref *remote)
 {
        struct commit *head = lookup_commit_or_die(head_sha1, "HEAD");
-       struct commit *branch = lookup_commit_or_die(remote->old_sha1, remote->name);
+       struct commit *branch = lookup_commit_or_die(remote->old_oid.hash, remote->name);
 
        return in_merge_bases(branch, head);
 }
@@ -1654,11 +1644,11 @@ static int delete_remote_branch(const char *pattern, int force)
                        return error("Remote HEAD resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", sha1_to_hex(head_sha1));
 
                /* Remote branch must resolve to a known object */
-               if (is_null_sha1(remote_ref->old_sha1))
+               if (is_null_oid(&remote_ref->old_oid))
                        return error("Unable to resolve remote branch %s",
                                     remote_ref->name);
-               if (!has_sha1_file(remote_ref->old_sha1))
-                       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));
+               if (!has_object_file(&remote_ref->old_oid))
+                       return error("Remote branch %s resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", remote_ref->name, oid_to_hex(&remote_ref->old_oid));
 
                /* Remote branch must be an ancestor of remote HEAD */
                if (!verify_merge_base(head_sha1, remote_ref)) {
@@ -1866,15 +1856,12 @@ int main(int argc, char **argv)
 
        new_refs = 0;
        for (ref = remote_refs; ref; ref = ref->next) {
-               char old_hex[60], *new_hex;
-               const char *commit_argv[5];
-               int commit_argc;
-               char *new_sha1_hex, *old_sha1_hex;
+               struct argv_array commit_argv = ARGV_ARRAY_INIT;
 
                if (!ref->peer_ref)
                        continue;
 
-               if (is_null_sha1(ref->peer_ref->new_sha1)) {
+               if (is_null_oid(&ref->peer_ref->new_oid)) {
                        if (delete_remote_branch(ref->name, 1) == -1) {
                                error("Could not remove %s", ref->name);
                                if (helper_status)
@@ -1887,7 +1874,7 @@ int main(int argc, char **argv)
                        continue;
                }
 
-               if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
+               if (!oidcmp(&ref->old_oid, &ref->peer_ref->new_oid)) {
                        if (push_verbosely)
                                fprintf(stderr, "'%s': up-to-date\n", ref->name);
                        if (helper_status)
@@ -1896,11 +1883,11 @@ int main(int argc, char **argv)
                }
 
                if (!force_all &&
-                   !is_null_sha1(ref->old_sha1) &&
+                   !is_null_oid(&ref->old_oid) &&
                    !ref->force) {
-                       if (!has_sha1_file(ref->old_sha1) ||
-                           !ref_newer(ref->peer_ref->new_sha1,
-                                      ref->old_sha1)) {
+                       if (!has_object_file(&ref->old_oid) ||
+                           !ref_newer(ref->peer_ref->new_oid.hash,
+                                      ref->old_oid.hash)) {
                                /*
                                 * We do not have the remote ref, or
                                 * we know that the remote ref is not
@@ -1921,15 +1908,14 @@ int main(int argc, char **argv)
                                continue;
                        }
                }
-               hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
+               oidcpy(&ref->new_oid, &ref->peer_ref->new_oid);
                new_refs++;
-               strcpy(old_hex, sha1_to_hex(ref->old_sha1));
-               new_hex = sha1_to_hex(ref->new_sha1);
 
                fprintf(stderr, "updating '%s'", ref->name);
                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);
+               fprintf(stderr, "\n  from %s\n  to   %s\n",
+                       oid_to_hex(&ref->old_oid), oid_to_hex(&ref->new_oid));
                if (dry_run) {
                        if (helper_status)
                                printf("ok %s\n", ref->name);
@@ -1948,27 +1934,15 @@ int main(int argc, char **argv)
                }
 
                /* Set up revision info for this refspec */
-               commit_argc = 3;
-               new_sha1_hex = xstrdup(sha1_to_hex(ref->new_sha1));
-               old_sha1_hex = NULL;
-               commit_argv[1] = "--objects";
-               commit_argv[2] = new_sha1_hex;
-               if (!push_all && !is_null_sha1(ref->old_sha1)) {
-                       old_sha1_hex = xmalloc(42);
-                       sprintf(old_sha1_hex, "^%s",
-                               sha1_to_hex(ref->old_sha1));
-                       commit_argv[3] = old_sha1_hex;
-                       commit_argc++;
-               }
-               commit_argv[commit_argc] = NULL;
+               argv_array_push(&commit_argv, ""); /* ignored */
+               argv_array_push(&commit_argv, "--objects");
+               argv_array_push(&commit_argv, oid_to_hex(&ref->new_oid));
+               if (!push_all && !is_null_oid(&ref->old_oid))
+                       argv_array_pushf(&commit_argv, "^%s",
+                                        oid_to_hex(&ref->old_oid));
                init_revisions(&revs, setup_git_directory());
-               setup_revisions(commit_argc, commit_argv, &revs, NULL);
+               setup_revisions(commit_argv.argc, commit_argv.argv, &revs, NULL);
                revs.edge_hint = 0; /* just in case */
-               free(new_sha1_hex);
-               if (old_sha1_hex) {
-                       free(old_sha1_hex);
-                       commit_argv[1] = NULL;
-               }
 
                /* Generate a list of objects that need to be pushed */
                pushing = 0;
@@ -1988,7 +1962,7 @@ int main(int argc, char **argv)
                run_request_queue();
 
                /* Update the remote branch if all went well */
-               if (aborted || !update_remote(ref->new_sha1, ref_lock))
+               if (aborted || !update_remote(ref->new_oid.hash, ref_lock))
                        rc = 1;
 
                if (!rc)
@@ -1997,6 +1971,7 @@ int main(int argc, char **argv)
                        printf("%s %s\n", !rc ? "ok" : "error", ref->name);
                unlock_remote(ref_lock);
                check_locks();
+               argv_array_clear(&commit_argv);
        }
 
        /* Update remote server info if appropriate */