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

[PATCH v15 8/8] history: support editing squashed commit messages

From
Harald Nordgren via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 8, 2026, 20:41 UTC
Message-ID
<8da033364685e6b88aa4bc2b44cc2a93b34e97a8.1788900120.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.2337.v15.git.git.1788900119.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>

Open the editor by default when squashing and provide --no-edit as the opt-out. Record the exact commits selected by the revision walk, rearrange that todo list with the sequencer's autosquash machinery, and build the message template from the resulting order.

Match interactive rebase's treatment of marker messages: comment out fixup! messages, retain squash! bodies, and let amend! replace its target unless a preceding squash! requires both bodies. This keeps message editing aligned with the marker validation used by the no-edit path.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
 Documentation/git-history.adoc |  18 ++-
 builtin/history.c              |  97 +++++++++++++++-
 t/t3455-history-squash.sh      | 197 +++++++++++++++++++++++++++++++++
 3 files changed, 305 insertions(+), 7 deletions(-)
diff --git a/Documentation/git-history.adoc b/Documentation/git-history.adoc
index fb04a67685..2e2e31f521 100644
--- a/Documentation/git-history.adoc
+++ b/Documentation/git-history.adoc
@@ -133,8 +133,9 @@ given, for example `HEAD~3..HEAD ^topic` to additionally exclude what is
 already on `topic`. Rev-list options may also be given, but any that would
 change how the range is walked are overridden with a warning.
 +
-With `--no-edit`, the oldest commit's message is preserved, except that an
-`amend!` commit targeting it replaces its message.
+An editor opens pre-filled with the messages of all the folded commits so you
+can combine them. With `--no-edit`, the oldest commit's message is preserved
+instead, except that an `amend!` commit targeting it replaces its message.
 +
 The selected commits must form a connected graph with a single tip and must
 not include a root commit. Every parent of a commit after the oldest one must
@@ -148,6 +149,13 @@ of markers for one target is combined into a single commit. With `--no-edit`,
 the last `amend!` message is used if there is one; a `squash!` or `amend!` is
 otherwise refused if folding it would discard its message.
 +
+The editor template mirrors `git rebase -i --autosquash`: each `fixup!`,
+`squash!`, or `amend!` is grouped under the commit it targets rather than
+shown in commit order. A `fixup!` message is dropped (commented out in full),
+a `squash!` keeps its body with only the marker subject commented, and an
+`amend!` replaces its target's message, unless a `squash!` folded into that
+target first, in which case it keeps its body like a `squash!`.
++
 A local branch descended from a selected commit but not from the range tip
 cannot be rewritten as a descendant of the result, so with the default
 `--update-refs=branches` the command refuses. Rerun with `--update-refs=head`
@@ -163,6 +171,12 @@ OPTIONS
 	objects will be written into the repository, so applying these printed
 	ref updates is generally safe.
 
+`--edit`::
+`--no-edit`::
+	For `squash`, open an editor to combine the messages of the folded commits.
+	This is the default; use `--no-edit` to keep the selected message without
+	opening an editor.
+
 `--reedit-message`::
 	Open an editor to modify the target commit's message.
 
diff --git a/builtin/history.c b/builtin/history.c
index 8176f6794e..2d88bc4352 100644
--- a/builtin/history.c
+++ b/builtin/history.c
@@ -1266,6 +1266,10 @@ static int squash_check_subject(struct repository *repo,
 	return ret;
 }
 
+static int build_squash_message(struct repository *repo,
+				const struct strbuf *todo_buf,
+				struct strbuf *out);
+
 static int setup_squash_revisions(struct repository *repo,
 				  int argc, const char **argv,
 				  struct rev_info *revs)
