Merge branch 'nd/use-opt-int-set-f'
authorJunio C Hamano <gitster@pobox.com>
Fri, 1 Jun 2018 06:06:38 +0000 (15:06 +0900)
committerJunio C Hamano <gitster@pobox.com>
Fri, 1 Jun 2018 06:06:38 +0000 (15:06 +0900)
Code simplification.

* nd/use-opt-int-set-f:
Use OPT_SET_INT_F() for cmdline option specification

1  2 
builtin/am.c
builtin/branch.c
builtin/difftool.c
builtin/fetch.c
builtin/grep.c
builtin/ls-files.c
builtin/merge.c
builtin/notes.c
builtin/pack-objects.c
diff --combined builtin/am.c
index aa989e73901d17a35680cf14930430e5e24f6122,a1ff235fbc7bd815047d2bf58a03878d89178ea8..2fc2d1e82c5ead598476964329b555e38de9a495
@@@ -403,11 -403,11 +403,11 @@@ static void am_load(struct am_state *st
        struct strbuf sb = STRBUF_INIT;
  
        if (read_state_file(&sb, state, "next", 1) < 0)
 -              die("BUG: state file 'next' does not exist");
 +              BUG("state file 'next' does not exist");
        state->cur = strtol(sb.buf, NULL, 10);
  
        if (read_state_file(&sb, state, "last", 1) < 0)
 -              die("BUG: state file 'last' does not exist");
 +              BUG("state file 'last' does not exist");
        state->last = strtol(sb.buf, NULL, 10);
  
        if (read_author_script(state) < 0)
@@@ -986,7 -986,7 +986,7 @@@ static int split_mail(struct am_state *
        case PATCH_FORMAT_MBOXRD:
                return split_mail_mbox(state, paths, keep_cr, 1);
        default:
 -              die("BUG: invalid patch_format");
 +              BUG("invalid patch_format");
        }
        return -1;
  }
@@@ -1041,7 -1041,7 +1041,7 @@@ static void am_setup(struct am_state *s
                str = "b";
                break;
        default:
 -              die("BUG: invalid value for state->keep");
 +              BUG("invalid value for state->keep");
        }
  
        write_state_text(state, "keep", str);
                str = "t";
                break;
        default:
 -              die("BUG: invalid value for state->scissors");
 +              BUG("invalid value for state->scissors");
        }
        write_state_text(state, "scissors", str);
  
@@@ -1216,7 -1216,7 +1216,7 @@@ static int parse_mail(struct am_state *
                mi.keep_non_patch_brackets_in_subject = 1;
                break;
        default:
 -              die("BUG: invalid value for state->keep");
 +              BUG("invalid value for state->keep");
        }
  
        if (state->message_id)
                mi.use_scissors = 1;
                break;
        default:
 -              die("BUG: invalid value for state->scissors");
 +              BUG("invalid value for state->scissors");
        }
  
        mi.input = xfopen(mail, "r");
