Note that an alias with the same name as a built-in format
        will be silently ignored.
 
+pull.ff::
+       By default, Git does not create an extra merge commit when merging
+       a commit that is a descendant of the current commit. Instead, the
+       tip of the current branch is fast-forwarded. When set to `false`,
+       this variable tells Git to create an extra merge commit in such
+       a case (equivalent to giving the `--no-ff` option from the command
+       line). When set to `only`, only such fast-forward merges are
+       allowed (equivalent to giving the `--ff-only` option from the
+       command line).
+
 pull.rebase::
        When true, rebase branches on top of the fetched branch, instead
        of merging the default branch from the default remote when "git
 
 then
        rebase=$(bool_or_string_config pull.rebase)
 fi
+
+# Setup default fast-forward options via `pull.ff`
+pull_ff=$(git config pull.ff)
+case "$pull_ff" in
+false)
+       no_ff=--no-ff
+       break
+       ;;
+only)
+       ff_only=--ff-only
+       break
+       ;;
+esac
+
+
 dry_run=
 while :
 do
 
        test -f c2.c
 '
 
+test_expect_success 'fast-forward pull succeeds with "true" in pull.ff' '
+       git reset --hard c0 &&
+       test_config pull.ff true &&
+       git pull . c1 &&
+       test "$(git rev-parse HEAD)" = "$(git rev-parse c1)"
+'
+
+test_expect_success 'fast-forward pull creates merge with "false" in pull.ff' '
+       git reset --hard c0 &&
+       test_config pull.ff false &&
+       git pull . c1 &&
+       test "$(git rev-parse HEAD^1)" = "$(git rev-parse c0)" &&
+       test "$(git rev-parse HEAD^2)" = "$(git rev-parse c1)"
+'
+
+test_expect_success 'pull prevents non-fast-forward with "only" in pull.ff' '
+       git reset --hard c1 &&
+       test_config pull.ff only &&
+       test_must_fail git pull . c3
+'
+
 test_expect_success 'merge c1 with c2 (ours in pull.twohead)' '
        git reset --hard c1 &&
        git config pull.twohead ours &&