Merge branch 'mh/simplify-repack-without-refs'
authorJunio C Hamano <gitster@pobox.com>
Mon, 22 Dec 2014 20:26:50 +0000 (12:26 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Dec 2014 20:26:50 +0000 (12:26 -0800)
"git remote update --prune" to drop many refs has been optimized.

* mh/simplify-repack-without-refs:
sort_string_list(): rename to string_list_sort()
prune_remote(): iterate using for_each_string_list_item()
prune_remote(): rename local variable
repack_without_refs(): make the refnames argument a string_list
prune_remote(): sort delete_refs_list references en masse
prune_remote(): initialize both delete_refs lists in a single loop
prune_remote(): exit early if there are no stale references

1  2 
builtin/apply.c
builtin/receive-pack.c
builtin/repack.c
connect.c
notes.c
refs.c
diff --combined builtin/apply.c
index 28d24f8e34c041c5afff4c659efbfeed4d5dc8c2,22218f90a6f0b30dc3893f39424643cad84b8372..0aad91283959bce51aba596c6f3d2d0925e5ba92
@@@ -3728,7 -3728,7 +3728,7 @@@ static void build_fake_ancestor(struct 
                        if (!preimage_sha1_in_gitlink_patch(patch, sha1))
                                ; /* ok, the textual part looks sane */
                        else
 -                              die("sha1 information is lacking or useless for submoule %s",
 +                              die("sha1 information is lacking or useless for submodule %s",
                                    name);
                } else if (!get_sha1_blob(patch->old_sha1_prefix, sha1)) {
                        ; /* ok */
@@@ -4180,7 -4180,7 +4180,7 @@@ static int write_out_results(struct pat
        if (cpath.nr) {
                struct string_list_item *item;
  
-               sort_string_list(&cpath);
+               string_list_sort(&cpath);
                for_each_string_list_item(item, &cpath)
                        fprintf(stderr, "U %s\n", item->string);
                string_list_clear(&cpath, 0);
diff --combined builtin/receive-pack.c
index e908d079bae83884cc218cf6a39d3ed705cf439b,d7ce6437f491655fe973ac04137a14dd2cc26e20..1eefaddac883399b465dde1601ffbdfc579312c1
@@@ -431,7 -431,7 +431,7 @@@ static const char *check_nonce(const ch
        nonce_stamp_slop = (long)ostamp - (long)stamp;
  
        if (nonce_stamp_slop_limit &&
 -          abs(nonce_stamp_slop) <= nonce_stamp_slop_limit) {
 +          labs(nonce_stamp_slop) <= nonce_stamp_slop_limit) {
                /*
                 * Pretend as if the received nonce (which passes the
                 * HMAC check, so it is not a forged by third-party)
@@@ -964,7 -964,7 +964,7 @@@ static void check_aliased_updates(struc
                        string_list_append(&ref_list, cmd->ref_name);
                item->util = (void *)cmd;
        }
-       sort_string_list(&ref_list);
+       string_list_sort(&ref_list);
  
        for (cmd = commands; cmd; cmd = cmd->next) {
                if (!cmd->error_string)
diff --combined builtin/repack.c
index 83e91c7382fc913ca7c51e6286cd73cdd91fbeae,0705d6802faaac96a59fae6107e021ca973d5874..3f852f35d1e786b2584d435d640ae830a9f34639
@@@ -135,6 -135,7 +135,6 @@@ int cmd_repack(int argc, const char **a
        };
        struct child_process cmd = CHILD_PROCESS_INIT;
        struct string_list_item *item;
 -      struct argv_array cmd_args = ARGV_ARRAY_INIT;
        struct string_list names = STRING_LIST_INIT_DUP;
        struct string_list rollback = STRING_LIST_INIT_NODUP;
        struct string_list existing_packs = STRING_LIST_INIT_DUP;
  
        sigchain_push_common(remove_pack_on_signal);
  
 -      argv_array_push(&cmd_args, "pack-objects");
 -      argv_array_push(&cmd_args, "--keep-true-parents");
 +      argv_array_push(&cmd.args, "pack-objects");
 +      argv_array_push(&cmd.args, "--keep-true-parents");
        if (!pack_kept_objects)
 -              argv_array_push(&cmd_args, "--honor-pack-keep");
 -      argv_array_push(&cmd_args, "--non-empty");
 -      argv_array_push(&cmd_args, "--all");
 -      argv_array_push(&cmd_args, "--reflog");
 -      argv_array_push(&cmd_args, "--indexed-objects");
 +              argv_array_push(&cmd.args, "--honor-pack-keep");
 +      argv_array_push(&cmd.args, "--non-empty");
 +      argv_array_push(&cmd.args, "--all");
 +      argv_array_push(&cmd.args, "--reflog");
 +      argv_array_push(&cmd.args, "--indexed-objects");
        if (window)
 -              argv_array_pushf(&cmd_args, "--window=%s", window);
 +              argv_array_pushf(&cmd.args, "--window=%s", window);
        if (window_memory)
 -              argv_array_pushf(&cmd_args, "--window-memory=%s", window_memory);
 +              argv_array_pushf(&cmd.args, "--window-memory=%s", window_memory);
        if (depth)
 -              argv_array_pushf(&cmd_args, "--depth=%s", depth);
 +              argv_array_pushf(&cmd.args, "--depth=%s", depth);
        if (max_pack_size)
 -              argv_array_pushf(&cmd_args, "--max-pack-size=%s", max_pack_size);
 +              argv_array_pushf(&cmd.args, "--max-pack-size=%s", max_pack_size);
        if (no_reuse_delta)
 -              argv_array_pushf(&cmd_args, "--no-reuse-delta");
 +              argv_array_pushf(&cmd.args, "--no-reuse-delta");
        if (no_reuse_object)
 -              argv_array_pushf(&cmd_args, "--no-reuse-object");
 +              argv_array_pushf(&cmd.args, "--no-reuse-object");
        if (write_bitmaps)
 -              argv_array_push(&cmd_args, "--write-bitmap-index");
 +              argv_array_push(&cmd.args, "--write-bitmap-index");
  
        if (pack_everything & ALL_INTO_ONE) {
                get_non_kept_pack_filenames(&existing_packs);
  
                if (existing_packs.nr && delete_redundant) {
                        if (unpack_unreachable)
 -                              argv_array_pushf(&cmd_args,
 +                              argv_array_pushf(&cmd.args,
                                                "--unpack-unreachable=%s",
                                                unpack_unreachable);
                        else if (pack_everything & LOOSEN_UNREACHABLE)
 -                              argv_array_push(&cmd_args,
 +                              argv_array_push(&cmd.args,
                                                "--unpack-unreachable");
                }
        } else {
 -              argv_array_push(&cmd_args, "--unpacked");
 -              argv_array_push(&cmd_args, "--incremental");
 +              argv_array_push(&cmd.args, "--unpacked");
 +              argv_array_push(&cmd.args, "--incremental");
        }
  
        if (local)
 -              argv_array_push(&cmd_args,  "--local");
 +              argv_array_push(&cmd.args,  "--local");
        if (quiet)
 -              argv_array_push(&cmd_args,  "--quiet");
 +              argv_array_push(&cmd.args,  "--quiet");
        if (delta_base_offset)
 -              argv_array_push(&cmd_args,  "--delta-base-offset");
 +              argv_array_push(&cmd.args,  "--delta-base-offset");
  
 -      argv_array_push(&cmd_args, packtmp);
 +      argv_array_push(&cmd.args, packtmp);
  
 -      cmd.argv = cmd_args.argv;
        cmd.git_cmd = 1;
        cmd.out = -1;
        cmd.no_stdin = 1;
        ret = finish_command(&cmd);
        if (ret)
                return ret;
 -      argv_array_clear(&cmd_args);
  
        if (!names.nr && !quiet)
                printf("Nothing new to pack.\n");
  
        if (delete_redundant) {
                int opts = 0;
-               sort_string_list(&names);
+               string_list_sort(&names);
                for_each_string_list_item(item, &existing_packs) {
                        char *sha1;
                        size_t len = strlen(item->string);
diff --combined connect.c
index cb23bbcf22c8804c9e589dcaf1a42c3340c27782,16f74b0ad380b02f1b42d0b12e1e09c98e63a603..062e133aa39b9e522bf3a03c5e57ac67c03ad88e
+++ b/connect.c
@@@ -93,7 -93,7 +93,7 @@@ static void annotate_refs_with_symref_i
                parse_one_symref_info(&symref, val, len);
                feature_list = val + 1;
        }
-       sort_string_list(&symref);
+       string_list_sort(&symref);
  
        for (; ref; ref = ref->next) {
                struct string_list_item *item;
@@@ -700,23 -700,14 +700,23 @@@ struct child_process *git_connect(int f
  
                conn->in = conn->out = -1;
                if (protocol == PROTO_SSH) {
 -                      const char *ssh = getenv("GIT_SSH");
 -                      int putty = ssh && strcasestr(ssh, "plink");
 +                      const char *ssh;
 +                      int putty;
                        char *ssh_host = hostandport;
                        const char *port = NULL;
                        get_host_and_port(&ssh_host, &port);
                        port = get_port_numeric(port);
  
 -                      if (!ssh) ssh = "ssh";
 +                      ssh = getenv("GIT_SSH_COMMAND");
 +                      if (ssh) {
 +                              conn->use_shell = 1;
 +                              putty = 0;
 +                      } else {
 +                              ssh = getenv("GIT_SSH");
 +                              if (!ssh)
 +                                      ssh = "ssh";
 +                              putty = !!strcasestr(ssh, "plink");
 +                      }
  
                        argv_array_push(&conn->args, ssh);
                        if (putty && !strcasestr(ssh, "tortoiseplink"))
diff --combined notes.c
index 62bc6e1818f02dea10022e3df30b4129ee1d8fcd,40f44183780eef5939daba3b3b555f7fa9340c62..c763a21eef5b64c984c22d18cd5f21c1bd32e5a3
+++ b/notes.c
@@@ -902,7 -902,7 +902,7 @@@ int combine_notes_cat_sort_uniq(unsigne
        if (string_list_add_note_lines(&sort_uniq_list, new_sha1))
                goto out;
        string_list_remove_empty_items(&sort_uniq_list, 0);
-       sort_string_list(&sort_uniq_list);
+       string_list_sort(&sort_uniq_list);
        string_list_remove_duplicates(&sort_uniq_list, 0);
  
        /* create a new blob object from sort_uniq_list */
@@@ -1218,7 -1218,8 +1218,7 @@@ static void format_note(struct notes_tr
        if (!sha1)
                return;
  
 -      if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||
 -                      type != OBJ_BLOB) {
 +      if (!(msg = read_sha1_file(sha1, &type, &msglen)) || type != OBJ_BLOB) {
                free(msg);
                return;
        }
diff --combined refs.c
index 0347328fda315ada005aeb064d0d10e59d8822fa,b675e013a941048f315cc88f836e91b8dc2f44a3..898d3c2ca4685a7ea47fbd3e34a384a77a1dea8a
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -2318,7 -2318,6 +2318,7 @@@ static struct ref_lock *lock_ref_sha1_b
  
        lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags);
        if (lock->lock_fd < 0) {
 +              last_errno = errno;
                if (errno == ENOENT && --attempts_remaining > 0)
                        /*
                         * Maybe somebody just deleted one of the
                         * again:
                         */
                        goto retry;
 -              else
 -                      unable_to_lock_die(ref_file, errno);
 +              else {
 +                      struct strbuf err = STRBUF_INIT;
 +                      unable_to_lock_message(ref_file, errno, &err);
 +                      error("%s", err.buf);
 +                      strbuf_reset(&err);
 +                      goto error_return;
 +              }
        }
        return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
  
@@@ -2645,22 -2639,25 +2645,25 @@@ static int curate_packed_ref_fn(struct 
        return 0;
  }
  
- int repack_without_refs(const char **refnames, int n, struct strbuf *err)
+ int repack_without_refs(struct string_list *refnames, struct strbuf *err)
  {
        struct ref_dir *packed;
        struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
-       struct string_list_item *ref_to_delete;
-       int i, ret, removed = 0;
+       struct string_list_item *refname, *ref_to_delete;
+       int ret, needs_repacking = 0, removed = 0;
  
        assert(err);
  
        /* Look for a packed ref */
-       for (i = 0; i < n; i++)
-               if (get_packed_ref(refnames[i]))
+       for_each_string_list_item(refname, refnames) {
+               if (get_packed_ref(refname->string)) {
+                       needs_repacking = 1;
                        break;
+               }
+       }
  
        /* Avoid locking if we have nothing to do */
-       if (i == n)
+       if (!needs_repacking)
                return 0; /* no refname exists in packed refs */
  
        if (lock_packed_refs(0)) {
        packed = get_packed_refs(&ref_cache);
  
        /* Remove refnames from the cache */
-       for (i = 0; i < n; i++)
-               if (remove_entry(packed, refnames[i]) != -1)
+       for_each_string_list_item(refname, refnames)
+               if (remove_entry(packed, refname->string) != -1)
                        removed = 1;
        if (!removed) {
                /*
@@@ -3744,10 -3741,11 +3747,11 @@@ static int ref_update_reject_duplicates
  int ref_transaction_commit(struct ref_transaction *transaction,
                           struct strbuf *err)
  {
-       int ret = 0, delnum = 0, i;
-       const char **delnames;
+       int ret = 0, i;
        int n = transaction->nr;
        struct ref_update **updates = transaction->updates;
+       struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
+       struct string_list_item *ref_to_delete;
  
        assert(err);
  
                return 0;
        }
  
-       /* Allocate work space */
-       delnames = xmalloc(sizeof(*delnames) * n);
        /* Copy, sort, and reject duplicate refs */
        qsort(updates, n, sizeof(*updates), ref_update_compare);
        if (ref_update_reject_duplicates(updates, n, err)) {
                        }
  
                        if (!(update->flags & REF_ISPRUNING))
-                               delnames[delnum++] = update->lock->ref_name;
+                               string_list_append(&refs_to_delete,
+                                                  update->lock->ref_name);
                }
        }
  
-       if (repack_without_refs(delnames, delnum, err)) {
+       if (repack_without_refs(&refs_to_delete, err)) {
                ret = TRANSACTION_GENERIC_ERROR;
                goto cleanup;
        }
-       for (i = 0; i < delnum; i++)
-               unlink_or_warn(git_path("logs/%s", delnames[i]));
+       for_each_string_list_item(ref_to_delete, &refs_to_delete)
+               unlink_or_warn(git_path("logs/%s", ref_to_delete->string));
        clear_loose_ref_cache(&ref_cache);
  
  cleanup:
        for (i = 0; i < n; i++)
                if (updates[i]->lock)
                        unlock_ref(updates[i]->lock);
-       free(delnames);
+       string_list_clear(&refs_to_delete, 0);
        return ret;
  }