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

Re: [PATCH v5 20/20] rebase: rename the two primary rebase backends

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Mar 17, 2020, 02:58 UTC
Message-ID
<20200317025808.GB31380@google.com>
In-Reply-To
<CABPp-BHSAbJzWEsPSTM5Q6MPdmu4VSuOx-=6-MJkHUovg3_1=g@mail.gmail.com>
Hi,
Elijah Newren wrote:
> On Thu, Mar 12, 2020 at 11:46 AM Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 21 quoted lines
>> Sorry for the lack of clarity.  I mean allowing
>>
>>         [rebase]
>>                 backend = am
>>                 backend = apply
>>                 backend = futuristic
>>
>> with behavior
>>
>> - on "git" that understands am but not apply or futuristic, use the am
>>   backend
>> - on "git" that understands apply but not am or futuristic, use the
>>   apply backend
>> - on "git" that understands apply and futuristic, use the futuristic
>>   backend
>>
>> That way, a single config file is usable on all three versions of Git.
>
> Ah, gotcha, that makes sense though we'd need to make the thing
> multi-valued which is a bit late for 2.26.  But we could at least
> extend the logic in that way for 2.27.

Here's a patch implementing that. I'm not convinced it's worth the complexity, mostly because I'm not convinced that rebase is going to have to select between additional new backends in the future. But if you think it will, then I think this would be a reasonable thing to do (maybe even without the documentation part of the patch).

Thoughts?

Thanks, Jonathan

-- >8 --
Subject: rebase: allow specifying unrecognized rebase.backend with a fallback

In 8295ed690bf (rebase: make the backend configurable via config setting, 2020-02-15), Git learned a new rebase.backend setting that can be used to specify which implementation should be used for non-interactive rebases: "am" (now called "apply"), which uses "git am", or "merge", which uses the three-way merge machinery.

Most likely those are the only two backends that rebase will ever need to learn, so this level of configurability would be sufficient. At some point the "apply" backend would be retired, and the setting would be removed altogether.

Suppose, though, that rebase learns another backend --- e.g. "faster". In that case, a user might set configuration to request it:

	[rebase]
		backend = faster

If their configuration is shared between multiple versions of Git (think "home directory on NFS shared between machines"), this would produce errors when read by older versions of Git:

	fatal: Unknown rebase backend: faster

On the other hand, if we ignore unrecognized rebase backend settings, then Git would fail to realize that

	[rebase]
		backend = appply

is a typo, producing a confusing user experience. Let's do something in between: when a rebase backend setting is unrecognized, fall back to the last earlier recognized value, but if no value was recognized, print an error message allowing the user to catch their typo.

Reported-by: Emily Shaffer <emilyshaffer@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Documentation/config/rebase.txt |  5 ++
 builtin/rebase.c                | 52 +++++++++++++++---
 t/t3435-rebase-backend.sh       | 97 +++++++++++++++++++++++++++++++++
 3 files changed, 146 insertions(+), 8 deletions(-)
 create mode 100755 t/t3435-rebase-backend.sh
diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt
index 7f7a07d22f8..c92adbdcc69 100644
--- a/Documentation/config/rebase.txt
+++ b/Documentation/config/rebase.txt
@@ -10,6 +10,11 @@ rebase.backend::
 	'apply' or 'merge'.  In the future, if the merge backend gains
 	all remaining capabilities of the apply backend, this setting
 	may become unused.
++
+If set multiple times, the last value corresponding to a recognized
+backend is used. This is for forward compatibility, as it allows
+specifying a rebase backend that Git does not know about yet along
+with a backend known today as a fallback.
 
 rebase.stat::
 	Whether to show a diffstat of what changed upstream since the last
diff --git a/builtin/rebase.c b/builtin/rebase.c
index ffa467aad52..5b0fab9741f 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -56,10 +56,18 @@ enum empty_type {
 	EMPTY_ASK
 };
 
