From: Junio C Hamano Date: Sun, 10 Sep 2017 08:08:22 +0000 (+0900) Subject: Merge branch 'ma/up-to-date' X-Git-Tag: v2.15.0-rc0~107 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/8e36002adda45a35c6fc4daf81913c3d2102cb59?ds=inline;hp=-c Merge branch 'ma/up-to-date' 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 --- 8e36002adda45a35c6fc4daf81913c3d2102cb59 diff --combined Documentation/git-merge.txt index 615e6bacde,53366a1700..4df6431c34 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@@ -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[]:: --gpg-sign[=]:: 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: diff --combined Documentation/githooks.txt index 623ed1a138,99abfc73a7..1bb4f92d4d --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@@ -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 7df3fe3927,a0789c798f..3672e38974 --- a/builtin/merge.c +++ b/builtin/merge.c @@@ -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; @@@ -929,6 -920,8 +929,6 @@@ 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) @@@ -936,13 -929,6 +936,13 @@@ 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"; @@@ -954,7 -940,7 +954,7 @@@ 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 @@@ -1359,7 -1345,7 +1359,7 @@@ * 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 && @@@ -1442,7 -1428,7 +1442,7 @@@ } } 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 6c390d6c22,5b2162c89d..7d19d37951 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@@ -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 @@@ -100,7 -100,7 +100,7 @@@ 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 744c685576,a4cb76f0f5..b04d2f2131 --- a/notes-merge.c +++ b/notes-merge.c @@@ -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 43c317e4e9,0f1992fbf9..4113090069 --- a/remote.c +++ 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 @@@ -151,7 -147,7 +151,7 @@@ 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 be78cc4fad,16ca6081fa..8f17fd9da8 --- a/t/t6040-tracking-info.sh +++ b/t/t6040-tracking-info.sh @@@ -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 68d34259c6,a2fe4e052d..87e8c69597 --- a/unpack-trees.c +++ b/unpack-trees.c @@@ -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) @@@ -349,10 -365,6 +349,10 @@@ 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]; @@@ -366,9 -378,8 +366,9 @@@ 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]; @@@ -383,7 -394,6 +383,7 @@@ } } } + 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); } }