Merge branch 'mg/merge-ff-config'
authorJunio C Hamano <gitster@pobox.com>
Mon, 16 May 2011 23:46:23 +0000 (16:46 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 May 2011 23:46:23 +0000 (16:46 -0700)
* mg/merge-ff-config:
tests: check git does not barf on merge.ff values for future versions of git
merge: introduce merge.ff configuration variable

Conflicts:
t/t7600-merge.sh

1  2 
builtin/merge.c
t/t7600-merge.sh
diff --combined builtin/merge.c
index 9661c8f425b82866552d435413928c60d59cb9ad,65c79630f0ee2a36d0caccb8e12f7f38993dfc79..7eebb71491047b2df6231df500e5fc28db1881b4
@@@ -550,6 -550,15 +550,15 @@@ static int git_merge_config(const char 
                if (is_bool && shortlog_len)
                        shortlog_len = DEFAULT_MERGE_LOG_LEN;
                return 0;
+       } else if (!strcmp(k, "merge.ff")) {
+               int boolval = git_config_maybe_bool(k, v);
+               if (0 <= boolval) {
+                       allow_fast_forward = boolval;
+               } else if (v && !strcmp(v, "only")) {
+                       allow_fast_forward = 1;
+                       fast_forward_only = 1;
+               } /* do not barf on values from future versions of git */
+               return 0;
        } else if (!strcmp(k, "merge.defaulttoupstream")) {
                default_to_upstream = git_config_bool(k, v);
                return 0;
@@@ -831,7 -840,7 +840,7 @@@ static void read_merge_msg(void
  {
        strbuf_reset(&merge_msg);
        if (strbuf_read_file(&merge_msg, git_path("MERGE_MSG"), 0) < 0)
 -              die_errno("Could not read from '%s'", git_path("MERGE_MSG"));
 +              die_errno(_("Could not read from '%s'"), git_path("MERGE_MSG"));
  }
  
  static void run_prepare_commit_msg(void)
@@@ -971,16 -980,16 +980,16 @@@ static int setup_with_upstream(const ch
        const char **args;
  
        if (!branch)
 -              die("No current branch.");
 +              die(_("No current branch."));
        if (!branch->remote)
 -              die("No remote for the current branch.");
 +              die(_("No remote for the current branch."));
        if (!branch->merge_nr)
 -              die("No default upstream defined for the current branch.");
 +              die(_("No default upstream defined for the current branch."));
  
        args = xcalloc(branch->merge_nr + 1, sizeof(char *));
        for (i = 0; i < branch->merge_nr; i++) {
                if (!branch->merge[i]->dst)
 -                      die("No remote tracking branch for %s from %s",
 +                      die(_("No remote tracking branch for %s from %s"),
                            branch->merge[i]->src, branch->remote_name);
                args[i] = branch->merge[i]->dst;
        }
@@@ -1054,10 -1063,10 +1063,10 @@@ int cmd_merge(int argc, const char **ar
        }
        if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
                if (advice_resolve_conflict)
 -                      die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 -                          "Please, commit your changes before you can merge.");
 +                      die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 +                          "Please, commit your changes before you can merge."));
                else
 -                      die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).");
 +                      die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."));
        }
        resolve_undo_clear();
  
        if (!allow_fast_forward && fast_forward_only)
                die(_("You cannot combine --no-ff with --ff-only."));
  
 -      if (!argc && !abort_current_merge && default_to_upstream)
 -              argc = setup_with_upstream(&argv);
 -
 +      if (!abort_current_merge) {
 +              if (!argc && default_to_upstream)
 +                      argc = setup_with_upstream(&argv);
 +              else if (argc == 1 && !strcmp(argv[0], "-"))
 +                      argv[0] = "@{-1}";
 +      }
        if (!argc)
                usage_with_options(builtin_merge_usage,
                        builtin_merge_options);