+enum rebase_backend {
+	BACKEND_UNSPECIFIED = 0,
+	BACKEND_UNRECOGNIZED,
+	BACKEND_APPLY,
+	BACKEND_MERGE,
+};
+
 struct rebase_options {
 	enum rebase_type type;
 	enum empty_type empty;
-	const char *default_backend;
+	enum rebase_backend configured_backend;
+	const char *last_specified_backend;
 	const char *state_dir;
 	struct commit *upstream;
 	const char *upstream_name;
@@ -100,7 +108,6 @@ struct rebase_options {
 #define REBASE_OPTIONS_INIT {			  	\
 		.type = REBASE_UNSPECIFIED,	  	\
 		.empty = EMPTY_UNSPECIFIED,	  	\
-		.default_backend = "merge",	  	\
 		.flags = REBASE_NO_QUIET, 		\
 		.git_am_opts = ARGV_ARRAY_INIT,		\
 		.git_format_patch_opt = STRBUF_INIT	\
@@ -1224,6 +1231,15 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
 	return status ? -1 : 0;
 }
 
+static enum rebase_backend parse_rebase_backend(const char *value)
+{
+	if (!strcmp(value, "apply"))
+		return BACKEND_APPLY;
+	if (!strcmp(value, "merge"))
+		return BACKEND_MERGE;
+	return BACKEND_UNRECOGNIZED;
+}
+
 static int rebase_config(const char *var, const char *value, void *data)
 {
 	struct rebase_options *opts = data;
@@ -1264,7 +1280,18 @@ static int rebase_config(const char *var, const char *value, void *data)
 	}
 
 	if (!strcmp(var, "rebase.backend")) {
-		return git_config_string(&opts->default_backend, var, value);
+		enum rebase_backend val;
+		if (!value)
+			return config_error_nonbool(var);
+		val = parse_rebase_backend(value);
+		if (opts->configured_backend == BACKEND_UNSPECIFIED)
+			opts->configured_backend = val;
+		else if (val == BACKEND_UNRECOGNIZED)
+			; /* Unrecognized rebase backend. Ignore it. */
+		else
+			opts->configured_backend = val;
+		opts->last_specified_backend = value;
+		return 0;
 	}
 
 	return git_default_config(var, value, data);
@@ -1903,14 +1930,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 		}
 	}
 