@@@ -1463,7 -1463,7 +1463,7 @@@ static int run_apply(const struct am_st
        int options = 0;
  
        if (init_apply_state(&apply_state, NULL))
 -              die("BUG: init_apply_state() failed");
 +              BUG("init_apply_state() failed");
  
        argv_array_push(&apply_opts, "apply");
        argv_array_pushv(&apply_opts, state->git_apply_opts.argv);
                apply_state.apply_verbosity = verbosity_silent;
  
        if (check_apply_state(&apply_state, force_apply))
 -              die("BUG: check_apply_state() failed");
 +              BUG("check_apply_state() failed");
  
        argv_array_push(&apply_paths, am_path(state, "patch"));
  
@@@ -1542,7 -1542,7 +1542,7 @@@ static int fall_back_threeway(const str
        char *their_tree_name;
  
        if (get_oid("HEAD", &our_tree) < 0)
 -              hashcpy(our_tree.hash, EMPTY_TREE_SHA1_BIN);
 +              oidcpy(&our_tree, the_hash_algo->empty_tree);
  
        if (build_fake_ancestor(state, index_path))
                return error("could not build fake ancestor");
@@@ -2042,7 -2042,7 +2042,7 @@@ static void am_skip(struct am_state *st
        am_rerere_clear();
  
        if (get_oid("HEAD", &head))
 -              hashcpy(head.hash, EMPTY_TREE_SHA1_BIN);
 +              oidcpy(&head, the_hash_algo->empty_tree);
  
        if (clean_index(&head, &head))
                die(_("failed to clean index"));
@@@ -2105,11 -2105,11 +2105,11 @@@ static void am_abort(struct am_state *s
        curr_branch = resolve_refdup("HEAD", 0, &curr_head, NULL);
        has_curr_head = curr_branch && !is_null_oid(&curr_head);
        if (!has_curr_head)
 -              hashcpy(curr_head.hash, EMPTY_TREE_SHA1_BIN);
 +              oidcpy(&curr_head, the_hash_algo->empty_tree);
  
        has_orig_head = !get_oid("ORIG_HEAD", &orig_head);
        if (!has_orig_head)
 -              hashcpy(orig_head.hash, EMPTY_TREE_SHA1_BIN);
 +              oidcpy(&orig_head, the_hash_algo->empty_tree);
  
        clean_index(&curr_head, &orig_head);
  
@@@ -2231,12 -2231,12 +2231,12 @@@ int cmd_am(int argc, const char **argv
                        N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),
                OPT_BOOL('m', "message-id", &state.message_id,
                        N_("pass -m flag to git-mailinfo")),
-               { OPTION_SET_INT, 0, "keep-cr", &keep_cr, NULL,
-                 N_("pass --keep-cr flag to git-mailsplit for mbox format"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
-               { OPTION_SET_INT, 0, "no-keep-cr", &keep_cr, NULL,
-                 N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 0},
+               OPT_SET_INT_F(0, "keep-cr", &keep_cr,
+                       N_("pass --keep-cr flag to git-mailsplit for mbox format"),
+                       1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "no-keep-cr", &keep_cr,
+                       N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),
+                       0, PARSE_OPT_NONEG),
                OPT_BOOL('c', "scissors", &state.scissors,
                        N_("strip everything before a scissors line")),
                OPT_PASSTHRU_ARGV(0, "whitespace", &state.git_apply_opts, N_("action"),
                ret = show_patch(&state);
                break;
        default:
 -              die("BUG: invalid resume value");
 +              BUG("invalid resume value");
        }
  
        am_state_release(&state);
diff --combined builtin/branch.c
index 5bb5123e7290d4a72672436737a8a56c647acbb6,cc089f9efb29c4a1eb2d2f4abb024b99f7809553..d53f6e2ad4c30ef02262ff3fa01ecdb54be96f11
@@@ -500,7 -500,7 +500,7 @@@ static void copy_or_rename_branch(cons
  
        if (!skip_prefix(oldref.buf, "refs/heads/", &interpreted_oldname) ||
            !skip_prefix(newref.buf, "refs/heads/", &interpreted_newname)) {
 -              die("BUG: expected prefix missing for refs");
 +              BUG("expected prefix missing for refs");
        }
  
        if (copy)
@@@ -592,8 -592,8 +592,8 @@@ int cmd_branch(int argc, const char **a
                OPT__QUIET(&quiet, N_("suppress informational messages")),
                OPT_SET_INT('t', "track",  &track, N_("set up tracking mode (see git-pull(1))"),
                        BRANCH_TRACK_EXPLICIT),
-               { OPTION_SET_INT, 0, "set-upstream", &track, NULL, N_("do not use"),
-                       PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, BRANCH_TRACK_OVERRIDE },
+               OPT_SET_INT_F(0, "set-upstream", &track, N_("do not use"),
+                       BRANCH_TRACK_OVERRIDE, PARSE_OPT_HIDDEN),
                OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")),
                OPT_BOOL(0, "unset-upstream", &unset_upstream, N_("Unset the upstream info")),
                OPT__COLOR(&branch_use_color, N_("use colored output")),
diff --combined builtin/difftool.c
index 162806f2385c944a3708dd31f38a5d1e2010aa5a,c439b6420788c42f6cae248a97b642e698fd88dc..bc97d4aef2db2d76e3ffddfc4759e52688f3974e
@@@ -610,7 -610,7 +610,7 @@@ static int run_dir_diff(const char *ext
                        continue;
  
                if (!indices_loaded) {
 -                      static struct lock_file lock;
 +                      struct lock_file lock = LOCK_INIT;
                        strbuf_reset(&buf);
                        strbuf_addf(&buf, "%s/wtindex", tmpdir);
                        if (hold_lock_file_for_update(&lock, buf.buf, 0) < 0 ||
@@@ -695,12 -695,11 +695,11 @@@ int cmd_difftool(int argc, const char *
                         N_("use `diff.guitool` instead of `diff.tool`")),
                OPT_BOOL('d', "dir-diff", &dir_diff,
                         N_("perform a full-directory diff")),
-               { OPTION_SET_INT, 'y', "no-prompt", &prompt, NULL,
+               OPT_SET_INT_F('y', "no-prompt", &prompt,
                        N_("do not prompt before launching a diff tool"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 0},
-               { OPTION_SET_INT, 0, "prompt", &prompt, NULL, NULL,
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN,
-                       NULL, 1 },
+                       0, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "prompt", &prompt, NULL,
+                       1, PARSE_OPT_NONEG | PARSE_OPT_HIDDEN),
                OPT_BOOL(0, "symlinks", &symlinks,
                         N_("use symlinks in dir-diff mode")),
                OPT_STRING('t', "tool", &difftool_cmd, N_("<tool>"),
diff --combined builtin/fetch.c
index c0d8ad1fe2aa7fe1ddbafa660746418301239463,0a4512b0fb8f9c0800ffb9a3d6714241da7e3ba5..ea5b9669ad1f40da56a8565cada56e5991d24206
@@@ -5,7 -5,6 +5,7 @@@
  #include "config.h"
  #include "repository.h"
  #include "refs.h"
 +#include "refspec.h"
  #include "commit.h"
  #include "builtin.h"
  #include "string-list.h"
@@@ -60,7 -59,8 +60,7 @@@ static const char *submodule_prefix = "
  static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
  static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
  static int shown_url = 0;
 -static int refmap_alloc, refmap_nr;
 -static const char **refmap_array;
 +static struct refspec refmap = REFSPEC_INIT_FETCH;
  static struct list_objects_filter_options filter_options;
  static struct string_list server_options = STRING_LIST_INIT_DUP;
  
@@@ -108,12 -108,14 +108,12 @@@ static int gitmodules_fetch_config(cons
  
  static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
  {
 -      ALLOC_GROW(refmap_array, refmap_nr + 1, refmap_alloc);
 -
        /*
         * "git fetch --refmap='' origin foo"
         * can be used to tell the command not to store anywhere
         */
 -      if (*arg)
 -              refmap_array[refmap_nr++] = arg;
 +      refspec_append(&refmap, arg);
 +
        return 0;
  }
  
@@@ -155,9 -157,9 +155,9 @@@ static struct option builtin_fetch_opti
                        N_("deepen history of shallow clone, excluding rev")),
        OPT_INTEGER(0, "deepen", &deepen_relative,
                    N_("deepen history of shallow clone")),
-       { OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
-                  N_("convert to a complete repository"),
-                  PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
+       OPT_SET_INT_F(0, "unshallow", &unshallow,
+                     N_("convert to a complete repository"),
+                     1, PARSE_OPT_NONEG),
        { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
                   N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
        { OPTION_CALLBACK, 0, "recurse-submodules-default",
@@@ -202,7 -204,7 +202,7 @@@ static void add_merge_config(struct re
  
        for (i = 0; i < branch->merge_nr; i++) {
                struct ref *rm, **old_tail = *tail;
 -              struct refspec refspec;
 +              struct refspec_item refspec;
  
                for (rm = *head; rm; rm = rm->next) {
                        if (branch_merge_matches(branch, i, rm->name)) {
@@@ -339,7 -341,7 +339,7 @@@ static void find_non_local_tags(struct 
  }
  
  static struct ref *get_ref_map(struct transport *transport,
 -                             struct refspec *refspecs, int refspec_count,
 +                             struct refspec *rs,
                               int tags, int *autotags)
  {
        int i;
  
        const struct ref *remote_refs;
  
 -      for (i = 0; i < refspec_count; i++) {
 -              if (!refspecs[i].exact_sha1) {
 -                      const char *glob = strchr(refspecs[i].src, '*');
 -                      if (glob)
 -                              argv_array_pushf(&ref_prefixes, "%.*s",
 -                                               (int)(glob - refspecs[i].src),
 -                                               refspecs[i].src);
 -                      else
 -                              expand_ref_prefix(&ref_prefixes, refspecs[i].src);
 -              }
 +      if (rs->nr)
 +              refspec_ref_prefixes(rs, &ref_prefixes);
 +      else if (transport->remote && transport->remote->fetch.nr)
 +              refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
 +
 +      if (ref_prefixes.argc &&
 +          (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) {
 +              argv_array_push(&ref_prefixes, "refs/tags/");
        }
  
        remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
  
        argv_array_clear(&ref_prefixes);
  
 -      if (refspec_count) {
 +      if (rs->nr) {
                struct refspec *fetch_refspec;
 -              int fetch_refspec_nr;
  
 -              for (i = 0; i < refspec_count; i++) {
 -                      get_fetch_map(remote_refs, &refspecs[i], &tail, 0);
 -                      if (refspecs[i].dst && refspecs[i].dst[0])
 +              for (i = 0; i < rs->nr; i++) {
 +                      get_fetch_map(remote_refs, &rs->items[i], &tail, 0);
 +                      if (rs->items[i].dst && rs->items[i].dst[0])
                                *autotags = 1;
                }
                /* Merge everything on the command line (but not --tags) */
                 * by ref_remove_duplicates() in favor of one of these
                 * opportunistic entries with FETCH_HEAD_IGNORE.
                 */
 -              if (refmap_array) {
 -                      fetch_refspec = parse_fetch_refspec(refmap_nr, refmap_array);
 -                      fetch_refspec_nr = refmap_nr;
 -              } else {
 -                      fetch_refspec = transport->remote->fetch;
 -                      fetch_refspec_nr = transport->remote->fetch_refspec_nr;
 -              }
 +              if (refmap.nr)
 +                      fetch_refspec = &refmap;
 +              else
 +                      fetch_refspec = &transport->remote->fetch;
  
 -              for (i = 0; i < fetch_refspec_nr; i++)
 -                      get_fetch_map(ref_map, &fetch_refspec[i], &oref_tail, 1);
 -      } else if (refmap_array) {
 +              for (i = 0; i < fetch_refspec->nr; i++)
 +                      get_fetch_map(ref_map, &fetch_refspec->items[i], &oref_tail, 1);
 +      } else if (refmap.nr) {
                die("--refmap option is only meaningful with command-line refspec(s).");
        } else {
                /* Use the defaults */
                struct branch *branch = branch_get(NULL);
                int has_merge = branch_has_merge_config(branch);
                if (remote &&
 -                  (remote->fetch_refspec_nr ||
 +                  (remote->fetch.nr ||
                     /* Note: has_merge implies non-NULL branch->remote_name */
                     (has_merge && !strcmp(branch->remote_name, remote->name)))) {
 -                      for (i = 0; i < remote->fetch_refspec_nr; i++) {
 -                              get_fetch_map(remote_refs, &remote->fetch[i], &tail, 0);
 -                              if (remote->fetch[i].dst &&
 -                                  remote->fetch[i].dst[0])
 +                      for (i = 0; i < remote->fetch.nr; i++) {
 +                              get_fetch_map(remote_refs, &remote->fetch.items[i], &tail, 0);
 +                              if (remote->fetch.items[i].dst &&
 +                                  remote->fetch.items[i].dst[0])
                                        *autotags = 1;
                                if (!i && !has_merge && ref_map &&
 -                                  !remote->fetch[0].pattern)
 +                                  !remote->fetch.items[0].pattern)
                                        ref_map->fetch_head_status = FETCH_HEAD_MERGE;
                        }
                        /*
@@@ -958,11 -966,11 +958,11 @@@ static int fetch_refs(struct transport 
        return ret;
  }
  
 -static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
 -              const char *raw_url)
 +static int prune_refs(struct refspec *rs, struct ref *ref_map,
 +                    const char *raw_url)
  {
        int url_len, i, result = 0;
 -      struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
 +      struct ref *ref, *stale_refs = get_stale_heads(rs, ref_map);
        char *url;
        int summary_width = transport_summary_width(stale_refs);
        const char *dangling_msg = dry_run
@@@ -1108,7 -1116,7 +1108,7 @@@ static void backfill_tags(struct transp
  }
  
  static int do_fetch(struct transport *transport,
 -                  struct refspec *refs, int ref_count)
 +                  struct refspec *rs)
  {
        struct string_list existing_refs = STRING_LIST_INIT_DUP;
        struct ref *ref_map;
                        goto cleanup;
        }
  
 -      ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
 +      ref_map = get_ref_map(transport, rs, tags, &autotags);
        if (!update_head_ok)
                check_not_current_branch(ref_map);
  
                 * explicitly (via command line or configuration); we
                 * don't care whether --tags was specified.
                 */
 -              if (ref_count) {
 -                      prune_refs(refs, ref_count, ref_map, transport->url);
 +              if (rs->nr) {
 +                      prune_refs(rs, ref_map, transport->url);
                } else {
 -                      prune_refs(transport->remote->fetch,
 -                                 transport->remote->fetch_refspec_nr,
 +                      prune_refs(&transport->remote->fetch,
                                   ref_map,
                                   transport->url);
                }
@@@ -1348,8 -1357,10 +1348,8 @@@ static inline void fetch_one_setup_part
  
  static int fetch_one(struct remote *remote, int argc, const char **argv, int prune_tags_ok)
  {
 -      static const char **refs = NULL;
 -      struct refspec *refspec;
 -      int ref_nr = 0;
 -      int j = 0;
 +      struct refspec rs = REFSPEC_INIT_FETCH;
 +      int i;
        int exit_code;
        int maybe_prune_tags;
        int remote_via_config = remote_is_configured(remote, 0);
  
        maybe_prune_tags = prune_tags_ok && prune_tags;
        if (maybe_prune_tags && remote_via_config)
 -              add_prune_tags_to_fetch_refspec(remote);
 -
 -      if (argc > 0 || (maybe_prune_tags && !remote_via_config)) {
 -              size_t nr_alloc = st_add3(argc, maybe_prune_tags, 1);
 -              refs = xcalloc(nr_alloc, sizeof(const char *));
 -              if (maybe_prune_tags) {
 -                      refs[j++] = xstrdup("refs/tags/*:refs/tags/*");
 -                      ref_nr++;
 -              }
 -      }
 -
 -      if (argc > 0) {
 -              int i;
 -              for (i = 0; i < argc; i++) {
 -                      if (!strcmp(argv[i], "tag")) {
 -                              i++;
 -                              if (i >= argc)
 -                                      die(_("You need to specify a tag name."));
 -                              refs[j++] = xstrfmt("refs/tags/%s:refs/tags/%s",
 -                                                  argv[i], argv[i]);
 -                      } else
 -                              refs[j++] = argv[i];
 -                      ref_nr++;
 +              refspec_append(&remote->fetch, TAG_REFSPEC);
 +
 +      if (maybe_prune_tags && (argc || !remote_via_config))
 +              refspec_append(&rs, TAG_REFSPEC);
 +
 +      for (i = 0; i < argc; i++) {
 +              if (!strcmp(argv[i], "tag")) {
 +                      char *tag;
 +                      i++;
 +                      if (i >= argc)
 +                              die(_("You need to specify a tag name."));
 +
 +                      tag = xstrfmt("refs/tags/%s:refs/tags/%s",
 +                                    argv[i], argv[i]);
 +                      refspec_append(&rs, tag);
 +                      free(tag);
 +              } else {
 +                      refspec_append(&rs, argv[i]);
                }
        }
  
  
        sigchain_push_common(unlock_pack_on_signal);
        atexit(unlock_pack);
 -      refspec = parse_fetch_refspec(ref_nr, refs);
 -      exit_code = do_fetch(gtransport, refspec, ref_nr);
 -      free_refspec(ref_nr, refspec);
 +      exit_code = do_fetch(gtransport, &rs);
 +      refspec_clear(&rs);
        transport_disconnect(gtransport);
        gtransport = NULL;
        return exit_code;
diff --combined builtin/grep.c
index 69f0743619f3134df44c94912dfd1e1c43f5fdc5,850bcffd9930f9341fc0e8f0f55c1e5fbad8f593..ee753a403eba0e9bc25b40a1efd200cafdf31e19
@@@ -488,8 -488,7 +488,8 @@@ static int grep_cache(struct grep_opt *
                strbuf_addstr(&name, repo->submodule_prefix);
        }
  
 -      repo_read_index(repo);
 +      if (repo_read_index(repo) < 0)
 +              die("index file corrupt");
  
        for (nr = 0; nr < repo->index->cache_nr; nr++) {
                const struct cache_entry *ce = repo->index->cache[nr];
@@@ -886,9 -885,9 +886,9 @@@ int cmd_grep(int argc, const char **arg
                           N_("indicate hit with exit status without output")),
                OPT_BOOL(0, "all-match", &opt.all_match,
                        N_("show only matches from files that match all patterns")),
-               { OPTION_SET_INT, 0, "debug", &opt.debug, NULL,
-                 N_("show parse tree for grep expression"),
-                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1 },
+               OPT_SET_INT_F(0, "debug", &opt.debug,
+                             N_("show parse tree for grep expression"),
+                             1, PARSE_OPT_HIDDEN),
                OPT_GROUP(""),
                { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
                        N_("pager"), N_("show matching files in the pager"),
diff --combined builtin/ls-files.c
index 967b2b3380d9a1eb0ccea9a742c8abfb4004602b,40d9138c467181f0164415dcf02ef22ee6b60910..88bb2019ad7a52a13373d4c88b127915b219e4a5
@@@ -166,7 -166,7 +166,7 @@@ static void show_killed_files(const str
                                 */
                                pos = index_name_pos(istate, ent->name, ent->len);
                                if (0 <= pos)
 -                                      die("BUG: killed-file %.*s not found",
 +                                      BUG("killed-file %.*s not found",
                                                ent->len, ent->name);
                                pos = -pos - 1;
                                while (pos < istate->cache_nr &&
@@@ -556,9 -556,9 +556,9 @@@ int cmd_ls_files(int argc, const char *
                { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
                        N_("add the standard git exclusions"),
                        PARSE_OPT_NOARG, option_parse_exclude_standard },
-               { OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
-                       N_("make the output relative to the project top directory"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
+               OPT_SET_INT_F(0, "full-name", &prefix_len,
+                             N_("make the output relative to the project top directory"),
+                             0, PARSE_OPT_NONEG),
                OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
                        N_("recurse through submodules")),
                OPT_BOOL(0, "error-unmatch", &error_unmatch,
diff --combined builtin/merge.c
index 6d7bbe8c9f34827c97f23e9beaffb19708db016c,4be71dd81bbad34d618cb22c382da4766d5214b9..b00d6f4821e7dc4067997bf515702edcfa413501
@@@ -14,7 -14,6 +14,7 @@@
  #include "run-command.h"
  #include "diff.h"
  #include "refs.h"
 +#include "refspec.h"
  #include "commit.h"
  #include "diffcore.h"
  #include "revision.h"
@@@ -35,7 -34,6 +35,7 @@@
  #include "string-list.h"
  #include "packfile.h"
  #include "tag.h"
 +#include "alias.h"
  
  #define DEFAULT_TWOHEAD (1<<0)
  #define DEFAULT_OCTOPUS (1<<1)
@@@ -215,9 -213,9 +215,9 @@@ static struct option builtin_merge_opti
        OPT_BOOL('e', "edit", &option_edit,
                N_("edit message before committing")),
        OPT_SET_INT(0, "ff", &fast_forward, N_("allow fast-forward (default)"), FF_ALLOW),
-       { OPTION_SET_INT, 0, "ff-only", &fast_forward, NULL,
-               N_("abort if fast-forward is not possible"),
-               PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, FF_ONLY },
+       OPT_SET_INT_F(0, "ff-only", &fast_forward,
+                     N_("abort if fast-forward is not possible"),
+                     FF_ONLY, PARSE_OPT_NONEG),
        OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
        OPT_BOOL(0, "verify-signatures", &verify_signatures,
                N_("verify that the named commit has a valid GPG signature")),
@@@ -282,7 -280,7 +282,7 @@@ out
        return rc;
  }
  
 -static void read_empty(unsigned const char *sha1, int verbose)
 +static void read_empty(const struct object_id *oid, int verbose)
  {
        int i = 0;
        const char *args[7];
                args[i++] = "-v";
        args[i++] = "-m";
        args[i++] = "-u";
 -      args[i++] = EMPTY_TREE_SHA1_HEX;
 -      args[i++] = sha1_to_hex(sha1);
 +      args[i++] = empty_tree_oid_hex();
 +      args[i++] = oid_to_hex(oid);
        args[i] = NULL;
  
        if (run_command_v_opt(args, RUN_GIT_CMD))
                die(_("read-tree failed"));
  }
  
 -static void reset_hard(unsigned const char *sha1, int verbose)
 +static void reset_hard(const struct object_id *oid, int verbose)
  {
        int i = 0;
        const char *args[6];
                args[i++] = "-v";
        args[i++] = "--reset";
        args[i++] = "-u";
 -      args[i++] = sha1_to_hex(sha1);
 +      args[i++] = oid_to_hex(oid);
        args[i] = NULL;
  
        if (run_command_v_opt(args, RUN_GIT_CMD))
@@@ -326,7 -324,7 +326,7 @@@ static void restore_state(const struct 
        if (is_null_oid(stash))
                return;
  
 -      reset_hard(head->hash, 1);
 +      reset_hard(head, 1);
  
        args[2] = oid_to_hex(stash);
  
@@@ -649,7 -647,7 +649,7 @@@ static int try_merge_strategy(const cha
                              struct commit_list *remoteheads,
                              struct commit *head)
  {
 -      static struct lock_file lock;
 +      struct lock_file lock = LOCK_INIT;
        const char *head_arg = "HEAD";
  
        hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
@@@ -807,7 -805,7 +807,7 @@@ static int merge_trivial(struct commit 
  {
        struct object_id result_tree, result_commit;
        struct commit_list *parents, **pptr = &parents;
 -      static struct lock_file lock;
 +      struct lock_file lock = LOCK_INIT;
  
        hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
        refresh_cache(REFRESH_QUIET);
@@@ -1299,7 -1297,7 +1299,7 @@@ int cmd_merge(int argc, const char **ar
                if (remoteheads->next)
                        die(_("Can merge only exactly one commit into empty head"));
                remote_head_oid = &remoteheads->item->object.oid;
 -              read_empty(remote_head_oid->hash, 0);
 +              read_empty(remote_head_oid, 0);
                update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0,
                           UPDATE_REFS_DIE_ON_ERR);
                goto done;
diff --combined builtin/notes.c
index da279cdd3493781fc022cdd1bfe964d9ace17716,4d34994c34a68a67b8964a428cd7066c1d180d25..6981e2d906f43b06cac5bd11cb0d627571be09d5
@@@ -461,7 -461,7 +461,7 @@@ static int add(int argc, const char **a
        if (d.buf.len || allow_empty) {
                write_note_data(&d, &new_note);
                if (add_note(t, &object, &new_note, combine_notes_overwrite))
 -                      die("BUG: combine_notes_overwrite failed");
 +                      BUG("combine_notes_overwrite failed");
                commit_notes(t, "Notes added by 'git notes add'");
        } else {
                fprintf(stderr, _("Removing note for object %s\n"),
@@@ -544,7 -544,7 +544,7 @@@ static int copy(int argc, const char **
        }
  
        if (add_note(t, &object, from_note, combine_notes_overwrite))
 -              die("BUG: combine_notes_overwrite failed");
 +              BUG("combine_notes_overwrite failed");
        commit_notes(t, "Notes added by 'git notes copy'");
  out:
        free_notes(t);
@@@ -621,7 -621,7 +621,7 @@@ static int append_edit(int argc, const 
        if (d.buf.len || allow_empty) {
                write_note_data(&d, &new_note);
                if (add_note(t, &object, &new_note, combine_notes_overwrite))
 -                      die("BUG: combine_notes_overwrite failed");
 +                      BUG("combine_notes_overwrite failed");
                logmsg = xstrfmt("Notes added by 'git notes %s'", argv[0]);
        } else {
                fprintf(stderr, _("Removing note for object %s\n"),
@@@ -778,13 -778,13 +778,13 @@@ static int merge(int argc, const char *
                           N_("resolve notes conflicts using the given strategy "
                              "(manual/ours/theirs/union/cat_sort_uniq)")),
                OPT_GROUP(N_("Committing unmerged notes")),
-               { OPTION_SET_INT, 0, "commit", &do_commit, NULL,
-                       N_("finalize notes merge by committing unmerged notes"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
+               OPT_SET_INT_F(0, "commit", &do_commit,
+                             N_("finalize notes merge by committing unmerged notes"),
+                             1, PARSE_OPT_NONEG),
                OPT_GROUP(N_("Aborting notes merge resolution")),
-               { OPTION_SET_INT, 0, "abort", &do_abort, NULL,
-                       N_("abort notes merge"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
+               OPT_SET_INT_F(0, "abort", &do_abort,
+                             N_("abort notes merge"),
+                             1, PARSE_OPT_NONEG),
                OPT_END()
        };
  
                const char *short_ref = NULL;
  
                if (!skip_prefix(o.local_ref, "refs/notes/", &short_ref))
 -                      die("BUG: local ref %s is outside of refs/notes/",
 +                      BUG("local ref %s is outside of refs/notes/",
                            o.local_ref);
  
                strbuf_addf(&merge_key, "notes.%s.mergeStrategy", short_ref);
diff --combined builtin/pack-objects.c
index e78f3f52203f369d63c6af6eefb7e21f48c83318,bd6ac48968dc6b58dbdb70cf9a733985a12d0c03..71056d8294d7f4bcfdcbc9bb292a5d17faf49252
@@@ -279,7 -279,6 +279,7 @@@ static unsigned long write_no_reuse_obj
        enum object_type type;
        void *buf;
        struct git_istream *st = NULL;
 +      const unsigned hashsz = the_hash_algo->rawsz;
  
        if (!usable_delta) {
                if (oe_type(entry) == OBJ_BLOB &&
                dheader[pos] = ofs & 127;
                while (ofs >>= 7)
                        dheader[--pos] = 128 | (--ofs & 127);
 -              if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) {
 +              if (limit && hdrlen + sizeof(dheader) - pos + datalen + hashsz >= limit) {
                        if (st)
                                close_istream(st);
                        free(buf);
        } else if (type == OBJ_REF_DELTA) {
                /*
                 * Deltas with a base reference contain
 -               * an additional 20 bytes for the base sha1.
 +               * additional bytes for the base object ID.
                 */
 -              if (limit && hdrlen + 20 + datalen + 20 >= limit) {
 +              if (limit && hdrlen + hashsz + datalen + hashsz >= limit) {
                        if (st)
                                close_istream(st);
                        free(buf);
                        return 0;
                }
                hashwrite(f, header, hdrlen);
 -              hashwrite(f, DELTA(entry)->idx.oid.hash, 20);
 -              hdrlen += 20;
 +              hashwrite(f, DELTA(entry)->idx.oid.hash, hashsz);
 +              hdrlen += hashsz;
        } else {
 -              if (limit && hdrlen + datalen + 20 >= limit) {
 +              if (limit && hdrlen + datalen + hashsz >= limit) {
                        if (st)
                                close_istream(st);
                        free(buf);
@@@ -392,7 -391,6 +392,7 @@@ static off_t write_reuse_object(struct 
        unsigned char header[MAX_PACK_OBJECT_HEADER],
                      dheader[MAX_PACK_OBJECT_HEADER];
        unsigned hdrlen;
 +      const unsigned hashsz = the_hash_algo->rawsz;
        unsigned long entry_size = SIZE(entry);
  
        if (DELTA(entry))
                dheader[pos] = ofs & 127;
                while (ofs >>= 7)
                        dheader[--pos] = 128 | (--ofs & 127);
 -              if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) {
 +              if (limit && hdrlen + sizeof(dheader) - pos + datalen + hashsz >= limit) {
                        unuse_pack(&w_curs);
                        return 0;
                }
                hdrlen += sizeof(dheader) - pos;
                reused_delta++;
        } else if (type == OBJ_REF_DELTA) {
 -              if (limit && hdrlen + 20 + datalen + 20 >= limit) {
 +              if (limit && hdrlen + hashsz + datalen + hashsz >= limit) {
                        unuse_pack(&w_curs);
                        return 0;
                }
                hashwrite(f, header, hdrlen);
 -              hashwrite(f, DELTA(entry)->idx.oid.hash, 20);
 -              hdrlen += 20;
 +              hashwrite(f, DELTA(entry)->idx.oid.hash, hashsz);
 +              hdrlen += hashsz;
                reused_delta++;
        } else {
 -              if (limit && hdrlen + datalen + 20 >= limit) {
 +              if (limit && hdrlen + datalen + hashsz >= limit) {
                        unuse_pack(&w_curs);
                        return 0;
                }
@@@ -771,7 -769,7 +771,7 @@@ static off_t write_reused_pack(struct h
                die_errno("unable to seek in reused packfile");
  
        if (reuse_packfile_offset < 0)
 -              reuse_packfile_offset = reuse_packfile->pack_size - 20;
 +              reuse_packfile_offset = reuse_packfile->pack_size - the_hash_algo->rawsz;
  
        total = to_write = reuse_packfile_offset - sizeof(struct pack_header);
  
@@@ -1035,7 -1033,7 +1035,7 @@@ static int want_object_in_pack(const st
        int want;
        struct list_head *pos;
  
 -      if (!exclude && local && has_loose_object_nonlocal(oid->hash))
 +      if (!exclude && local && has_loose_object_nonlocal(oid))
                return 0;
  
        /*
@@@ -1469,7 -1467,7 +1469,7 @@@ static void check_object(struct object_
                        if (reuse_delta && !entry->preferred_base)
                                base_ref = use_pack(p, &w_curs,
                                                entry->in_pack_offset + used, NULL);
 -                      entry->in_pack_header_size = used + 20;
 +                      entry->in_pack_header_size = used + the_hash_algo->rawsz;
                        break;
                case OBJ_OFS_DELTA:
                        buf = use_pack(p, &w_curs,
@@@ -1670,7 -1668,7 +1670,7 @@@ static void break_delta_chains(struct o
                 * is a bug.
                 */
                if (cur->dfs_state != DFS_NONE)
 -                      die("BUG: confusing delta dfs state in first pass: %d",
 +                      BUG("confusing delta dfs state in first pass: %d",
                            cur->dfs_state);
  
                /*
                if (cur->dfs_state == DFS_DONE)
                        break;
                else if (cur->dfs_state != DFS_ACTIVE)
 -                      die("BUG: confusing delta dfs state in second pass: %d",
 +                      BUG("confusing delta dfs state in second pass: %d",
                            cur->dfs_state);
  
                /*
@@@ -1951,7 -1949,7 +1951,7 @@@ static int try_delta(struct unpacked *t
        /* Now some size filtering heuristics. */
        trg_size = SIZE(trg_entry);
        if (!DELTA(trg_entry)) {
 -              max_size = trg_size/2 - 20;
 +              max_size = trg_size/2 - the_hash_algo->rawsz;
                ref_depth = 1;
        } else {
                max_size = DELTA_SIZE(trg_entry);
@@@ -3134,18 -3132,18 +3134,18 @@@ int cmd_pack_objects(int argc, const ch
                         N_("do not create an empty pack output")),
                OPT_BOOL(0, "revs", &use_internal_rev_list,
                         N_("read revision arguments from standard input")),
-               { OPTION_SET_INT, 0, "unpacked", &rev_list_unpacked, NULL,
-                 N_("limit the objects to those that are not yet packed"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
-               { OPTION_SET_INT, 0, "all", &rev_list_all, NULL,
-                 N_("include objects reachable from any reference"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
-               { OPTION_SET_INT, 0, "reflog", &rev_list_reflog, NULL,
-                 N_("include objects referred by reflog entries"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
-               { OPTION_SET_INT, 0, "indexed-objects", &rev_list_index, NULL,
-                 N_("include objects referred to by the index"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
+               OPT_SET_INT_F(0, "unpacked", &rev_list_unpacked,
+                             N_("limit the objects to those that are not yet packed"),
+                             1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "all", &rev_list_all,
+                             N_("include objects reachable from any reference"),
+                             1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "reflog", &rev_list_reflog,
+                             N_("include objects referred by reflog entries"),
+                             1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "indexed-objects", &rev_list_index,
+                             N_("include objects referred to by the index"),
+                             1, PARSE_OPT_NONEG),
                OPT_BOOL(0, "stdout", &pack_to_stdout,
                         N_("output pack to stdout")),
                OPT_BOOL(0, "include-tag", &include_tag,