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

Re: [PATCH 0/3] Reject non-ff pulls by default

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 5, 2013, 23:38 UTC
Message-ID
<xmqq7geug7oy.fsf@gitster.dls.corp.google.com>
In-Reply-To
<xmqqr4d4jird.fsf@gitster.dls.corp.google.com>
Junio C Hamano <gitster@pobox.com> writes:
Show 24 quoted lines
> I can imagine users might want to say "when I am on these small
> number of branches, I want to merge (or rebase), but when I am on
> other, majority of my branches, because they are private, unfinished
> and unpublished work, please stop me from accidentally messing their
> histories with changes from upstream or anywhere else for that
> matter".  If that is the issue you are trying to raise, because
> there is no
>
> 	[pull]
>         	rebase = fail
> 	[branch "master"]
>         	rebase = yes
>
> to force "git pull" to fail by default on any branch while allowing
> it to rebase (or merge, for that matter) only on a few selected
> branches, we fall a bit short.
>
> Which can be solved by adding the above "fail" option, and then
> renaming them to "pull.integrate" and "branch.<name>.integrate" to
> clarify what these variables are about (it is no longer "do you
> rebase or not---if you choose not to rebase, by definition you are
> going to merge", as there is a third choice to "fail"), while
> retaining "pull.rebase" and "branch.<name>.rebase" as a deprecated
> synonym.

The first step of such an enhancement may look like this patch. It introduces "pull.integrate" and "branch.<name>.integrate" that will eventually deprecate "*.rebase", but at this step only supports values "rebase" and "merge" (i.e. no "fail" yet).

The steps after this change would be to
 * Enhance addition to t5520 made by 949e0d8e (pull: require choice
   between rebase/merge on non-fast-forward pull, 2013-06-27) to
   make sure that setting pull.integrate and branch.<name>.integrate
   will squelch the safety added by that patch;
 * Teach "branch.c" to set "branch.<name>.integrate" either instead
   of or in addition to "branch.<name>.rebase", and adjust tests
   that expect to see "branch.<name>.rebase" to expect to see that
   "branch.<name>.integrate" is set to "rebase";
 * Add "fail" to the set of valid values for "*.integrate", and teach
   "git pull" honor it; and
 * Update builtin/remote.c to show cases where branch.<name>.integrate
   is set to "fail" in some different way.

I do not plan to do these follow-up steps myself soonish (hint, hint).

 builtin/remote.c | 12 ++++++++++--
 git-pull.sh      | 60 +++++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/builtin/remote.c b/builtin/remote.c
index 5e54d36..d3b6d0b5 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -274,7 +274,7 @@ static int config_read_branches(const char *key, const char *value, void *cb)
 		char *name;
 		struct string_list_item *item;
 		struct branch_info *info;
-		enum { REMOTE, MERGE, REBASE } type;
+		enum { REMOTE, MERGE, REBASE, INTEGRATE } type;
 
 		key += 7;
 		if (!postfixcmp(key, ".remote")) {
@@ -286,6 +286,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)
 		} else if (!postfixcmp(key, ".rebase")) {
 			name = xstrndup(key, strlen(key) - 7);
 			type = REBASE;
+		} else if (!postfixcmp(key, ".integrate")) {
+			name = xstrndup(key, strlen(key) - 10);
+			type = INTEGRATE;
 		} else
 			return 0;
 
@@ -309,8 +312,13 @@ static int config_read_branches(const char *key, const char *value, void *cb)
 				space = strchr(value, ' ');
 			}
 			string_list_append(&info->merge, xstrdup(value));
-		} else
+		} else if (type == REBASE) {
 			info->rebase = git_config_bool(orig_key, value);
+		} else if (type == INTEGRATE) {
+			if (!value)
+				return config_error_nonbool(orig_key);
+			info->rebase = !strcmp(value, "rebase");
+		}
 	}
 	return 0;
 }
diff --git a/git-pull.sh b/git-pull.sh
index 88c198f..5c557b7 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -45,16 +45,34 @@ merge_args= edit=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short="${curr_branch#refs/heads/}"
 