diff --combined t/t7600-merge.sh
index a07caa8eaec1cd148f68d7190880fbe537a14162,8ddaa1d8ee3a025cc32e0d52dfbaa67ef67e6d50..87aac835a1b864eab083b25940892b93af491326
@@@ -28,79 -28,81 +28,80 @@@ Testing basic merge operations/option p
  
  . ./test-lib.sh
  
 -test_expect_success 'set up test data and helpers' '
 -      printf "%s\n" 1 2 3 4 5 6 7 8 9 >file &&
 -      printf "%s\n" "1 X" 2 3 4 5 6 7 8 9 >file.1 &&
 -      printf "%s\n" 1 2 3 4 "5 X" 6 7 8 9 >file.5 &&
 -      printf "%s\n" 1 2 3 4 5 6 7 8 "9 X" >file.9 &&
 -      printf "%s\n" "1 X" 2 3 4 5 6 7 8 9 >result.1 &&
 -      printf "%s\n" "1 X" 2 3 4 "5 X" 6 7 8 9 >result.1-5 &&
 -      printf "%s\n" "1 X" 2 3 4 "5 X" 6 7 8 "9 X" >result.1-5-9 &&
 -      >empty &&
 -
 -      create_merge_msgs() {
 -              echo "Merge commit '\''c2'\''" >msg.1-5 &&
 -              echo "Merge commit '\''c2'\''; commit '\''c3'\''" >msg.1-5-9 &&
 -              {
 -                      echo "Squashed commit of the following:" &&
 -                      echo &&
 -                      git log --no-merges ^HEAD c1
 -              } >squash.1 &&
 -              {
 -                      echo "Squashed commit of the following:" &&
 -                      echo &&
 -                      git log --no-merges ^HEAD c2
 -              } >squash.1-5 &&
 -              {
 -                      echo "Squashed commit of the following:" &&
 -                      echo &&
 -                      git log --no-merges ^HEAD c2 c3
 -              } >squash.1-5-9 &&
 -              echo >msg.nolog &&
 -              {
 -                      echo "* commit '\''c3'\'':" &&
 -                      echo "  commit 3" &&
 -                      echo
 -              } >msg.log
 -      } &&
 -
 -      verify_merge() {
 -              test_cmp "$2" "$1" &&
 -              git update-index --refresh &&
 -              git diff --exit-code &&
 -              if test -n "$3"
 -              then
 -                      git show -s --pretty=format:%s HEAD >msg.act &&
 -                      test_cmp "$3" msg.act
 -              fi
 -      } &&
 -
 -      verify_head() {
 -              echo "$1" >head.expected &&
 -              git rev-parse HEAD >head.actual &&
 -              test_cmp head.expected head.actual
 -      } &&
 -
 -      verify_parents() {
 -              printf "%s\n" "$@" >parents.expected &&
 -              >parents.actual &&
 -              i=1 &&
 -              while test $i -le $#
 -              do
 -                      git rev-parse HEAD^$i >>parents.actual &&
 -                      i=$(expr $i + 1) ||
 -                      return 1
 -              done &&
 -              test_cmp parents.expected parents.actual
 -      } &&
 -
 -      verify_mergeheads() {
 -              printf "%s\n" "$@" >mergehead.expected &&
 -              test_cmp mergehead.expected .git/MERGE_HEAD
 -      } &&
 -
 -      verify_no_mergehead() {
 -              ! test -e .git/MERGE_HEAD
 -      }
 -'
 +printf '%s\n' 1 2 3 4 5 6 7 8 9 >file
 +printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >file.1
 +printf '%s\n' 1 2 3 4 '5 X' 6 7 8 9 >file.5
 +printf '%s\n' 1 2 3 4 5 6 7 8 '9 X' >file.9
 +printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >result.1
 +printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 9 >result.1-5
 +printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
++>empty
 +
 +create_merge_msgs () {
 +      echo "Merge commit 'c2'" >msg.1-5 &&
 +      echo "Merge commit 'c2'; commit 'c3'" >msg.1-5-9 &&
 +      {
 +              echo "Squashed commit of the following:" &&
 +              echo &&
 +              git log --no-merges ^HEAD c1
 +      } >squash.1 &&
 +      {
 +              echo "Squashed commit of the following:" &&
 +              echo &&
 +              git log --no-merges ^HEAD c2
 +      } >squash.1-5 &&
 +      {
 +              echo "Squashed commit of the following:" &&
 +              echo &&
 +              git log --no-merges ^HEAD c2 c3
 +      } >squash.1-5-9 &&
 +      echo >msg.nolog &&
 +      {
 +              echo "* commit 'c3':" &&
 +              echo "  commit 3" &&
 +              echo
 +      } >msg.log
 +}
 +
 +verify_merge () {
 +      test_cmp "$2" "$1" &&
 +      git update-index --refresh &&
 +      git diff --exit-code &&
 +      if test -n "$3"
 +      then
 +              git show -s --pretty=format:%s HEAD >msg.act &&
 +              test_cmp "$3" msg.act
 +      fi
 +}
 +
 +verify_head () {
 +      echo "$1" >head.expected &&
 +      git rev-parse HEAD >head.actual &&
 +      test_cmp head.expected head.actual
 +}
 +
 +verify_parents () {
 +      printf '%s\n' "$@" >parents.expected &&
 +      >parents.actual &&
 +      i=1 &&
 +      while test $i -le $#
 +      do
 +              git rev-parse HEAD^$i >>parents.actual &&
 +              i=$(expr $i + 1) ||
 +              return 1
 +      done &&
 +      test_must_fail git rev-parse --verify "HEAD^$i" &&
 +      test_cmp parents.expected parents.actual
 +}
 +
 +verify_mergeheads () {
 +      printf '%s\n' "$@" >mergehead.expected &&
 +      test_cmp mergehead.expected .git/MERGE_HEAD
 +}
 +
 +verify_no_mergehead () {
 +      ! test -e .git/MERGE_HEAD
 +}
  
  test_expect_success 'setup' '
        git add file &&