@@ -1319,6 +1323,7 @@ static int setup_squash_revisions(struct repository *repo,
  */
 static int resolve_squash_range(struct repository *repo,
 				bool update_branches,
+				bool edit_message,
 				int argc, const char **argv,
 				struct commit **oldest_out,
 				struct commit **tip_out,
@@ -1327,11 +1332,13 @@ static int resolve_squash_range(struct repository *repo,
 	struct rev_info revs;
 	struct subject_data subject_data = SUBJECT_DATA_INIT;
 	struct commit *commit, *oldest = NULL, *tip = NULL;
+	struct strbuf todo_buf = STRBUF_INIT;
 	int ret, tip_count = 0;
 	bool walk_started = false;
 	struct ref_filter filter = REF_FILTER_INIT;
 	struct ref_array refs = { 0 };
 
+	subject_data.edit_message = edit_message;
 	ret = setup_squash_revisions(repo, argc, argv, &revs);
 	if (ret < 0)
 		goto out;
@@ -1344,6 +1351,10 @@ static int resolve_squash_range(struct repository *repo,
 	while ((commit = get_revision(&revs))) {
 		struct commit_list *p;
 
+		if (edit_message)
+			strbuf_addf(&todo_buf, "pick %s\n",
+				    oid_to_hex(&commit->object.oid));
+
 		if (!commit->parents) {
 			ret = error(_("cannot squash down to root commit"));
 			goto out;
@@ -1457,6 +1468,13 @@ static int resolve_squash_range(struct repository *repo,
 		string_list_clear(&sorting_options, 0);
 		goto out;
 	}
+	if (edit_message) {
+		strbuf_reset(&subject_data.squash_message);
+		ret = build_squash_message(repo, &todo_buf,
+					   &subject_data.squash_message);
+		if (ret < 0)
+			goto out;
+	}
 
 	*oldest_out = oldest;
 	*tip_out = tip;
@@ -1464,6 +1482,7 @@ static int resolve_squash_range(struct repository *repo,
 	ret = 0;
 
 out:
+	strbuf_release(&todo_buf);
 	clear_object_flags(repo, SQUASH_SEEN | SQUASH_TIP |
 			   SQUASH_AMEND_TARGET);
 	if (walk_started)
@@ -1475,6 +1494,76 @@ out:
 	return ret;
 }
 
+static bool amend_replaces_target(struct todo_list *todo, int target)
+{
+	for (int i = target + 1; i < todo->nr &&
+				 todo->items[i].command != TODO_PICK; i++) {
+		if (todo->items[i].command == TODO_SQUASH)
+			return false;
+		if (todo->items[i].flags & TODO_REPLACE_FIXUP_MSG)
+			return true;
+	}
+	return false;
+}
+
+static int build_squash_message(struct repository *repo,
+				const struct strbuf *todo_buf,
+				struct strbuf *out)
+{
+	struct todo_list todo = TODO_LIST_INIT;
+	struct replay_opts opts = REPLAY_OPTS_INIT;
+	int nr_commits, ret;
+
+	if (todo_list_parse_insn_buffer(repo, &opts, todo_buf->buf, &todo) < 0 ||
+	    todo_list_rearrange_squash(&todo) < 0) {
+		ret = error(_("could not prepare the squash message"));
+		goto out;
+	}
+
+	nr_commits = todo.nr;
+	for (int i = 0; i < nr_commits; i++) {
+		struct todo_item *item = &todo.items[i];
+		const char *message, *body;
+		size_t commented_len;
+		bool skip, squashing;
+
+		squashing = item->command == TODO_SQUASH ||
+			    (item->flags & TODO_REPLACE_FIXUP_MSG);
+		if (item->command == TODO_PICK)
+			skip = amend_replaces_target(&todo, i);
+		else
+			skip = !squashing;
+
+		message = repo_logmsg_reencode(repo, item->commit, NULL, NULL);
+		find_commit_subject(message, &body);
+
+		if (skip)
+			commented_len = strlen(body);
+		else if (squashing)
+			commented_len = squash_subject_comment_len(body, 1);
+		else
+			commented_len = 0;
+
+		if (!i)
+			add_squash_combination_header(out, nr_commits);
+		strbuf_addch(out, '\n');
+		add_squash_message_header(out, i + 1, skip);
+		strbuf_addstr(out, "\n\n");
+		strbuf_add_commented_lines(out, body, commented_len, comment_line_str);
+		strbuf_addstr(out, body + commented_len);
+		strbuf_complete_line(out);
+
+		repo_unuse_commit_buffer(repo, item->commit, message);
+	}
+
+	ret = 0;
+
+out:
+	todo_list_release(&todo);
+	replay_opts_release(&opts);
+	return ret;
+}
+
 static int cmd_history_squash(int argc,
 			      const char **argv,
 			      const char *prefix,
@@ -1519,14 +1608,11 @@ static int cmd_history_squash(int argc,
 	strbuf_join_argv(&reflog_msg, argc - 1, argv + 1, ' ');
 
 	ret = resolve_squash_range(repo, action == REF_ACTION_BRANCHES,
+				   edit,
 				   argc, argv, &oldest, &tip,
 				   &message_template);
 	if (ret < 0)
 		goto out;
-	if (edit) {
-		ret = error(_("message editing is not supported yet; use '--no-edit'"));
-		goto out;
-	}
 
 	ret = setup_revwalk(repo, action, tip, &revs);
 	if (ret < 0)
@@ -1538,7 +1624,8 @@ static int cmd_history_squash(int argc,
 
 	ret = commit_tree_ext(repo, "squash", oldest, message_template,
 			      oldest->parents, base_tree_oid, tip_tree_oid,
-			      &rewritten, 0);
+			      &rewritten,
+			      edit ? COMMIT_TREE_EDIT_MESSAGE : 0);
 	if (ret < 0) {
 		ret = error(_("failed writing squashed commit"));
 		goto out;
diff --git a/t/t3455-history-squash.sh b/t/t3455-history-squash.sh
index fb06637aaf..d21e9d9fc4 100755
--- a/t/t3455-history-squash.sh
+++ b/t/t3455-history-squash.sh
@@ -381,6 +381,203 @@ test_expect_success 'squashing fixups into a merge' '
 	sed 1,2d msg | test_commit_message HEAD
 '
 
+test_expect_success 'edits every message and aborts on an empty result' '
+	git reset --hard start &&
+	stage_file b &&
+	git commit -m "re-one subject" -m "re-one body line" &&
+	test_commit --no-tag re-two file c &&
+	test_commit re-three file d &&
+	head_before=$(git rev-parse HEAD) &&
+
+	write_script empty-editor <<-\EOF &&
+	>"$1"
+	EOF
+	test_set_editor "$(pwd)/empty-editor" &&
+	test_must_fail git history squash start.. 2>err &&
+	test_grep "Aborting commit due to empty commit message" err &&
+	test_cmp_rev "$head_before" HEAD &&
+
+	write_script editor <<-\EOF &&
+	cat "$1" >edited &&
+	echo combined >"$1"
+	EOF
+	test_set_editor "$(pwd)/editor" &&
+	git history squash start.. &&
+
+	cat >expect <<-EOF &&
+	# This is a combination of 3 commits.
+	# This is the 1st commit message:
+
+	re-one subject
+
+	re-one body line
+
+	# This is the commit message #2:
+
+	re-two
+
+	# This is the commit message #3:
+
+	re-three
+
+	# Please enter the commit message for the squash changes. Lines starting
+	# with ${SQ}#${SQ} will be ignored, and an empty message aborts the commit.
+	# Changes to be committed:
+	#	modified:   file
+	#
+	EOF
+	test_cmp expect edited &&
+	check_log_subjects -1 <<-\EOF
+	combined
+	EOF
+'
+
+test_expect_success 'handles fixup!, squash! and amend! like rebase' '
+	git reset --hard start &&
+	test_commit --no-tag mark-base file b &&
+	stage_file c &&
+	commit_with_message "fixup! mark-base\n\nfixup body\n" &&
+	stage_file d &&
+	commit_with_message "squash! mark-base\n\nsquash remark\n" &&
+	stage_file e &&
+	commit_with_message "amend! mark-base\n\namended message\n" &&
+
+	write_script editor <<-\EOF &&
+	cat "$1" >edited
+	EOF
+	test_set_editor "$(pwd)/editor" &&
+	git history squash start.. &&
+
+	cat >expect <<-EOF &&
+	# This is a combination of 4 commits.
+	# This is the 1st commit message:
+
+	mark-base
+
+	# The commit message #2 will be skipped:
+
+	# fixup! mark-base
+	#
+	# fixup body
+
+	# This is the commit message #3:
+
+	# squash! mark-base
+
+	squash remark
+
+	# This is the commit message #4:
+
+	# amend! mark-base
+
+	amended message
+
+	# Please enter the commit message for the squash changes. Lines starting
+	# with ${SQ}#${SQ} will be ignored, and an empty message aborts the commit.
+	# Changes to be committed:
+	#	modified:   file
+	#
+	EOF
+	test_cmp expect edited &&
+	check_log_messages -1 <<-\EOF
+	mark-base
+
+	squash remark
+
+	amended message
+
+	EOF
+'
+
+test_expect_success 'groups fixups under their targets in the editor' '
+	git reset --hard start &&
+	test_commit --no-tag alpha file a1 &&
+	test_commit --no-tag beta file b1 &&
+	stage_file a2 &&
+	commit_with_message "fixup! alpha\n" &&
+	stage_file b2 &&
+	commit_with_message "fixup! beta\n" &&
+
+	write_script editor <<-\EOF &&
+	cat "$1" >edited
+	EOF
+	test_set_editor "$(pwd)/editor" &&
+	git history squash start.. &&
+
+	cat >expect <<-EOF &&
+	# This is a combination of 4 commits.
+	# This is the 1st commit message:
+
+	alpha
+
+	# The commit message #2 will be skipped:
+
+	# fixup! alpha
+
+	# This is the commit message #3:
+
+	beta
+
+	# The commit message #4 will be skipped:
+
+	# fixup! beta
+
+	# Please enter the commit message for the squash changes. Lines starting
+	# with ${SQ}#${SQ} will be ignored, and an empty message aborts the commit.
+	# Changes to be committed:
+	#	modified:   file
+	#
+	EOF
+	test_cmp expect edited
+'
+
+test_expect_success 'lets amend! replace its target message in the editor' '
+	git reset --hard start &&
+	test_commit --no-tag mark-base file b &&
+	stage_file c &&
+	commit_with_message "amend! mark-base\n\namended message\n" &&
+	stage_file d &&
+	commit_with_message "squash! mark-base\n\nsquash remark\n" &&
+
+	write_script editor <<-\EOF &&
+	cat "$1" >edited
+	EOF
+	test_set_editor "$(pwd)/editor" &&
+	git history squash start.. &&
+
+	cat >expect <<-EOF &&
+	# This is a combination of 3 commits.
+	# The 1st commit message will be skipped:
+
+	# mark-base
+
+	# This is the commit message #2:
+
+	# amend! mark-base
+
+	amended message
+
+	# This is the commit message #3:
+
+	# squash! mark-base
+
+	squash remark
+
+	# Please enter the commit message for the squash changes. Lines starting
+	# with ${SQ}#${SQ} will be ignored, and an empty message aborts the commit.
+	# Changes to be committed:
+	#	modified:   file
+	#
+	EOF
+	test_cmp expect edited &&
+	check_log_messages -1 <<-\EOF
+	amended message
+
+	squash remark
+
+	EOF
+'
+
 test_expect_success '--update-refs=head only moves HEAD' '
 	git reset --hard three &&
 	git branch -f other HEAD &&
-- 
gitgitgadget
Previous: Harald Nordgren via GitGitGadgetNext: Harald Nordgren via GitGitGadget
Message 184 of 185 in “rebase: add --fixup to fold a range into its oldest commit”
  1. 0/2 rebase: add --fixup to fold a range into its oldest commitHarald Nordgren via GitGitGadget, Jun 14, 2026
  2. 1/2 t3415: remove prepare-commit-msg hook after useHarald Nordgren via GitGitGadget, Jun 14, 2026
  3. 2/2 rebase: add --fixup-all to fold a rangeHarald Nordgren via GitGitGadget, Jun 14, 2026
  4. Junio C HamanoJun 15, 2026
  5. Harald NordgrenJun 15, 2026
  6. D. Ben KnobleJun 15, 2026
  7. Patrick SteinhardtJun 16, 2026
  8. Harald NordgrenJun 17, 2026
  9. 0/2 rebase: add --squash to fold a range into its first commitHarald Nordgren via GitGitGadget, Jun 15, 2026
  10. 1/2 t3415: remove prepare-commit-msg hook after useHarald Nordgren via GitGitGadget, Jun 15, 2026
  11. 2/2 rebase: add --squash to fold a rangeHarald Nordgren via GitGitGadget, Jun 15, 2026
  12. Phillip WoodJun 16, 2026
  13. Harald NordgrenJun 17, 2026
  14. Phillip WoodJun 17, 2026
  15. 0/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 18, 2026
  16. 1/4 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jun 18, 2026
  17. 2/4 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jun 18, 2026
  18. 3/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 18, 2026
  19. Junio C HamanoJun 18, 2026
  20. Junio C HamanoJun 18, 2026
  21. D. Ben KnobleJun 18, 2026
  22. Patrick SteinhardtJun 19, 2026
  23. 4/4 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jun 18, 2026
  24. D. Ben KnobleJun 18, 2026
  25. Junio C HamanoJun 19, 2026
  26. Patrick SteinhardtJun 19, 2026
  27. Junio C HamanoJun 19, 2026
  28. 0/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 21, 2026
  29. 1/4 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jun 21, 2026
  30. 2/4 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jun 21, 2026
  31. 3/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 21, 2026
  32. 4/4 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jun 21, 2026
  33. Patrick SteinhardtJun 22, 2026
  34. Harald NordgrenJun 23, 2026
  35. 0/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 24, 2026
  36. 1/4 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jun 24, 2026
  37. 2/4 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jun 24, 2026
  38. 3/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 24, 2026
  39. 4/4 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jun 24, 2026
  40. Phillip WoodJun 26, 2026
  41. Harald NordgrenJun 26, 2026
  42. Phillip WoodJun 26, 2026
  43. Junio C HamanoJun 26, 2026
  44. Harald NordgrenJun 26, 2026
  45. Patrick SteinhardtJun 29, 2026
  46. Phillip WoodJun 29, 2026
  47. Junio C HamanoJun 29, 2026
  48. Phillip WoodJul 1, 2026
  49. Harald NordgrenJun 29, 2026
  50. Phillip WoodJun 29, 2026
  51. Harald NordgrenJun 29, 2026
  52. Phillip WoodJun 30, 2026
  53. Harald NordgrenJun 30, 2026
  54. Phillip WoodJul 1, 2026
  55. Junio C HamanoJul 1, 2026
  56. Phillip WoodJul 1, 2026
  57. Junio C HamanoJul 1, 2026
  58. Phillip WoodJul 2, 2026
  59. Matt HunterJun 30, 2026
  60. Harald NordgrenJun 30, 2026
  61. Matt HunterJun 30, 2026
  62. Phillip WoodJun 30, 2026
  63. Patrick SteinhardtJul 2, 2026
  64. Junio C HamanoJul 2, 2026
  65. Harald NordgrenJun 29, 2026
  66. 0/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 28, 2026
  67. 1/4 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jun 28, 2026
  68. 2/4 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jun 28, 2026
  69. 3/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jun 28, 2026
  70. Junio C HamanoJun 29, 2026
  71. 4/4 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jun 28, 2026
  72. Junio C HamanoJun 29, 2026
  73. Harald NordgrenJun 29, 2026
  74. Junio C HamanoJun 29, 2026
  75. Junio C HamanoJun 29, 2026
  76. 0/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 6, 2026
  77. 1/5 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jul 6, 2026
  78. 2/5 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jul 6, 2026
  79. 3/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 6, 2026
  80. 4/5 sequencer: extract helpers for the squash message markersHarald Nordgren via GitGitGadget, Jul 6, 2026
  81. 5/5 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jul 6, 2026
  82. Phillip WoodJul 6, 2026
  83. Harald NordgrenJul 7, 2026
  84. Harald NordgrenJul 7, 2026
  85. Phillip WoodJul 7, 2026
  86. Phillip WoodJul 7, 2026
  87. Junio C HamanoJul 6, 2026
  88. 0/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 10, 2026
  89. 1/5 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jul 10, 2026
  90. 2/5 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jul 10, 2026
  91. 3/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 10, 2026
  92. 4/5 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Jul 10, 2026
  93. 5/5 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jul 10, 2026
  94. Matt HunterJul 14, 2026
  95. Harald NordgrenJul 14, 2026
  96. Harald NordgrenJul 14, 2026
  97. Ben KnobleJul 14, 2026
  98. Junio C HamanoJul 14, 2026
  99. 0/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 15, 2026
  100. 1/5 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jul 15, 2026
  101. 2/5 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jul 15, 2026
  102. 3/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 15, 2026
  103. Matt HunterJul 18, 2026
  104. Harald NordgrenJul 18, 2026
  105. 4/5 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Jul 15, 2026
  106. 5/5 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jul 15, 2026
  107. Matt HunterJul 18, 2026
  108. Harald NordgrenJul 18, 2026
  109. 0/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 20, 2026
  110. 1/5 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Jul 20, 2026
  111. 2/5 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Jul 20, 2026
  112. 3/5 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Jul 20, 2026
  113. Phillip WoodAug 3, 2026
  114. 1/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  115. 2/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  116. 3/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  117. 4/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  118. 5/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  119. 6/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  120. 7/3 fixup! history: add squash subcommand to fold a rangePhillip Wood, Aug 3, 2026
  121. Harald NordgrenAug 3, 2026
  122. Phillip WoodAug 4, 2026
  123. Junio C HamanoAug 4, 2026
  124. Harald NordgrenAug 4, 2026
  125. Harald NordgrenAug 4, 2026
  126. Tuomas AholaAug 7, 2026
  127. Junio C HamanoAug 4, 2026
  128. Phillip WoodAug 7, 2026
  129. Harald NordgrenAug 7, 2026
  130. Kristoffer HaugsbakkAug 6, 2026
  131. 4/5 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Jul 20, 2026
  132. 5/5 history: re-edit a squash with every messageHarald Nordgren via GitGitGadget, Jul 20, 2026
  133. Matt HunterJul 21, 2026
  134. 0/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Aug 1, 2026
  135. 1/4 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Aug 1, 2026
  136. 2/4 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Aug 1, 2026
  137. 3/4 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Aug 1, 2026
  138. 4/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Aug 1, 2026
  139. 0/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Aug 4, 2026
  140. 1/4 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Aug 4, 2026
  141. 2/4 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Aug 4, 2026
  142. 3/4 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Aug 4, 2026
  143. 4/4 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Aug 4, 2026
  144. 0/8 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Aug 7, 2026
  145. 1/8 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Aug 7, 2026
  146. 2/8 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Aug 7, 2026
  147. 3/8 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Aug 7, 2026
  148. 4/8 history: add skeleton for squash subcommandHarald Nordgren via GitGitGadget, Aug 7, 2026
  149. 5/8 history: validate squash revision rangesHarald Nordgren via GitGitGadget, Aug 7, 2026
  150. 6/8 history: protect branches when squashing a rangeHarald Nordgren via GitGitGadget, Aug 7, 2026
  151. 7/8 history: create squashed commits without editingHarald Nordgren via GitGitGadget, Aug 7, 2026
  152. Junio C HamanoAug 13, 2026
  153. Junio C HamanoAug 13, 2026
  154. Phillip WoodAug 17, 2026
  155. Junio C HamanoAug 17, 2026
  156. Junio C HamanoAug 17, 2026
  157. Junio C HamanoAug 17, 2026
  158. Junio C HamanoAug 17, 2026
  159. Harald NordgrenAug 17, 2026
  160. Kristoffer HaugsbakkAug 17, 2026
  161. 8/8 history: support editing squashed commit messagesHarald Nordgren via GitGitGadget, Aug 7, 2026
  162. 0/8 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Aug 20, 2026
  163. 1/8 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Aug 20, 2026
  164. 2/8 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Aug 20, 2026
  165. 3/8 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Aug 20, 2026
  166. 4/8 history: add skeleton for squash subcommandHarald Nordgren via GitGitGadget, Aug 20, 2026
  167. 5/8 history: validate squash revision rangesHarald Nordgren via GitGitGadget, Aug 20, 2026
  168. 6/8 history: protect branches when squashing a rangeHarald Nordgren via GitGitGadget, Aug 20, 2026
  169. 7/8 history: create squashed commits without editingHarald Nordgren via GitGitGadget, Aug 20, 2026
  170. Junio C HamanoAug 20, 2026
  171. Phillip WoodAug 24, 2026
  172. Junio C HamanoAug 24, 2026
  173. Phillip WoodAug 25, 2026
  174. Junio C HamanoAug 25, 2026
  175. 8/8 history: support editing squashed commit messagesHarald Nordgren via GitGitGadget, Aug 20, 2026
  176. 0/8 history: add squash subcommand to fold a rangeHarald Nordgren via GitGitGadget, Sep 8, 2026
  177. 1/8 history: extract helper for a commit's parent treeHarald Nordgren via GitGitGadget, Sep 8, 2026
  178. 2/8 history: give commit_tree_ext a message templateHarald Nordgren via GitGitGadget, Sep 8, 2026
  179. 3/8 sequencer: share the squash message marker helpers and flagsHarald Nordgren via GitGitGadget, Sep 8, 2026
  180. 4/8 history: add skeleton for squash subcommandHarald Nordgren via GitGitGadget, Sep 8, 2026
  181. Junio C HamanoSep 8, 2026
  182. 5/8 history: validate squash revision rangesHarald Nordgren via GitGitGadget, Sep 8, 2026
  183. 6/8 history: protect branches when squashing a rangeHarald Nordgren via GitGitGadget, Sep 8, 2026
  184. 8/8 history: support editing squashed commit messagesHarald Nordgren via GitGitGadget, Sep 8, 2026
  185. 7/8 history: create squashed commits without editingHarald Nordgren via GitGitGadget, Sep 8, 2026

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.