All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] commit -v: add --word-diff opt to commit template
@ 2026-04-20 20:13 Kraktus via GitGitGadget
  0 siblings, 0 replies; only message in thread
From: Kraktus via GitGitGadget @ 2026-04-20 20:13 UTC (permalink / raw)
  To: git; +Cc: Kraktus, kraktus

From: kraktus <rinses-riotous8n@icloud.com>

`--word-diff` was available for the `diff` command, but not for
the `commit` one, whereas it is very useful when updating column-based
data-format like CSV for example.

Only support the PORCELAIN mode for now, but if deemed necessary can
add plain too, I don't think COLOR makes sense when outputting a file.

Signed-off-by: kraktus <rinses-riotous8n@icloud.com>
---
    commit -v: add --word-diff opt to commit template

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2276%2Fkraktus%2Fgdiff_word_commit-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2276/kraktus/gdiff_word_commit-v1
Pull-Request: https://github.com/git/git/pull/2276

 Documentation/git-commit.adoc |  4 ++++
 builtin/commit.c              |  4 ++++
 t/t7507-commit-verbose.sh     | 45 +++++++++++++++++++++++++++++++++++
 wt-status.c                   |  2 ++
 wt-status.h                   |  1 +
 5 files changed, 56 insertions(+)

diff --git a/Documentation/git-commit.adoc b/Documentation/git-commit.adoc
index 8329c1034b..6cb5359b52 100644
--- a/Documentation/git-commit.adoc
+++ b/Documentation/git-commit.adoc
@@ -371,6 +371,10 @@ If specified twice, show in addition the unified diff between
 what would be committed and the worktree files, i.e. the unstaged
 changes to tracked files.
 
+`--word-diff`::
+	Show a word diff instead of a line diff in the verbose commit
+	template (requires `-v`).
+
 `-q`::
 `--quiet`::
 	Suppress commit summary message.
diff --git a/builtin/commit.c b/builtin/commit.c
index a3e52ac9ca..b24f086fd2 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -126,6 +126,7 @@ static int all, also, interactive, patch_interactive, only, amend, signoff;
 static struct interactive_options interactive_opts = INTERACTIVE_OPTIONS_INIT;
 static int edit_flag = -1; /* unspecified */
 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
+static int commit_word_diff;
 static int config_commit_verbose = -1; /* unspecified */
 static int no_post_rewrite, allow_empty_message, pathspec_file_nul;
 static const char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
@@ -573,6 +574,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
 		s->reference = "HEAD^1";
 	}
 	s->verbose = verbose;
+	s->word_diff = commit_word_diff;
 	s->index_file = index_file;
 	s->fp = fp;
 	s->nowarn = nowarn;
@@ -1705,6 +1707,8 @@ int cmd_commit(int argc,
 	static struct option builtin_commit_options[] = {
 		OPT__QUIET(&quiet, N_("suppress summary after successful commit")),
 		OPT__VERBOSE(&verbose, N_("show diff in commit message template")),
+		OPT_BOOL(0, "word-diff", &commit_word_diff,
+			N_("show word diff in verbose commit template")),
 
 		OPT_GROUP(N_("Commit message options")),
 		OPT_FILENAME('F', "file", &logfile, N_("read message from file")),
diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh
index b53d71c086..98693d22f2 100755
--- a/t/t7507-commit-verbose.sh
+++ b/t/t7507-commit-verbose.sh
@@ -166,4 +166,49 @@ test_expect_success "status ignores commit.verbose=true" '
 	! grep "^diff --git actual"
 '
 
+write_script "check-for-word-diff" <<\EOF
+cp "$1" template_out
+exit 0
+EOF
+test_set_editor "$PWD/check-for-word-diff"
+
+test_expect_success 'setup for word-diff tests' '
+	echo "the quick brown fox" >wordfile &&
+	git add wordfile &&
+	git commit -F message &&
+	echo "the slow brown fox" >wordfile &&
+	git add wordfile &&
+	git commit -F message
+'
+
+test_expect_success '--word-diff with -v shows word diff' '
+	git commit --amend -v --word-diff &&
+	grep "^-quick$" template_out &&
+	grep "^+slow$" template_out
+'
+
+test_expect_success '--word-diff without -v is a no-op' '
+	git commit --amend --word-diff &&
+	! grep "^~$" template_out
+'
+
+test_expect_success '-v -v --word-diff shows word diff in both sections' '
+	echo "the fast brown fox" >wordfile &&
+	git commit --amend -v -v --word-diff &&
+	grep "^-quick$" template_out &&
+	grep "^+slow$" template_out &&
+	grep "^-slow$" template_out &&
+	grep "^+fast$" template_out
+'
+
+test_expect_success 'word-diff markers stripped from saved commit message' '
+	git commit --amend -v --word-diff &&
+	check_message message
+'
+
+test_expect_success 'no --word-diff produces line diff without markers' '
+	git commit --amend -v &&
+	! grep "^~$" template_out
+'
+
 test_done
diff --git a/wt-status.c b/wt-status.c
index 479ccc3304..086275bae3 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1177,6 +1177,8 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
 	rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
 	rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
 	rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
+	if (s->word_diff)
+		rev.diffopt.word_diff = DIFF_WORDS_PORCELAIN;
 	rev.diffopt.file = s->fp;
 	rev.diffopt.close_file = 0;
 	/*
diff --git a/wt-status.h b/wt-status.h
index e9fe32e98c..90883d2c28 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -130,6 +130,7 @@ struct wt_status {
 	int detect_rename;
 	int rename_score;
 	int rename_limit;
+	int word_diff;
 	enum wt_status_format status_format;
 	unsigned char added_cut_line; /* boolean */
 	struct wt_status_state state;

base-commit: e8955061076952cc5eab0300424fc48b601fe12d
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-04-20 20:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 20:13 [PATCH] commit -v: add --word-diff opt to commit template Kraktus via GitGitGadget

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.