+	if (options.configured_backend == BACKEND_UNRECOGNIZED)
+		die(_("unknown rebase backend: %s"),
+		    options.last_specified_backend);
+
 	if (options.type == REBASE_UNSPECIFIED) {
-		if (!strcmp(options.default_backend, "merge"))
+		switch (options.configured_backend) {
+		case BACKEND_UNSPECIFIED:
+		case BACKEND_MERGE:
 			imply_merge(&options, "--merge");
-		else if (!strcmp(options.default_backend, "apply"))
+			break;
+		case BACKEND_APPLY:
 			options.type = REBASE_APPLY;
-		else
-			die(_("Unknown rebase backend: %s"),
-			    options.default_backend);
+			break;
+		default:
+			BUG("unexpected backend %d",
+			    (int) options.configured_backend);
+		}
 	}
 
 	switch (options.type) {
diff --git a/t/t3435-rebase-backend.sh b/t/t3435-rebase-backend.sh
new file mode 100755
index 00000000000..8b9ba6f1894
--- /dev/null
+++ b/t/t3435-rebase-backend.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+test_description='rebase.backend tests
+
+Checks of config parsing for the [rebase] backend setting.  We detect
+which backend was used by checking which directory was created to hold
+state.'
+
+. ./test-lib.sh
+
+# usage: test_backend_choice <expectation> <command>
+#
+# Tests that the chosen backend for rebase command <command>
+# is <expectation> ("merge" or "apply").
+test_backend_choice () {
+	expect=$1 &&
+	shift &&
+
+	test_must_fail git "$@" master topic &&
+	case $expect in
+	apply)
+		test_path_is_dir .git/rebase-apply &&
+		test_path_is_missing .git/rebase-merge
+		;;
+	merge)
+		test_path_is_dir .git/rebase-merge &&
+		test_path_is_missing .git/rebase-apply
+		;;
+	*)
+		error "unrecognized expectation $expect"
+	esac
+}
+
+test_expect_success 'setup' '
+	test_commit base &&
+	test_commit sidea conflict.txt myway &&
+	git checkout -b topic base &&
+	test_commit sideb conflict.txt thehighway
+'
+
+test_expect_success '--apply uses apply backend' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice apply rebase --apply
+'
+
+test_expect_success '--merge uses merge backend' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice merge rebase --merge
+'
+
+test_expect_success 'default to merge backend' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice merge rebase
+'
+
+test_expect_success 'config overrides default' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice apply -c rebase.backend=apply rebase
+'
+
+test_expect_success 'option overrides config' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice merge -c rebase.backend=apply rebase --merge
+'
+
+test_expect_success 'last config value wins' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice merge \
+		-c rebase.backend=apply \
+		-c rebase.backend=merge \
+		rebase
+'
+
+test_expect_success 'last config value wins' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice merge \
+		-c rebase.backend=apply \
+		-c rebase.backend=merge \
+		rebase
+'
+
+test_expect_success 'misspelled backend without fallback is diagnosed' '
+	test_must_fail \
+		git -c rebase.backend=appply rebase master topic 2>message &&
+	test_i18ngrep "unknown rebase backend" message &&
+	grep appply message
+'
+
+test_expect_success 'forward compatibility by skipping unrecognized values' '
+	test_when_finished "git rebase --abort" &&
+	test_backend_choice apply \
+		-c rebase.backend=apply \
+		-c rebase.backend=futuristic \
+		rebase
+'
+
+test_done
-- 
2.25.1.481.gfbce0eb801
Previous: Elijah NewrenNext: Elijah Newren
Message 144 of 161 in “rebase: make the default backend configurable”
  1. 00/15 rebase: make the default backend configurableElijah Newren via GitGitGadget, Dec 20, 2019
  2. 02/15 t3406: simplify an already simple testElijah Newren via GitGitGadget, Dec 20, 2019
  3. 03/15 rebase, sequencer: remove the broken GIT_QUIET handlingElijah Newren via GitGitGadget, Dec 20, 2019
  4. Junio C HamanoDec 20, 2019
  5. 01/15 rebase: extend the options for handling of empty commitsElijah Newren via GitGitGadget, Dec 20, 2019
  6. Junio C HamanoDec 20, 2019
  7. Elijah NewrenDec 21, 2019
  8. Elijah NewrenDec 21, 2019
  9. Junio C HamanoDec 21, 2019
  10. 06/15 t3432: make these tests work with either am or merge backendsElijah Newren via GitGitGadget, Dec 20, 2019
  11. Denton LiuDec 22, 2019
  12. Elijah NewrenDec 23, 2019
  13. 04/15 rebase: make sure to pass along the quiet flag to the sequencerElijah Newren via GitGitGadget, Dec 20, 2019
  14. 09/15 rebase: move incompatibility checks between backend options a bit earlierElijah Newren via GitGitGadget, Dec 20, 2019
  15. 07/15 rebase: allow more types of rebases to fast-forwardElijah Newren via GitGitGadget, Dec 20, 2019
  16. 08/15 git-rebase.txt: add more details about behavioral differences of backendsElijah Newren via GitGitGadget, Dec 20, 2019
  17. 13/15 rebase tests: repeat some tests using the merge backend instead of amElijah Newren via GitGitGadget, Dec 20, 2019
  18. 12/15 rebase tests: mark tests specific to the am-backend with --amElijah Newren via GitGitGadget, Dec 20, 2019
  19. 14/15 rebase: make the backend configurable via config settingElijah Newren via GitGitGadget, Dec 20, 2019
  20. 11/15 contrib: change the prompt for am-based rebasesElijah Newren via GitGitGadget, Dec 20, 2019
  21. SZEDER GáborDec 20, 2019
  22. Elijah NewrenDec 21, 2019
  23. 05/15 rebase: fix handling of restrict_revisionElijah Newren via GitGitGadget, Dec 20, 2019
  24. Junio C HamanoDec 20, 2019
  25. 15/15 rebase: change the default backend from "am" to "merge"Elijah Newren via GitGitGadget, Dec 20, 2019
  26. 10/15 rebase: add an --am optionElijah Newren via GitGitGadget, Dec 20, 2019
  27. Alban GruinDec 20, 2019
  28. Elijah NewrenDec 20, 2019
  29. 00/15 rebase: make the default backend configurableElijah Newren via GitGitGadget, Dec 23, 2019
  30. 02/15 t3406: simplify an already simple testElijah Newren via GitGitGadget, Dec 23, 2019
  31. 01/15 rebase: extend the options for handling of empty commitsElijah Newren via GitGitGadget, Dec 23, 2019
  32. 04/15 rebase: make sure to pass along the quiet flag to the sequencerElijah Newren via GitGitGadget, Dec 23, 2019
  33. 03/15 rebase, sequencer: remove the broken GIT_QUIET handlingElijah Newren via GitGitGadget, Dec 23, 2019
  34. 08/15 git-rebase.txt: add more details about behavioral differences of backendsElijah Newren via GitGitGadget, Dec 23, 2019
  35. 05/15 rebase: fix handling of restrict_revisionElijah Newren via GitGitGadget, Dec 23, 2019
  36. 07/15 rebase: allow more types of rebases to fast-forwardElijah Newren via GitGitGadget, Dec 23, 2019
  37. 06/15 t3432: make these tests work with either am or merge backendsElijah Newren via GitGitGadget, Dec 23, 2019
  38. 14/15 rebase: make the backend configurable via config settingElijah Newren via GitGitGadget, Dec 23, 2019
  39. 13/15 rebase tests: repeat some tests using the merge backend instead of amElijah Newren via GitGitGadget, Dec 23, 2019
  40. 12/15 rebase tests: mark tests specific to the am-backend with --amElijah Newren via GitGitGadget, Dec 23, 2019
  41. 15/15 rebase: change the default backend from "am" to "merge"Elijah Newren via GitGitGadget, Dec 23, 2019
  42. 09/15 rebase: move incompatibility checks between backend options a bit earlierElijah Newren via GitGitGadget, Dec 23, 2019
  43. 10/15 rebase: add an --am optionElijah Newren via GitGitGadget, Dec 23, 2019
  44. 11/15 contrib: change the prompt for interactive-based rebasesElijah Newren via GitGitGadget, Dec 23, 2019
  45. Denton LiuDec 23, 2019
  46. 00/15 rebase: make the default backend configurableElijah Newren via GitGitGadget, Dec 24, 2019
  47. 02/15 t3406: simplify an already simple testElijah Newren via GitGitGadget, Dec 24, 2019
  48. 03/15 rebase, sequencer: remove the broken GIT_QUIET handlingElijah Newren via GitGitGadget, Dec 24, 2019
  49. 01/15 rebase: extend the options for handling of empty commitsElijah Newren via GitGitGadget, Dec 24, 2019
  50. Phillip WoodJan 7, 2020
  51. Elijah NewrenJan 7, 2020
  52. Phillip WoodJan 8, 2020
  53. Johannes SchindelinJan 9, 2020
  54. 04/15 rebase: make sure to pass along the quiet flag to the sequencerElijah Newren via GitGitGadget, Dec 24, 2019
  55. 05/15 rebase: fix handling of restrict_revisionElijah Newren via GitGitGadget, Dec 24, 2019
  56. 07/15 rebase: allow more types of rebases to fast-forwardElijah Newren via GitGitGadget, Dec 24, 2019
  57. 06/15 t3432: make these tests work with either am or merge backendsElijah Newren via GitGitGadget, Dec 24, 2019
  58. 08/15 git-rebase.txt: add more details about behavioral differences of backendsElijah Newren via GitGitGadget, Dec 24, 2019
  59. 11/15 git-prompt: change the prompt for interactive-based rebasesElijah Newren via GitGitGadget, Dec 24, 2019
  60. 12/15 rebase tests: mark tests specific to the am-backend with --amElijah Newren via GitGitGadget, Dec 24, 2019
  61. 10/15 rebase: add an --am optionElijah Newren via GitGitGadget, Dec 24, 2019
  62. Phillip WoodJan 7, 2020
  63. Elijah NewrenJan 7, 2020
  64. Junio C HamanoJan 7, 2020
  65. Phillip WoodJan 8, 2020
  66. Junio C HamanoJan 8, 2020
  67. Phillip WoodJan 8, 2020
  68. 14/15 rebase: make the backend configurable via config settingElijah Newren via GitGitGadget, Dec 24, 2019
  69. 09/15 rebase: move incompatibility checks between backend options a bit earlierElijah Newren via GitGitGadget, Dec 24, 2019
  70. 15/15 rebase: change the default backend from "am" to "merge"Elijah Newren via GitGitGadget, Dec 24, 2019
  71. Jonathan NiederJan 10, 2020
  72. Elijah NewrenJan 11, 2020
  73. Phillip WoodJan 11, 2020
  74. Johannes SchindelinJan 12, 2020
  75. Elijah NewrenJan 16, 2020
  76. Jonathan NiederJan 16, 2020
  77. Jonathan NiederJan 16, 2020
  78. Elijah NewrenJan 16, 2020
  79. Jonathan NiederJan 16, 2020
  80. Elijah NewrenJan 16, 2020
  81. Jonathan NiederJan 16, 2020
  82. Elijah NewrenJan 16, 2020
  83. Junio C HamanoJan 16, 2020
  84. Elijah NewrenJan 17, 2020
  85. Elijah NewrenJan 16, 2020
  86. Junio C HamanoJan 16, 2020
  87. Johannes SchindelinJan 16, 2020
  88. Junio C HamanoJan 12, 2020
  89. Jonathan NiederJan 15, 2020
  90. Emily ShafferJan 15, 2020
  91. 13/15 rebase tests: repeat some tests using the merge backend instead of amElijah Newren via GitGitGadget, Dec 24, 2019
  92. 00/19 rebase: make the default backend configurableElijah Newren via GitGitGadget, Jan 16, 2020
  93. 01/19 git-rebase.txt: update description of --allow-empty-messageElijah Newren via GitGitGadget, Jan 16, 2020
  94. Phillip WoodFeb 9, 2020
  95. Elijah NewrenFeb 13, 2020
  96. 02/19 t3404: directly test the behavior of interestElijah Newren via GitGitGadget, Jan 16, 2020
  97. 03/19 rebase (interactive-backend): make --keep-empty the defaultElijah Newren via GitGitGadget, Jan 16, 2020
  98. Phillip WoodFeb 9, 2020
  99. Elijah NewrenFeb 13, 2020
  100. 04/19 rebase (interactive-backend): fix handling of commits that become emptyElijah Newren via GitGitGadget, Jan 16, 2020
  101. Phillip WoodFeb 10, 2020
  102. Elijah NewrenFeb 13, 2020
  103. Phillip WoodFeb 16, 2020
  104. 11/19 git-rebase.txt: add more details about behavioral differences of backendsElijah Newren via GitGitGadget, Jan 16, 2020
  105. 12/19 rebase: move incompatibility checks between backend options a bit earlierElijah Newren via GitGitGadget, Jan 16, 2020
  106. 14/19 git-prompt: change the prompt for interactive-based rebasesElijah Newren via GitGitGadget, Jan 16, 2020
  107. 07/19 rebase: make sure to pass along the quiet flag to the sequencerElijah Newren via GitGitGadget, Jan 16, 2020
  108. 06/19 rebase, sequencer: remove the broken GIT_QUIET handlingElijah Newren via GitGitGadget, Jan 16, 2020
  109. 10/19 rebase: allow more types of rebases to fast-forwardElijah Newren via GitGitGadget, Jan 16, 2020
  110. 09/19 t3432: make these tests work with either am or merge backendsElijah Newren via GitGitGadget, Jan 16, 2020
  111. 05/19 t3406: simplify an already simple testElijah Newren via GitGitGadget, Jan 16, 2020
  112. 08/19 rebase: fix handling of restrict_revisionElijah Newren via GitGitGadget, Jan 16, 2020
  113. 19/19 rebase: change the default backend from "am" to "merge"Elijah Newren via GitGitGadget, Jan 16, 2020
  114. 18/19 rebase: make the backend configurable via config settingElijah Newren via GitGitGadget, Jan 16, 2020
  115. 16/19 rebase tests: mark tests specific to the am-backend with --amElijah Newren via GitGitGadget, Jan 16, 2020
  116. 15/19 rebase: drop '-i' from the reflog for interactive-based rebasesElijah Newren via GitGitGadget, Jan 16, 2020
  117. 17/19 rebase tests: repeat some tests using the merge backend instead of amElijah Newren via GitGitGadget, Jan 16, 2020
  118. 13/19 rebase: add an --am optionElijah Newren via GitGitGadget, Jan 16, 2020
  119. Phillip WoodJan 17, 2020
  120. Junio C HamanoFeb 5, 2020
  121. Elijah NewrenFeb 5, 2020
  122. 00/20 rebase: make the default backend configurable and change the defaultElijah Newren via GitGitGadget, Feb 15, 2020
  123. 01/20 git-rebase.txt: update description of --allow-empty-messageElijah Newren via GitGitGadget, Feb 15, 2020
  124. 02/20 t3404: directly test the behavior of interestElijah Newren via GitGitGadget, Feb 15, 2020
  125. 05/20 t3406: simplify an already simple testElijah Newren via GitGitGadget, Feb 15, 2020
  126. 06/20 rebase, sequencer: remove the broken GIT_QUIET handlingElijah Newren via GitGitGadget, Feb 15, 2020
  127. 09/20 t3432: make these tests work with either am or merge backendsElijah Newren via GitGitGadget, Feb 15, 2020
  128. 03/20 rebase (interactive-backend): make --keep-empty the defaultElijah Newren via GitGitGadget, Feb 15, 2020
  129. 08/20 rebase: fix handling of restrict_revisionElijah Newren via GitGitGadget, Feb 15, 2020
  130. 04/20 rebase (interactive-backend): fix handling of commits that become emptyElijah Newren via GitGitGadget, Feb 15, 2020
  131. 12/20 rebase: move incompatibility checks between backend options a bit earlierElijah Newren via GitGitGadget, Feb 15, 2020
  132. 10/20 rebase: allow more types of rebases to fast-forwardElijah Newren via GitGitGadget, Feb 15, 2020
  133. 19/20 rebase: change the default backend from "am" to "merge"Elijah Newren via GitGitGadget, Feb 15, 2020
  134. 18/20 rebase: make the backend configurable via config settingElijah Newren via GitGitGadget, Feb 15, 2020
  135. 17/20 rebase tests: repeat some tests using the merge backend instead of amElijah Newren via GitGitGadget, Feb 15, 2020
  136. 16/20 rebase tests: mark tests specific to the am-backend with --amElijah Newren via GitGitGadget, Feb 15, 2020
  137. 20/20 rebase: rename the two primary rebase backendsElijah Newren via GitGitGadget, Feb 15, 2020
  138. Emily ShafferMar 12, 2020
  139. Elijah NewrenMar 12, 2020
  140. Jonathan NiederMar 12, 2020
  141. Elijah NewrenMar 12, 2020
  142. Jonathan NiederMar 12, 2020
  143. Elijah NewrenMar 12, 2020
  144. Jonathan NiederMar 17, 2020
  145. Elijah NewrenMar 17, 2020
  146. Junio C HamanoMar 12, 2020
  147. Junio C HamanoMar 12, 2020
  148. Jonathan NiederMar 12, 2020
  149. Junio C HamanoMar 12, 2020
  150. Elijah NewrenMar 12, 2020
  151. Jeff KingMar 12, 2020
  152. Junio C HamanoMar 12, 2020
  153. Elijah NewrenMar 12, 2020
  154. Junio C HamanoMar 13, 2020
  155. Jonathan NiederMar 12, 2020
  156. 07/20 rebase: make sure to pass along the quiet flag to the sequencerElijah Newren via GitGitGadget, Feb 15, 2020
  157. 15/20 rebase: drop '-i' from the reflog for interactive-based rebasesElijah Newren via GitGitGadget, Feb 15, 2020
  158. 14/20 git-prompt: change the prompt for interactive-based rebasesElijah Newren via GitGitGadget, Feb 15, 2020
  159. 13/20 rebase: add an --am optionElijah Newren via GitGitGadget, Feb 15, 2020
  160. 11/20 git-rebase.txt: add more details about behavioral differences of backendsElijah Newren via GitGitGadget, Feb 15, 2020
  161. Phillip WoodFeb 16, 2020

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.