git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 03/14] pull: pass git-merge's options to git-merge

From
Paul Tan <pyokagan@gmail.com>
Date
May 18, 2015, 15:06 UTC
Message-ID
<1431961571-20370-4-git-send-email-pyokagan@gmail.com>
In-Reply-To
<1431961571-20370-1-git-send-email-pyokagan@gmail.com>

Specify git-merge's options in the option list, and pass any specified options to git-merge.

These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
  '--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
  option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
  and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
  --no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
  of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
  try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
  -X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
  2014-02-10)

While most options can be implemented through the parse_opt_passthru() callback, --strategy and --strategy-option are implemented by introducing argv_push_strategies() and argv_push_strategy_opts() as they can be specified multiple times.

Also allow --log to take a value <n>, thus making the failing test '--log=1 limits shortlog length' pass.

Signed-off-by: Paul Tan <pyokagan@gmail.com>
---
 builtin/pull.c               | 94 ++++++++++++++++++++++++++++++++++++++++++++
 t/t4013-diff-various.sh      |  3 --
 t/t5150-request-pull.sh      |  2 +-
 t/t5524-pull-msg.sh          |  2 +-
 t/t5572-pull-submodule.sh    |  4 --
 t/t6029-merge-subtree.sh     |  6 +--
 t/t6037-merge-ours-theirs.sh |  2 +-
 7 files changed, 100 insertions(+), 13 deletions(-)
diff --git a/builtin/pull.c b/builtin/pull.c
index a4d9c92..573e4f6 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -44,6 +44,18 @@ static const char * const pull_usage[] = {
 static int opt_verbosity;
 static char *opt_progress;
 
+/* Options passed to git-merge */
+static char *opt_diffstat;
+static char *opt_log;
+static char *opt_squash;
+static char *opt_commit;
+static char *opt_edit;
+static char *opt_ff;
+static char *opt_verify_signatures;
+static struct string_list opt_strategies = STRING_LIST_INIT_NODUP;
+static struct string_list opt_strategy_opts = STRING_LIST_INIT_NODUP;
+static char *opt_gpg_sign;
+
 static struct option pull_options[] = {
 	/* Shared options */
 	OPT__VERBOSITY(&opt_verbosity),
@@ -51,6 +63,47 @@ static struct option pull_options[] = {
 	  N_("force progress reporting"),
 	  PARSE_OPT_NOARG, parse_opt_passthru},
 
+	/* Options passed to git-merge */
+	OPT_GROUP(N_("Options related to merging")),
+	{ OPTION_CALLBACK, 'n', NULL, &opt_diffstat, NULL,
+	  N_("do not show a diffstat at the end of the merge"),
+	  PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_passthru, (intptr_t) "no-stat" },
+	{ OPTION_CALLBACK, 0, "stat", &opt_diffstat, NULL,
+	  N_("show a diffstat at the end of the merge"),
+	  PARSE_OPT_NOARG, parse_opt_passthru, (intptr_t) "stat" },
+	{ OPTION_CALLBACK, 0, "summary", &opt_diffstat, NULL,
+	  N_("(synonym to --stat)"),
+	  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, parse_opt_passthru, (intptr_t) "stat" },
+	{ OPTION_CALLBACK, 0, "log", &opt_log, N_("n"),
+	  N_("add (at most <n>) entries from shortlog to merge commit message"),
+	  PARSE_OPT_OPTARG, parse_opt_passthru, (intptr_t) "log" },
+	{ OPTION_CALLBACK, 0, "squash", &opt_squash, NULL,
+	  N_("create a single commit instead of doing a merge"),
+	  PARSE_OPT_NOARG, parse_opt_passthru, (intptr_t) "squash" },
+	{ OPTION_CALLBACK, 0, "commit", &opt_commit, NULL,
+	  N_("perform a commit if the merge succeeds (default)"),
+	  PARSE_OPT_NOARG, parse_opt_passthru, (intptr_t) "commit" },
+	{ OPTION_CALLBACK, 0, "edit", &opt_edit, NULL,
+	  N_("edit message before committing"),
+	  PARSE_OPT_NOARG, parse_opt_passthru, (intptr_t) "edit" },
+	{ OPTION_CALLBACK, 0, "ff", &opt_ff, NULL,
+	  N_("allow fast-forward"),
+	  PARSE_OPT_NOARG, parse_opt_passthru, (intptr_t) "ff" },
+	{ OPTION_CALLBACK, 0, "ff-only", &opt_ff, NULL,
+	  N_("abort if fast-forward is not possible"),
+	  PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_passthru, (intptr_t) "ff-only" },
+	{ OPTION_CALLBACK, 0, "verify-signatures", &opt_verify_signatures, NULL,
+	  N_("verify that the named commit has a valid GPG signature"),
+	  PARSE_OPT_NOARG, parse_opt_passthru, (intptr_t) "verify-signatures" },
+	OPT_STRING_LIST('s', "strategy", &opt_strategies, N_("strategy"),
+			N_("merge strategy to use")),
+	OPT_STRING_LIST('X', "strategy-option", &opt_strategy_opts,
+			N_("option=value"),
+			N_("option for selected merge strategy")),
+	{ OPTION_CALLBACK, 'S', "gpg-sign", &opt_gpg_sign, N_("key-id"),
+	  N_("GPG sign commit"),
+	  PARSE_OPT_OPTARG, parse_opt_passthru, (intptr_t) "gpg-sign" },
+
 	OPT_END()
 };
 
@@ -69,6 +122,27 @@ static void argv_push_verbosity(struct argv_array *arr)
 }
 
 /**
+ * Pushes opt_strategies as "-s <strategy>" flags into arr.
+ */
+static void argv_push_strategies(struct argv_array *arr)
+{
+	struct string_list_item *item;
+
+	for_each_string_list_item(item, &opt_strategies)
+		argv_array_pushl(arr, "-s", item->string, NULL);
+}
+
+/**
+ * Pushes opt_strategy_opts as "-X <option>" flags into arr.
+ */
+static void argv_push_strategy_opts(struct argv_array *arr)
+{
+	struct string_list_item *item;
+	for_each_string_list_item(item, &opt_strategy_opts)
+		argv_array_pushl(arr, "-X", item->string, NULL);
+}
+
+/**
  * Parses argv into [<repo> [<refspecs>...]], returning their values in `repo`
  * as a string and `refspecs` as a null-terminated array of strings. If `repo`
  * is not provided in argv, it is set to NULL.
@@ -123,6 +197,26 @@ static int run_merge(void)
 	if (opt_progress)
 		argv_array_push(&args, opt_progress);
 
+	/* Options passed to git-merge */
+	if (opt_diffstat)
+		argv_array_push(&args, opt_diffstat);
+	if (opt_log)
+		argv_array_push(&args, opt_log);
+	if (opt_squash)
+		argv_array_push(&args, opt_squash);
+	if (opt_commit)
+		argv_array_push(&args, opt_commit);
+	if (opt_edit)
+		argv_array_push(&args, opt_edit);
+	if (opt_ff)
+		argv_array_push(&args, opt_ff);
+	if (opt_verify_signatures)
+		argv_array_push(&args, opt_verify_signatures);
+	argv_push_strategies(&args);
+	argv_push_strategy_opts(&args);
+	if (opt_gpg_sign)
+		argv_array_push(&args, opt_gpg_sign);
+
 	argv_array_push(&args, "FETCH_HEAD");
 	ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
 	argv_array_clear(&args);
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index a11e48b..6ec6072 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -7,9 +7,6 @@ test_description='Various diff formatting options'
 
 . ./test-lib.sh
 