-# See if we are configured to rebase by default.
-# The value $rebase is, throughout the main part of the code:
+# See what we are configured to do by default.
+# The value $integration is, throughout the main part of the code:
 #    (empty) - the user did not have any preference
-#    true    - the user told us to integrate by rebasing
-#    false   - the user told us to integrate by merging
-rebase=$(git config --bool branch.$curr_branch_short.rebase)
-if test -z "$rebase"
-then
-	rebase=$(git config --bool pull.rebase)
-fi
+#    rebase  - the user told us to integrate by rebasing
+#    merge   - the user told us to integrate by merging
+
+integration=
+
+set_integration () {
+	integration=$(git config branch.$curr_branch_short.integrate)
+	test -n "$integration" && return
+
+	case "$(git config --bool branch.$curr_branch_short.rebase)" in
+	true)	integration=rebase ;;
+	false)	integration=merge ;;
+	esac
+	test -n "$integration" && return
+
+	integration=$(git config pull.integrate)
+	test -n "$integration" && return
+
+	case "$(git config --bool pull.rebase)" in
+	true)	integration=rebase ;;
+	false)	integration=merge ;;
+	esac
+}
+
+set_integration
 
 dry_run=
 while :
@@ -119,11 +137,11 @@ do
 		merge_args="$merge_args$xx "
 		;;
 	-r|--r|--re|--reb|--reba|--rebas|--rebase)
-		rebase=true
+		integration=rebase
 		;;
 	--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase|\
 	-m|--m|--me|--mer|--merg|--merge)
-		rebase=false
+		integration=merge
 		;;
 	--recurse-submodules)
 		recurse_submodules=--recurse-submodules
