Merge branch 'sg/diff-multiple-identical-renames'
[gitweb.git] / builtin / receive-pack.c
index 2b3b746fb40d7a3da9cefd4688b6f60efde10c24..220a899b960a9ddc39ab1e582847ec87d9adad6f 100644 (file)
 #include "sigchain.h"
 #include "fsck.h"
 
-static const char receive_pack_usage[] = "git receive-pack <git-dir>";
+static const char * const receive_pack_usage[] = {
+       N_("git receive-pack <git-dir>"),
+       NULL
+};
 
 enum deny_action {
        DENY_UNCONFIGURED,
@@ -49,7 +52,7 @@ static int quiet;
 static int prefer_ofs_delta = 1;
 static int auto_update_server_info;
 static int auto_gc = 1;
-static int fix_thin = 1;
+static int reject_thin;
 static int stateless_rpc;
 static const char *service_dir;
 static const char *head_name;
@@ -1031,7 +1034,6 @@ static void run_update_post_hook(struct command *commands)
 {
        struct command *cmd;
        int argc;
-       const char **argv;
        struct child_process proc = CHILD_PROCESS_INIT;
        const char *hook;
 
@@ -1044,21 +1046,16 @@ static void run_update_post_hook(struct command *commands)
        if (!argc || !hook)
                return;
 
-       argv = xmalloc(sizeof(*argv) * (2 + argc));
-       argv[0] = hook;
-
-       for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
+       argv_array_push(&proc.args, hook);
+       for (cmd = commands; cmd; cmd = cmd->next) {
                if (cmd->error_string || cmd->did_not_exist)
                        continue;
-               argv[argc] = xstrdup(cmd->ref_name);
-               argc++;
+               argv_array_push(&proc.args, cmd->ref_name);
        }
-       argv[argc] = NULL;
 
        proc.no_stdin = 1;
        proc.stdout_to_stderr = 1;
        proc.err = use_sideband ? -1 : 0;
-       proc.argv = argv;
 
        if (!start_command(&proc)) {
                if (use_sideband)
@@ -1378,7 +1375,7 @@ static struct command **queue_command(struct command **tail,
 
        refname = line + 82;
        reflen = linelen - 82;
-       cmd = xcalloc(1, sizeof(struct command) + reflen + 1);
+       cmd = xcalloc(1, st_add3(sizeof(struct command), reflen, 1));
        hashcpy(cmd->old_sha1, old_sha1);
        hashcpy(cmd->new_sha1, new_sha1);
        memcpy(cmd->ref_name, refname, reflen);
@@ -1554,7 +1551,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                if (fsck_objects)
                        argv_array_pushf(&child.args, "--strict%s",
                                fsck_msg_types.buf);
-               if (fix_thin)
+               if (!reject_thin)
                        argv_array_push(&child.args, "--fix-thin");
                child.out = -1;
                child.err = err_fd;
@@ -1597,8 +1594,7 @@ static void prepare_shallow_update(struct command *commands,
 {
        int i, j, k, bitmap_size = (si->ref->nr + 31) / 32;
 
-       si->used_shallow = xmalloc(sizeof(*si->used_shallow) *
-                                  si->shallow->nr);
+       ALLOC_ARRAY(si->used_shallow, si->shallow->nr);
        assign_shallow_commits_to_refs(si, si->used_shallow, NULL);
 
        si->need_reachability_test =
@@ -1664,7 +1660,7 @@ static void update_shallow_info(struct command *commands,
                return;
        }
 
-       ref_status = xmalloc(sizeof(*ref_status) * ref->nr);
+       ALLOC_ARRAY(ref_status, ref->nr);
        assign_shallow_commits_to_refs(si, NULL, ref_status);
        for (cmd = commands; cmd; cmd = cmd->next) {
                if (is_null_sha1(cmd->new_sha1))
@@ -1714,45 +1710,29 @@ static int delete_only(struct command *commands)
 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 {
        int advertise_refs = 0;
-       int i;
        struct command *commands;
        struct sha1_array shallow = SHA1_ARRAY_INIT;
        struct sha1_array ref = SHA1_ARRAY_INIT;
        struct shallow_info si;
 
-       packet_trace_identity("receive-pack");
+       struct option options[] = {
+               OPT__QUIET(&quiet, N_("quiet")),
+               OPT_HIDDEN_BOOL(0, "stateless-rpc", &stateless_rpc, NULL),
+               OPT_HIDDEN_BOOL(0, "advertise-refs", &advertise_refs, NULL),
+               OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL),
+               OPT_END()
+       };
 
-       argv++;
-       for (i = 1; i < argc; i++) {
-               const char *arg = *argv++;
+       packet_trace_identity("receive-pack");
 
-               if (*arg == '-') {
-                       if (!strcmp(arg, "--quiet")) {
-                               quiet = 1;
-                               continue;
-                       }
+       argc = parse_options(argc, argv, prefix, options, receive_pack_usage, 0);
 
-                       if (!strcmp(arg, "--advertise-refs")) {
-                               advertise_refs = 1;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--stateless-rpc")) {
-                               stateless_rpc = 1;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--reject-thin-pack-for-testing")) {
-                               fix_thin = 0;
-                               continue;
-                       }
+       if (argc > 1)
+               usage_msg_opt(_("Too many arguments."), receive_pack_usage, options);
+       if (argc == 0)
+               usage_msg_opt(_("You must specify a directory."), receive_pack_usage, options);
 
-                       usage(receive_pack_usage);
-               }
-               if (service_dir)
-                       usage(receive_pack_usage);
-               service_dir = arg;
-       }
-       if (!service_dir)
-               usage(receive_pack_usage);
+       service_dir = argv[0];
 
        setup_path();
 
@@ -1796,6 +1776,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
                                "gc", "--auto", "--quiet", NULL,
                        };
                        int opt = RUN_GIT_CMD | RUN_COMMAND_STDOUT_TO_STDERR;
+                       close_all_packs();
                        run_command_v_opt(argv_gc_auto, opt);
                }
                if (auto_update_server_info)