-skip_all='setup for this test suite requires git pull -s'
-test_done
-
 LF='
 '
 
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index f5ea605..82c33b8 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -132,7 +132,7 @@ test_expect_success 'pull request when forgot to push' '
 
 '
 
-test_expect_failure 'pull request after push' '
+test_expect_success 'pull request after push' '
 
 	rm -fr downstream.git &&
 	git init --bare downstream.git &&
diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh
index 1ba8054..eebb8c9 100755
--- a/t/t5524-pull-msg.sh
+++ b/t/t5524-pull-msg.sh
@@ -25,7 +25,7 @@ test_expect_success setup '
 	git commit -m "do not clobber $dollar signs"
 '
 
-test_expect_failure pull '
+test_expect_success pull '
 (
 	cd cloned &&
 	git pull --log &&
diff --git a/t/t5572-pull-submodule.sh b/t/t5572-pull-submodule.sh
index 408c886..accfa5c 100755
--- a/t/t5572-pull-submodule.sh
+++ b/t/t5572-pull-submodule.sh
@@ -5,10 +5,6 @@ test_description='pull can handle submodules'
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-submodule-update.sh
 
-KNOWN_FAILURE_STASH_DOES_IGNORE_SUBMODULE_CHANGES=1
-KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
-KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1
-
 reset_branch_to_HEAD () {
 	git branch -D "$1" &&
 	git checkout -b "$1" HEAD &&
diff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh
index 54af64e..73fc240 100755
--- a/t/t6029-merge-subtree.sh
+++ b/t/t6029-merge-subtree.sh
@@ -61,7 +61,7 @@ test_expect_success 'initial merge' '
 	test_cmp expected actual
 '
 
-test_expect_failure 'merge update' '
+test_expect_success 'merge update' '
 	cd ../git-gui &&
 	echo git-gui2 > git-gui.sh &&
 	o3=$(git hash-object git-gui.sh) &&
@@ -95,7 +95,7 @@ test_expect_success 'initial ambiguous subtree' '
 	test_cmp expected actual
 '
 
-test_expect_failure 'merge using explicit' '
+test_expect_success 'merge using explicit' '
 	cd ../git &&
 	git reset --hard master2 &&
 	git pull -Xsubtree=git-gui gui master2 &&
@@ -108,7 +108,7 @@ test_expect_failure 'merge using explicit' '
 	test_cmp expected actual
 '
 
-test_expect_failure 'merge2 using explicit' '
+test_expect_success 'merge2 using explicit' '
 	cd ../git &&
 	git reset --hard master2 &&
 	git pull -Xsubtree=git-gui2 gui master2 &&
diff --git a/t/t6037-merge-ours-theirs.sh b/t/t6037-merge-ours-theirs.sh
index 876e23b..3889eca 100755
--- a/t/t6037-merge-ours-theirs.sh
+++ b/t/t6037-merge-ours-theirs.sh
@@ -65,7 +65,7 @@ test_expect_success 'binary file with -Xours/-Xtheirs' '
 	git diff --exit-code master HEAD -- file
 '
 
-test_expect_failure 'pull passes -X to underlying merge' '
+test_expect_success 'pull passes -X to underlying merge' '
 	git reset --hard master && git pull -s recursive -Xours . side &&
 	git reset --hard master && git pull -s recursive -X ours . side &&
 	git reset --hard master && git pull -s recursive -Xtheirs . side &&
-- 
2.1.4
Previous: Paul TanNext: Paul Tan
Message 9 of 43 in “Make git-pull a builtin”
  1. 00/14 Make git-pull a builtinPaul Tan, May 18, 2015
  2. 01/14 pull: implement fetch + mergePaul Tan, May 18, 2015
  3. Johannes SchindelinMay 18, 2015
  4. 02/14 pull: pass verbosity, --progress flags to fetch and mergePaul Tan, May 18, 2015
  5. Johannes SchindelinMay 18, 2015
  6. Paul TanMay 21, 2015
  7. Johannes SchindelinMay 21, 2015
  8. Paul TanMay 22, 2015
  9. 03/14 pull: pass git-merge's options to git-mergePaul Tan, May 18, 2015
  10. 04/14 pull: pass git-fetch's options to git-fetchPaul Tan, May 18, 2015
  11. 05/14 pull: error on no merge candidatesPaul Tan, May 18, 2015
  12. Johannes SchindelinMay 18, 2015
  13. 06/14 pull: support pull.ff configPaul Tan, May 18, 2015
  14. Johannes SchindelinMay 18, 2015
  15. Paul TanMay 21, 2015
  16. 07/14 pull: check if in unresolved merge statePaul Tan, May 18, 2015
  17. Johannes SchindelinMay 18, 2015
  18. 08/14 pull: fast-forward working tree if head is updatedPaul Tan, May 18, 2015
  19. Johannes SchindelinMay 18, 2015
  20. 09/14 pull: implement pulling into an unborn branchPaul Tan, May 18, 2015
  21. 10/14 pull: set reflog messagePaul Tan, May 18, 2015
  22. Johannes SchindelinMay 18, 2015
  23. Junio C HamanoMay 18, 2015
  24. Paul TanMay 21, 2015
  25. 11/14 pull: teach git pull about --rebasePaul Tan, May 18, 2015
  26. Stefan BellerMay 18, 2015
  27. Johannes SchindelinMay 19, 2015
  28. Paul TanMay 31, 2015
  29. Paul TanJun 2, 2015
  30. 12/14 pull: configure --rebase via branch.<name>.rebase or pull.rebasePaul Tan, May 18, 2015
  31. Stefan BellerMay 18, 2015
  32. 13/14 pull --rebase: exit early when the working directory is dirtyPaul Tan, May 18, 2015
  33. 14/14 pull --rebase: error on no merge candidate casesPaul Tan, May 18, 2015
  34. Stefan BellerMay 19, 2015
  35. Johannes SchindelinMay 19, 2015
  36. Junio C HamanoMay 19, 2015
  37. Paul TanMay 22, 2015
  38. Johannes SchindelinMay 22, 2015
  39. Stefan BellerMay 22, 2015
  40. Junio C HamanoMay 18, 2015
  41. Paul TanMay 30, 2015
  42. Paul TanMay 30, 2015
  43. Johannes SchindelinMay 18, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.