@@ -166,7 +184,7 @@ error_on_no_merge_candidates () {
 		esac
 	done
 
-	if test true = "$rebase"
+	if test "$integration" = rebase
 	then
 		op_type=rebase
 		op_prep=against
@@ -180,7 +198,8 @@ error_on_no_merge_candidates () {
 	remote=$(git config "branch.$curr_branch.remote")
 
 	if [ $# -gt 1 ]; then
-		if [ "$rebase" = true ]; then
+		if test "$integration" = rebase
+		then
 			printf "There is no candidate for rebasing against "
 		else
 			printf "There are no candidates for merging "
@@ -203,7 +222,8 @@ error_on_no_merge_candidates () {
 	exit 1
 }
 
-test true = "$rebase" && {
+if test "$integration" = rebase
+then
 	if ! git rev-parse -q --verify HEAD >/dev/null
 	then
 		# On an unborn branch
@@ -227,7 +247,7 @@ test true = "$rebase" && {
 			break
 		fi
 	done
-}
+fi
 
 orig_head=$(git rev-parse -q --verify HEAD)
 git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
@@ -269,7 +289,7 @@ case "$merge_head" in
 	then
 		die "$(gettext "Cannot merge multiple branches into empty head")"
 	fi
-	if test true = "$rebase"
+	if test "$integration" = rebase
 	then
 		die "$(gettext "Cannot rebase onto multiple branches")"
 	fi
@@ -279,7 +299,7 @@ case "$merge_head" in
 	# trigger this check when we will say "fast-forward" or "already
 	# up-to-date".
 	merge_head=${merge_head% }
-	if test -z "$rebase$no_ff$ff_only${squash#--no-squash}" &&
+	if test -z "$integration$no_ff$ff_only${squash#--no-squash}" &&
 		test -n "$orig_head" &&
 		test $# = 0 &&
 		! git merge-base --is-ancestor "$orig_head" "$merge_head" &&
@@ -311,7 +331,7 @@ then
 	exit
 fi
 
-if test true = "$rebase"
+if test "$integration" = rebase
 then
 	o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)
 	if test "$oldremoteref" = "$o"
@@ -321,8 +341,8 @@ then
 fi
 
 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
-case "$rebase" in
-true)
+case "$integration" in
+rebase)
 	eval="git-rebase $diffstat $strategy_args $merge_args $verbosity"
 	eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
 	;;
Previous: Junio C HamanoNext: Felipe Contreras
Message 76 of 84 in “Reject non-ff pulls by default”
  1. 0/3 Reject non-ff pulls by defaultFelipe Contreras, Aug 31, 2013
  2. 1/3 merge: simplify ff-only optionFelipe Contreras, Aug 31, 2013
  3. 2/3 t: replace pulls with mergesFelipe Contreras, Aug 31, 2013
  4. 3/3 pull: reject non-ff pulls by defaultFelipe Contreras, Aug 31, 2013
  5. Junio C HamanoSep 3, 2013
  6. Felipe ContrerasSep 3, 2013
  7. Junio C HamanoSep 3, 2013
  8. Felipe ContrerasSep 3, 2013
  9. John KeepingSep 4, 2013
  10. Jeff KingSep 4, 2013
  11. John KeepingSep 4, 2013
  12. Felipe ContrerasSep 8, 2013
  13. Jeff KingSep 8, 2013
  14. Felipe ContrerasSep 8, 2013
  15. Jeff KingSep 8, 2013
  16. Felipe ContrerasSep 8, 2013
  17. Jeff KingSep 8, 2013
  18. Felipe ContrerasSep 8, 2013
  19. Jeff KingSep 8, 2013
  20. Felipe ContrerasSep 8, 2013
  21. Jeff KingSep 8, 2013
  22. Felipe ContrerasSep 8, 2013
  23. Jeff KingSep 9, 2013
  24. Felipe ContrerasSep 9, 2013
  25. John KeepingSep 8, 2013
  26. Jeff KingSep 9, 2013
  27. brian m. carlsonSep 8, 2013
  28. Felipe ContrerasSep 8, 2013
  29. brian m. carlsonSep 9, 2013
  30. Felipe ContrerasSep 9, 2013
  31. Felipe ContrerasSep 9, 2013
  32. brian m. carlsonSep 9, 2013
  33. Matthieu MoySep 9, 2013
  34. Junio C HamanoSep 9, 2013
  35. Jeff KingSep 9, 2013
  36. John KeepingSep 9, 2013
  37. Jeff KingSep 9, 2013
  38. John KeepingSep 9, 2013
  39. Richard HansenSep 9, 2013
  40. Matthieu MoySep 9, 2013
  41. Jeff KingSep 9, 2013
  42. Philip OakleySep 9, 2013
  43. Felipe ContrerasSep 9, 2013
  44. John KeepingSep 10, 2013
  45. Matthieu MoySep 9, 2013
  46. Junio C HamanoSep 10, 2013
  47. Felipe ContrerasSep 9, 2013
  48. Matthieu MoySep 10, 2013
  49. Felipe ContrerasSep 11, 2013
  50. Matthieu MoySep 11, 2013
  51. Felipe ContrerasSep 13, 2013
  52. Junio C HamanoSep 4, 2013
  53. Junio C HamanoSep 4, 2013
  54. Philip OakleySep 4, 2013
  55. Junio C HamanoSep 4, 2013
  56. John KeepingSep 5, 2013
  57. Junio C HamanoSep 5, 2013
  58. John KeepingSep 5, 2013
  59. Jonathan NiederSep 6, 2013
  60. Junio C HamanoSep 6, 2013
  61. John KeepingSep 7, 2013
  62. Felipe ContrerasSep 8, 2013
  63. Felipe ContrerasSep 8, 2013
  64. Philip OakleySep 8, 2013
  65. Felipe ContrerasSep 8, 2013
  66. Philip OakleySep 8, 2013
  67. Felipe ContrerasSep 8, 2013
  68. Philip OakleySep 8, 2013
  69. Philip OakleySep 8, 2013
  70. John SzakmeisterSep 5, 2013
  71. John KeepingSep 5, 2013
  72. John SzakmeisterSep 5, 2013
  73. Richard HansenSep 5, 2013
  74. Philip OakleySep 5, 2013
  75. Junio C HamanoSep 5, 2013
  76. Junio C HamanoSep 5, 2013
  77. Felipe ContrerasSep 8, 2013
  78. Richard HansenSep 8, 2013
  79. Junio C HamanoSep 8, 2013
  80. Richard HansenSep 8, 2013
  81. Philip OakleySep 8, 2013
  82. Felipe ContrerasSep 8, 2013
  83. Ramkumar RamachandraSep 8, 2013
  84. Greg TroxelSep 5, 2013

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.