Merge branch 'bg/merge-ff-only'
authorJunio C Hamano <gitster@pobox.com>
Tue, 10 Nov 2009 20:32:59 +0000 (12:32 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 10 Nov 2009 20:32:59 +0000 (12:32 -0800)
* bg/merge-ff-only:
Teach 'git merge' and 'git pull' the option --ff-only

1  2 
Documentation/merge-options.txt
builtin-merge.c
index 48d04a5d8833a2c83f1dc754c798688b194de5b9,27a9a8489c9c28cbb5f67281937c246b738f6d82..fec33943058ea3e139aff0b898ef55a677d4067e
@@@ -1,42 -1,43 +1,42 @@@
 --q::
 ---quiet::
 -      Operate quietly.
 -
 --v::
 ---verbose::
 -      Be verbose.
 -
 ---stat::
 -      Show a diffstat at the end of the merge. The diffstat is also
 -      controlled by the configuration option merge.stat.
 -
 --n::
 ---no-stat::
 -      Do not show a diffstat at the end of the merge.
 +--commit::
 +--no-commit::
 +      Perform the merge and commit the result. This option can
 +      be used to override --no-commit.
 ++
 +With --no-commit perform the merge but pretend the merge
 +failed and do not autocommit, to give the user a chance to
 +inspect and further tweak the merge result before committing.
  
 ---summary::
 ---no-summary::
 -      Synonyms to --stat and --no-stat; these are deprecated and will be
 -      removed in the future.
 +--ff::
 +--no-ff::
 +      Do not generate a merge commit if the merge resolved as
 +      a fast-forward, only update the branch pointer. This is
 +      the default behavior of git-merge.
 ++
 +With --no-ff Generate a merge commit even if the merge
 +resolved as a fast-forward.
  
  --log::
 +--no-log::
        In addition to branch names, populate the log message with
        one-line descriptions from the actual commits that are being
        merged.
 ++
 +With --no-log do not list one-line descriptions from the
 +actual commits being merged.
  
 ---no-log::
 -      Do not list one-line descriptions from the actual commits being
 -      merged.
 -
 ---no-commit::
 -      Perform the merge but pretend the merge failed and do
 -      not autocommit, to give the user a chance to inspect and
 -      further tweak the merge result before committing.
  
 ---commit::
 -      Perform the merge and commit the result. This option can
 -      be used to override --no-commit.
 +--stat::
 +-n::
 +--no-stat::
 +      Show a diffstat at the end of the merge. The diffstat is also
 +      controlled by the configuration option merge.stat.
 ++
 +With -n or --no-stat do not show a diffstat at the end of the
 +merge.
  
  --squash::
 +--no-squash::
        Produce the working tree and index state as if a real
        merge happened (except for the merge information),
        but do not actually make a commit or
        commit.  This allows you to create a single commit on
        top of the current branch whose effect is the same as
        merging another branch (or more in case of an octopus).
 -
 ---no-squash::
 -      Perform the merge and commit the result. This option can
 -      be used to override --squash.
 -
 ---no-ff::
 -      Generate a merge commit even if the merge resolved as a
 -      fast-forward.
 -
 ---ff::
 -      Do not generate a merge commit if the merge resolved as
 -      a fast-forward, only update the branch pointer. This is
 -      the default behavior of git-merge.
 ++
 +With --no-squash perform the merge and commit the result. This
 +option can be used to override --squash.
  
+ --ff-only::
+       Refuse to merge and exit with a non-zero status unless the
+       current `HEAD` is already up-to-date or the merge can be
+       resolved as a fast-forward.
  -s <strategy>::
  --strategy=<strategy>::
        Use the given merge strategy; can be supplied more than
        If there is no `-s` option, a built-in list of strategies
        is used instead ('git-merge-recursive' when merging a single
        head, 'git-merge-octopus' otherwise).
 +
 +--summary::
 +--no-summary::
 +      Synonyms to --stat and --no-stat; these are deprecated and will be
 +      removed in the future.
 +
 +-q::
 +--quiet::
 +      Operate quietly.
 +
 +-v::
 +--verbose::
 +      Be verbose.
diff --combined builtin-merge.c
index c69a3051f38eb70f148015471d0c2df1df8db33b,5e8c4b5e4bf6c8c1ca1774544b747aa0c9d72e4b..1ff7b15803fef8791c5c47209ba6f983d59f3065
@@@ -43,6 -43,7 +43,7 @@@ static const char * const builtin_merge
  
  static int show_diffstat = 1, option_log, squash;
  static int option_commit = 1, allow_fast_forward = 1;
+ static int fast_forward_only;
  static int allow_trivial = 1, have_message;
  static struct strbuf merge_msg;
  static struct commit_list *remoteheads;
@@@ -167,6 -168,8 +168,8 @@@ static struct option builtin_merge_opti
                "perform a commit if the merge succeeds (default)"),
        OPT_BOOLEAN(0, "ff", &allow_fast_forward,
                "allow fast forward (default)"),
+       OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
+               "abort if fast forward is not possible"),
        OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
                "merge strategy to use", option_parse_strategy),
        OPT_CALLBACK('m', "message", &merge_msg, "message",
@@@ -264,7 -267,6 +267,7 @@@ static void squash_message(void
        struct strbuf out = STRBUF_INIT;
        struct commit_list *j;
        int fd;
 +      struct pretty_print_context ctx = {0};
  
        printf("Squash commit -- not updating HEAD\n");
        fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
        if (prepare_revision_walk(&rev))
                die("revision walk setup failed");
  
 +      ctx.abbrev = rev.abbrev;
 +      ctx.date_mode = rev.date_mode;
 +
        strbuf_addstr(&out, "Squashed commit of the following:\n");
        while ((commit = get_revision(&rev)) != NULL) {
                strbuf_addch(&out, '\n');
                strbuf_addf(&out, "commit %s\n",
                        sha1_to_hex(commit->object.sha1));
 -              pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
 -                      NULL, NULL, rev.date_mode, 0);
 +              pretty_print_commit(rev.commit_format, commit, &out, &ctx);
        }
        if (write(fd, out.buf, out.len) < 0)
                die_errno("Writing SQUASH_MSG");
@@@ -877,6 -877,9 +880,9 @@@ int cmd_merge(int argc, const char **ar
                option_commit = 0;
        }
  
+       if (!allow_fast_forward && fast_forward_only)
+               die("You cannot combine --no-ff with --ff-only.");
        if (!argc)
                usage_with_options(builtin_merge_usage,
                        builtin_merge_options);
                 * only one common.
                 */
                refresh_cache(REFRESH_QUIET);
-               if (allow_trivial) {
+               if (allow_trivial && !fast_forward_only) {
                        /* See if it is really trivial. */
                        git_committer_info(IDENT_ERROR_ON_NO_NAME);
                        printf("Trying really trivial in-index merge...\n");
                }
        }
  
+       if (fast_forward_only)
+               die("Not possible to fast forward, aborting.");
        /* We are going to make a new commit. */
        git_committer_info(IDENT_ERROR_ON_NO_NAME);