@@@ -224,12 -226,28 +225,28 @@@ test_expect_success 'merge c1 with c2 a
  
  test_debug 'git log --graph --decorate --oneline --all'
  
- test_expect_success 'failing merges with --ff-only' '
+ test_expect_success 'merges with --ff-only' '
        git reset --hard c1 &&
        test_tick &&
        test_must_fail git merge --ff-only c2 &&
        test_must_fail git merge --ff-only c3 &&
-       test_must_fail git merge --ff-only c2 c3
+       test_must_fail git merge --ff-only c2 c3 &&
+       git reset --hard c0 &&
+       git merge c3 &&
+       verify_head $c3
+ '
+ test_expect_success 'merges with merge.ff=only' '
+       git reset --hard c1 &&
+       test_tick &&
+       test_when_finished "git config --unset merge.ff" &&
+       git config merge.ff only &&
+       test_must_fail git merge c2 &&
+       test_must_fail git merge c3 &&
+       test_must_fail git merge c2 c3 &&
+       git reset --hard c0 &&
+       git merge c3 &&
+       verify_head $c3
  '
  
  test_expect_success 'merge c0 with c1 (no-commit)' '
@@@ -338,10 -356,11 +355,11 @@@ test_expect_success 'merge c1 with c2 (
  '
  
  test_expect_success 'merge c1 with c2 (log in config gets overridden)' '
-       (
-               git config --remove-section branch.master
-               git config --remove-section merge
-       )
+       test_when_finished "git config --remove-section branch.master" &&
+       test_when_finished "git config --remove-section merge" &&
+       test_might_fail git config --remove-section branch.master &&
+       test_might_fail git config --remove-section merge &&
        git reset --hard c1 &&
        git merge c2 &&
        git show -s --pretty=tformat:%s%n%b >expect &&
@@@ -446,7 -465,41 +464,41 @@@ test_expect_success 'merge c0 with c1 (
  
  test_debug 'git log --graph --decorate --oneline --all'
  
+ test_expect_success 'merge c0 with c1 (merge.ff=false)' '
+       git reset --hard c0 &&
+       git config merge.ff false &&
+       test_tick &&
+       git merge c1 &&
+       git config --remove-section merge &&
+       verify_merge file result.1 &&
+       verify_parents $c0 $c1
+ '
+ test_debug 'git log --graph --decorate --oneline --all'
+ test_expect_success 'combine branch.master.mergeoptions with merge.ff' '
+       git reset --hard c0 &&
+       git config branch.master.mergeoptions --ff &&
+       git config merge.ff false &&
+       test_tick &&
+       git merge c1 &&
+       git config --remove-section "branch.master" &&
+       git config --remove-section "merge" &&
+       verify_merge file result.1 &&
+       verify_parents "$c0"
+ '
+ test_expect_success 'tolerate unknown values for merge.ff' '
+       git reset --hard c0 &&
+       git config merge.ff something-new &&
+       test_tick &&
+       git merge c1 2>message &&
+       git config --remove-section "merge" &&
+       verify_head "$c1" &&
+       test_cmp empty message
+ '
  test_expect_success 'combining --squash and --no-ff is refused' '
+       git reset --hard c0 &&
        test_must_fail git merge --squash --no-ff c1 &&
        test_must_fail git merge --no-ff --squash c1
  '
@@@ -526,10 -579,10 +578,10 @@@ test_expect_success 'merge fast-forwar
  
  test_debug 'git log --graph --decorate --oneline --all'
  
 -test_expect_success C_LOCALE_OUTPUT 'in-index merge' '
 +test_expect_success 'in-index merge' '
        git reset --hard c0 &&
        git merge --no-ff -s resolve c1 >out &&
 -      grep "Wonderful." out &&
 +      test_i18ngrep "Wonderful." out &&
        verify_parents $c0 $c1
  '