Merge branch 'ma/up-to-date' into next
authorJunio C Hamano <gitster@pobox.com>
Fri, 25 Aug 2017 21:41:11 +0000 (14:41 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 25 Aug 2017 21:41:11 +0000 (14:41 -0700)
Message and doc updates.

* ma/up-to-date:
treewide: correct several "up-to-date" to "up to date"
Documentation/user-manual: update outdated example output

1  2 
Documentation/git-merge.txt
Documentation/githooks.txt
builtin/merge.c
git-merge-octopus.sh
notes-merge.c
remote.c
t/t6040-tracking-info.sh
unpack-trees.c
index 615e6bacde7355e3125268bc969d0fee2a06392e,53366a17005e95824bb948255c681f84ab15e9dd..4df6431c341a466f2cb9fef094607751b58c008d
@@@ -64,14 -64,6 +64,14 @@@ OPTION
  -------
  include::merge-options.txt[]
  
 +--signoff::
 +      Add Signed-off-by line by the committer at the end of the commit
 +      log message.  The meaning of a signoff depends on the project,
 +      but it typically certifies that committer has
 +      the rights to submit this work under the same license and
 +      agrees to a Developer Certificate of Origin
 +      (see http://developercertificate.org/ for more information).
 +
  -S[<keyid>]::
  --gpg-sign[=<keyid>]::
        GPG-sign the resulting merge commit. The `keyid` argument is
@@@ -141,7 -133,7 +141,7 @@@ exception is when the changed index ent
  would result from the merge already.)
  
  If all named commits are already ancestors of `HEAD`, 'git merge'
- will exit early with the message "Already up-to-date."
+ will exit early with the message "Already up to date."
  
  FAST-FORWARD MERGE
  ------------------
@@@ -288,10 -280,7 +288,10 @@@ After seeing a conflict, you can do tw
  
   * Resolve the conflicts.  Git will mark the conflicts in
     the working tree.  Edit the files into shape and
 -   'git add' them to the index.  Use 'git commit' to seal the deal.
 +   'git add' them to the index.  Use 'git commit' or
 +   'git merge --continue' to seal the deal. The latter command
 +   checks whether there is a (interrupted) merge in progress
 +   before calling 'git commit'.
  
  You can work through the conflict with a number of tools:
  
index 623ed1a13829188971531aa62c6e109e9d29ec44,99abfc73a7822b00fdcd6bd8788c082dc01871d4..1bb4f92d4d317e16929767066a61c123fee0f280
@@@ -121,8 -121,8 +121,8 @@@ it is not suppressed by the `--no-verif
  means a failure of the hook and aborts the commit.  It should not
  be used as replacement for pre-commit hook.
  
 -The sample `prepare-commit-msg` hook that comes with Git comments
 -out the `Conflicts:` part of a merge's commit message.
 +The sample `prepare-commit-msg` hook that comes with Git removes the
 +help message found in the commented portion of the commit template.
  
  commit-msg
  ~~~~~~~~~~
@@@ -369,7 -369,7 +369,7 @@@ them
  
  When enabled, the default 'post-update' hook runs
  'git update-server-info' to keep the information used by dumb
- transports (e.g., HTTP) up-to-date.  If you are publishing
+ transports (e.g., HTTP) up to date.  If you are publishing
  a Git repository that is accessible via HTTP, you should
  probably enable this hook.
  
diff --combined builtin/merge.c
index 7df3fe3927ef8a1c65f7baad7d957602436315cd,a0789c798fd68f1dcd79a5925ceb25a965228e55..3672e38974f094831c305d509b9582c146f94236
@@@ -32,7 -32,6 +32,7 @@@
  #include "gpg-interface.h"
  #include "sequencer.h"
  #include "string-list.h"
 +#include "packfile.h"
  
  #define DEFAULT_TWOHEAD (1<<0)
  #define DEFAULT_OCTOPUS (1<<1)
@@@ -71,7 -70,6 +71,7 @@@ static int continue_current_merge
  static int allow_unrelated_histories;
  static int show_progress = -1;
  static int default_to_upstream = 1;
 +static int signoff;
  static const char *sign_commit;
  
  static struct strategy all_strategy[] = {
@@@ -235,7 -233,6 +235,7 @@@ static struct option builtin_merge_opti
        { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
          N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
        OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
 +      OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")),
        OPT_END()
  };
  
@@@ -540,7 -537,7 +540,7 @@@ static void parse_branch_merge_options(
                die(_("Bad branch.%s.mergeoptions string: %s"), branch,
                    split_cmdline_strerror(argc));
        REALLOC_ARRAY(argv, argc + 2);
 -      memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
 +      MOVE_ARRAY(argv + 1, argv, argc + 1);
        argc++;
        argv[0] = "branch.*.mergeoptions";
        parse_options(argc, argv, NULL, builtin_merge_options,
@@@ -569,7 -566,7 +569,7 @@@ static int git_merge_config(const char 
        else if (!strcmp(k, "merge.renormalize"))
                option_renormalize = git_config_bool(k, v);
        else if (!strcmp(k, "merge.ff")) {
 -              int boolval = git_config_maybe_bool(k, v);
 +              int boolval = git_parse_maybe_bool(v);
                if (0 <= boolval) {
                        fast_forward = boolval ? FF_ALLOW : FF_NO;
                } else if (v && !strcmp(v, "only")) {
@@@ -759,19 -756,13 +759,19 @@@ N_("Please enter a commit message to ex
     "Lines starting with '%c' will be ignored, and an empty message aborts\n"
     "the commit.\n");
  
 +static void write_merge_heads(struct commit_list *);
  static void prepare_to_commit(struct commit_list *remoteheads)
  {
        struct strbuf msg = STRBUF_INIT;
        strbuf_addbuf(&msg, &merge_msg);
        strbuf_addch(&msg, '\n');
 +      if (squash)
 +              BUG("the control must not reach here under --squash");
        if (0 < option_edit)
                strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
 +      if (signoff)
 +              append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0);
 +      write_merge_heads(remoteheads);
        write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
        if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
                            git_path_merge_msg(), "merge", NULL))
@@@ -913,7 -904,7 +913,7 @@@ static int setup_with_upstream(const ch
        return i;
  }
  
 -static void write_merge_state(struct commit_list *remoteheads)
 +static void write_merge_heads(struct commit_list *remoteheads)
  {
        struct commit_list *j;
        struct strbuf buf = STRBUF_INIT;
                strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
        }
        write_file_buf(git_path_merge_head(), buf.buf, buf.len);
 -      strbuf_addch(&merge_msg, '\n');
 -      write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
  
        strbuf_reset(&buf);
        if (fast_forward == FF_NO)
        write_file_buf(git_path_merge_mode(), buf.buf, buf.len);
  }
  
 +static void write_merge_state(struct commit_list *remoteheads)
 +{
 +      write_merge_heads(remoteheads);
 +      strbuf_addch(&merge_msg, '\n');
 +      write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
 +}
 +
  static int default_edit_option(void)
  {
        static const char name[] = "GIT_MERGE_AUTOEDIT";
                return 0;
  
        if (e) {
 -              int v = git_config_maybe_bool(name, e);
 +              int v = git_parse_maybe_bool(e);
                if (v < 0)
                        die(_("Bad value '%s' in environment '%s'"), e, name);
                return v;
@@@ -1131,8 -1117,8 +1131,8 @@@ int cmd_merge(int argc, const char **ar
         * current branch.
         */
        branch = branch_to_free = resolve_refdup("HEAD", 0, head_oid.hash, NULL);
 -      if (branch && starts_with(branch, "refs/heads/"))
 -              branch += 11;
 +      if (branch)
 +              skip_prefix(branch, "refs/heads/", &branch);
        if (!branch || is_null_oid(&head_oid))
                head_commit = NULL;
        else
                 * If head can reach all the merge then we are up to date.
                 * but first the most common case of merging one remote.
                 */
-               finish_up_to_date(_("Already up-to-date."));
+               finish_up_to_date(_("Already up to date."));
                goto done;
        } else if (fast_forward != FF_NO && !remoteheads->next &&
                        !common->next &&
                        }
                }
                if (up_to_date) {
-                       finish_up_to_date(_("Already up-to-date. Yeeah!"));
+                       finish_up_to_date(_("Already up to date. Yeeah!"));
                        goto done;
                }
        }
diff --combined git-merge-octopus.sh
index 6c390d6c229d7ef8cca8ae01d33b42b57e29c3b3,5b2162c89d7b1bb110e08d273172256abb0829a4..7d19d379512b52168d7c604002e872fc3eef9fd7
@@@ -74,7 -74,7 +74,7 @@@ d
  
        case "$LF$common$LF" in
        *"$LF$SHA1$LF"*)
-               eval_gettextln "Already up-to-date with \$pretty_name"
+               eval_gettextln "Already up to date with \$pretty_name"
                continue
                ;;
        esac
        if test $? -ne 0
        then
                gettextln "Simple merge did not work, trying automatic merge."
 -              git-merge-index -o git-merge-one-file -a ||
 +              git merge-index -o git-merge-one-file -a ||
                OCTOPUS_FAILURE=1
                next=$(git write-tree 2>/dev/null)
        fi
diff --combined notes-merge.c
index 744c68557649ff1b1fbc007cd2bd2951fc09ab93,a4cb76f0f54b544dfc1ca30b66d9750c9e223ff1..b04d2f213116a6413d564107a6e12e3f7317accb
@@@ -99,7 -99,8 +99,7 @@@ static struct notes_merge_pair *find_no
        else {
                *occupied = 0;
                if (insert_new && i < len) {
 -                      memmove(list + i + 1, list + i,
 -                              (len - i) * sizeof(struct notes_merge_pair));
 +                      MOVE_ARRAY(list + i + 1, list + i, len - i);
                        memset(list + i, 0, sizeof(struct notes_merge_pair));
                }
        }
@@@ -624,7 -625,7 +624,7 @@@ int notes_merge(struct notes_merge_opti
        if (!oidcmp(&remote->object.oid, base_oid)) {
                /* Already merged; result == local commit */
                if (o->verbosity >= 2)
-                       printf("Already up-to-date!\n");
+                       printf("Already up to date!\n");
                oidcpy(result_oid, &local->object.oid);
                goto found_result;
        }
@@@ -709,7 -710,7 +709,7 @@@ int notes_merge_commit(struct notes_mer
                /* write file as blob, and add to partial_tree */
                if (stat(path.buf, &st))
                        die_errno("Failed to stat '%s'", path.buf);
 -              if (index_path(blob_oid.hash, path.buf, &st, HASH_WRITE_OBJECT))
 +              if (index_path(&blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
                        die("Failed to write blob object from '%s'", path.buf);
                if (add_note(partial_tree, &obj_oid, &blob_oid, NULL))
                        die("Failed to add resolved note '%s' to notes tree",
diff --combined remote.c
index 43c317e4e9f6e67aa3e1d0ae245d097bdba664db,0f1992fbf98ff19a79d288c8fead764c6b5d072f..41130900698893f46dd18b817a7e6b6485c735a4
+++ b/remote.c
@@@ -134,14 -134,10 +134,14 @@@ struct remotes_hash_key 
  };
  
  static int remotes_hash_cmp(const void *unused_cmp_data,
 -                          const struct remote *a,
 -                          const struct remote *b,
 -                          const struct remotes_hash_key *key)
 +                          const void *entry,
 +                          const void *entry_or_key,
 +                          const void *keydata)
  {
 +      const struct remote *a = entry;
 +      const struct remote *b = entry_or_key;
 +      const struct remotes_hash_key *key = keydata;
 +
        if (key)
                return strncmp(a->name, key->str, key->len) || a->name[key->len];
        else
  static inline void init_remotes_hash(void)
  {
        if (!remotes_hash.cmpfn)
 -              hashmap_init(&remotes_hash, (hashmap_cmp_fn)remotes_hash_cmp, NULL, 0);
 +              hashmap_init(&remotes_hash, remotes_hash_cmp, NULL, 0);
  }
  
  static struct remote *make_remote(const char *name, int len)
@@@ -1085,7 -1081,7 +1085,7 @@@ static int try_explicit_object_name(con
                return 0;
        }
  
 -      if (get_sha1(name, oid.hash))
 +      if (get_oid(name, &oid))
                return -1;
  
        if (match) {
@@@ -2084,7 -2080,7 +2084,7 @@@ int format_tracking_info(struct branch 
                                _("  (use \"git branch --unset-upstream\" to fixup)\n"));
        } else if (!ours && !theirs) {
                strbuf_addf(sb,
-                       _("Your branch is up-to-date with '%s'.\n"),
+                       _("Your branch is up to date with '%s'.\n"),
                        base);
        } else if (!theirs) {
                strbuf_addf(sb,
@@@ -2301,8 -2297,8 +2301,8 @@@ static int parse_push_cas_option(struc
        if (!*colon)
                entry->use_tracking = 1;
        else if (!colon[1])
 -              hashclr(entry->expect);
 -      else if (get_sha1(colon + 1, entry->expect))
 +              oidclr(&entry->expect);
 +      else if (get_oid(colon + 1, &entry->expect))
                return error("cannot parse expected object name '%s'", colon + 1);
        return 0;
  }
@@@ -2349,7 -2345,7 +2349,7 @@@ static void apply_cas(struct push_cas_o
                        continue;
                ref->expect_old_sha1 = 1;
                if (!entry->use_tracking)
 -                      hashcpy(ref->old_oid_expect.hash, cas->entry[i].expect);
 +                      oidcpy(&ref->old_oid_expect, &entry->expect);
                else if (remote_tracking(remote, ref->name, &ref->old_oid_expect))
                        oidclr(&ref->old_oid_expect);
                return;
diff --combined t/t6040-tracking-info.sh
index be78cc4fad205d7f1da7cc864de3c6e04be51882,16ca6081faac3bd58b25a5f6ff5252b6d74a78c7..8f17fd9da8ef6b54ae0a97500f2154b1c9d968b3
@@@ -100,7 -100,7 +100,7 @@@ test_expect_success 'checkout (up-to-da
        (
                cd test && git checkout b6
        ) >actual &&
-       test_i18ngrep "Your branch is up-to-date with .origin/master" actual
+       test_i18ngrep "Your branch is up to date with .origin/master" actual
  '
  
  test_expect_success 'status (diverged from upstream)' '
@@@ -130,7 -130,7 +130,7 @@@ test_expect_success 'status (up-to-dat
                # reports nothing to commit
                test_must_fail git commit --dry-run
        ) >actual &&
-       test_i18ngrep "Your branch is up-to-date with .origin/master" actual
+       test_i18ngrep "Your branch is up to date with .origin/master" actual
  '
  
  cat >expect <<\EOF
@@@ -188,29 -188,35 +188,29 @@@ test_expect_success 'fail to track anno
        test_must_fail git checkout heavytrack
  '
  
 -test_expect_success 'setup tracking with branch --set-upstream on existing branch' '
 +test_expect_success '--set-upstream-to does not change branch' '
        git branch from-master master &&
 -      test_must_fail git config branch.from-master.merge > actual &&
 -      git branch --set-upstream from-master master &&
 -      git config branch.from-master.merge > actual &&
 -      grep -q "^refs/heads/master$" actual
 -'
 -
 -test_expect_success '--set-upstream does not change branch' '
 +      git branch --set-upstream-to master from-master &&
        git branch from-master2 master &&
        test_must_fail git config branch.from-master2.merge > actual &&
        git rev-list from-master2 &&
        git update-ref refs/heads/from-master2 from-master2^ &&
        git rev-parse from-master2 >expect2 &&
 -      git branch --set-upstream from-master2 master &&
 +      git branch --set-upstream-to master from-master2 &&
        git config branch.from-master.merge > actual &&
        git rev-parse from-master2 >actual2 &&
        grep -q "^refs/heads/master$" actual &&
        cmp expect2 actual2
  '
  
 -test_expect_success '--set-upstream @{-1}' '
 -      git checkout from-master &&
 +test_expect_success '--set-upstream-to @{-1}' '
 +      git checkout follower &&
        git checkout from-master2 &&
        git config branch.from-master2.merge > expect2 &&
 -      git branch --set-upstream @{-1} follower &&
 +      git branch --set-upstream-to @{-1} from-master &&
        git config branch.from-master.merge > actual &&
        git config branch.from-master2.merge > actual2 &&
 -      git branch --set-upstream from-master follower &&
 +      git branch --set-upstream-to follower from-master &&
        git config branch.from-master.merge > expect &&
        test_cmp expect2 actual2 &&
        test_cmp expect actual
diff --combined unpack-trees.c
index 68d34259c6cf6ecb4de29c32621ddbe967b6dbf9,a2fe4e052d60e6a15ab2e8e21ebebf6353059b77..87e8c695971c470657fdd0b9fe29555e14604edd
@@@ -1,6 -1,5 +1,6 @@@
  #define NO_THE_INDEX_COMPATIBILITY_MACROS
  #include "cache.h"
 +#include "repository.h"
  #include "config.h"
  #include "dir.h"
  #include "tree.h"
@@@ -163,7 -162,7 +163,7 @@@ void setup_unpack_trees_porcelain(struc
        msgs[ERROR_BIND_OVERLAP] = _("Entry '%s' overlaps with '%s'.  Cannot bind.");
  
        msgs[ERROR_SPARSE_NOT_UPTODATE_FILE] =
-               _("Cannot update sparse checkout: the following entries are not up-to-date:\n%s");
+               _("Cannot update sparse checkout: the following entries are not up to date:\n%s");
        msgs[ERROR_WOULD_LOSE_ORPHANED_OVERWRITTEN] =
                _("The following working tree files would be overwritten by sparse checkout update:\n%s");
        msgs[ERROR_WOULD_LOSE_ORPHANED_REMOVED] =
@@@ -256,41 -255,47 +256,41 @@@ static int check_submodule_move_head(co
  {
        unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN;
        const struct submodule *sub = submodule_from_ce(ce);
 +
        if (!sub)
                return 0;
  
        if (o->reset)
                flags |= SUBMODULE_MOVE_HEAD_FORCE;
  
 -      switch (sub->update_strategy.type) {
 -      case SM_UPDATE_UNSPECIFIED:
 -      case SM_UPDATE_CHECKOUT:
 -              if (submodule_move_head(ce->name, old_id, new_id, flags))
 -                      return o->gently ? -1 :
 -                              add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
 -              return 0;
 -      case SM_UPDATE_NONE:
 -              return 0;
 -      case SM_UPDATE_REBASE:
 -      case SM_UPDATE_MERGE:
 -      case SM_UPDATE_COMMAND:
 -      default:
 -              warning(_("submodule update strategy not supported for submodule '%s'"), ce->name);
 -              return -1;
 -      }
 +      if (submodule_move_head(ce->name, old_id, new_id, flags))
 +              return o->gently ? -1 :
 +                                 add_rejected_path(o, ERROR_WOULD_LOSE_SUBMODULE, ce->name);
 +      return 0;
  }
  
 -static void reload_gitmodules_file(struct index_state *index,
 -                                 struct checkout *state)
 +/*
 + * Preform the loading of the repository's gitmodules file.  This function is
 + * used by 'check_update()' to perform loading of the gitmodules file in two
 + * differnt situations:
 + * (1) before removing entries from the working tree if the gitmodules file has
 + *     been marked for removal.  This situation is specified by 'state' == NULL.
 + * (2) before checking out entries to the working tree if the gitmodules file
 + *     has been marked for update.  This situation is specified by 'state' != NULL.
 + */
 +static void load_gitmodules_file(struct index_state *index,
 +                               struct checkout *state)
  {
 -      int i;
 -      for (i = 0; i < index->cache_nr; i++) {
 -              struct cache_entry *ce = index->cache[i];
 -              if (ce->ce_flags & CE_UPDATE) {
 -                      int r = strcmp(ce->name, ".gitmodules");
 -                      if (r < 0)
 -                              continue;
 -                      else if (r == 0) {
 -                              submodule_free();
 -                              checkout_entry(ce, state, NULL);
 -                              gitmodules_config();
 -                              git_config(submodule_config, NULL);
 -                      } else
 -                              break;
 +      int pos = index_name_pos(index, GITMODULES_FILE, strlen(GITMODULES_FILE));
 +
 +      if (pos >= 0) {
 +              struct cache_entry *ce = index->cache[pos];
 +              if (!state && ce->ce_flags & CE_WT_REMOVE) {
 +                      repo_read_gitmodules(the_repository);
 +              } else if (state && (ce->ce_flags & CE_UPDATE)) {
 +                      submodule_free();
 +                      checkout_entry(ce, state, NULL);
 +                      repo_read_gitmodules(the_repository);
                }
        }
  }
@@@ -303,9 -308,19 +303,9 @@@ static void unlink_entry(const struct c
  {
        const struct submodule *sub = submodule_from_ce(ce);
        if (sub) {
 -              switch (sub->update_strategy.type) {
 -              case SM_UPDATE_UNSPECIFIED:
 -              case SM_UPDATE_CHECKOUT:
 -              case SM_UPDATE_REBASE:
 -              case SM_UPDATE_MERGE:
 -                      /* state.force is set at the caller. */
 -                      submodule_move_head(ce->name, "HEAD", NULL,
 -                                          SUBMODULE_MOVE_HEAD_FORCE);
 -                      break;
 -              case SM_UPDATE_NONE:
 -              case SM_UPDATE_COMMAND:
 -                      return; /* Do not touch the submodule. */
 -              }
 +              /* state.force is set at the caller. */
 +              submodule_move_head(ce->name, "HEAD", NULL,
 +                                  SUBMODULE_MOVE_HEAD_FORCE);
        }
        if (!check_leading_path(ce->name, ce_namelen(ce)))
                return;
@@@ -328,7 -343,8 +328,7 @@@ static struct progress *get_progress(st
                        total++;
        }
  
 -      return start_progress_delay(_("Checking out files"),
 -                                  total, 50, 1);
 +      return start_delayed_progress(_("Checking out files"), total);
  }
  
  static int check_updates(struct unpack_trees_options *o)
  
        if (o->update)
                git_attr_set_direction(GIT_ATTR_CHECKOUT, index);
 +
 +      if (should_update_submodules() && o->update && !o->dry_run)
 +              load_gitmodules_file(index, NULL);
 +
        for (i = 0; i < index->cache_nr; i++) {
                const struct cache_entry *ce = index->cache[i];
  
        remove_scheduled_dirs();
  
        if (should_update_submodules() && o->update && !o->dry_run)
 -              reload_gitmodules_file(index, &state);
 +              load_gitmodules_file(index, &state);
  
 +      enable_delayed_checkout(&state);
        for (i = 0; i < index->cache_nr; i++) {
                struct cache_entry *ce = index->cache[i];
  
                        }
                }
        }
 +      errs |= finish_delayed_checkout(&state);
        stop_progress(&progress);
        if (o->update)
                git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
@@@ -650,10 -660,10 +650,10 @@@ static int traverse_trees_recursive(in
                else if (i > 1 && are_same_oid(&names[i], &names[i - 2]))
                        t[i] = t[i - 2];
                else {
 -                      const unsigned char *sha1 = NULL;
 +                      const struct object_id *oid = NULL;
                        if (dirmask & 1)
 -                              sha1 = names[i].oid->hash;
 -                      buf[nr_buf++] = fill_tree_descriptor(t+i, sha1);
 +                              oid = names[i].oid;
 +                      buf[nr_buf++] = fill_tree_descriptor(t + i, oid);
                }
        }