git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Nicholas Guriev <nicholas@guriev.su>
To: git@vger.kernel.org
Subject: [RFC PATCH] mergetools: support difftool.tabbed setting
Date: Wed, 13 Jan 2021 08:59:55 +0300	[thread overview]
Message-ID: <2fb58fd30ae730ccd3e88ec51b5fe6d80ab7a8c7.camel@guriev.su> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 1457 bytes --]

I was asked how to configure "git difftool" to open files using several
tabs and stop spawning diff application on every modified file. I looked
into Git source and found no possibility to run diff tool at one step.

The patch allows a user to view diffs in single window at one go. The
current implementation is still poor and it can be used solely for
demonstration purposes. To see it in action, tweak the local gitconfig:

    git config difftool.prompt false
    git config difftool.tabbed true

Then run:

    git difftool -t vimdiff

Or:

    git difftool -t meld

The solution has some restrictions, diffing up to ten files works now (I
did not bother with dynamic memory allocation), and it does not handle spaces
in file names (I do not know how to pass them correctly to underlying tools
without "xargs -0").

I think the git-difftool--helper should be changed so that it could
process many files in single invocation and it would not use a temporary
file by itself. A similar behaviour can be done in git-mergetool, too.

Do you have ideas how to better implement such a feature? Any comments
are welcome.

P.S.: I'm attaching screenshots for a clear demo what I mean.
---
 diff.c                |  4 ++--
 git-mergetool--lib.sh | 36 +++++++++++++++++++++++++++++++++++-
 mergetools/meld       |  4 ++++
 mergetools/vimdiff    | 17 +++++++++++++++++
 4 files changed, 58 insertions(+), 3 deletions(-)




[-- Attachment #1.2: 0001-mergetools-support-difftool.tabbed-setting.patch --]
[-- Type: text/x-patch, Size: 3035 bytes --]

diff --git a/diff.c b/diff.c
index 2253ec880..8a265e0b0 100644
--- a/diff.c
+++ b/diff.c
@@ -532,7 +532,7 @@ static struct diff_tempfile {
 	 * this tempfile object is used to manage its lifetime.
 	 */
 	struct tempfile *tempfile;
-} diff_temp[2];
+} diff_temp[20];
 
 struct emit_callback {
 	int color_diff;
@@ -4275,7 +4275,7 @@ static void run_external_diff(const char *pgm,
 	if (run_command_v_opt_cd_env(argv.v, RUN_USING_SHELL, NULL, env.v))
 		die(_("external diff died, stopping at %s"), name);
 
-	remove_tempfile();
+	//remove_tempfile();
 	strvec_clear(&argv);
 	strvec_clear(&env);
 }
diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh
index 7225abd81..e599e4243 100644
--- a/git-mergetool--lib.sh
+++ b/git-mergetool--lib.sh
@@ -193,6 +193,8 @@ setup_tool () {
 		false
 	}
 
+	unset -f diff_combo_cmd
+
 	if test -f "$MERGE_TOOLS_DIR/$tool"
 	then
 		. "$MERGE_TOOLS_DIR/$tool"
@@ -248,6 +250,25 @@ trust_exit_code () {
 	fi
 }
 
+is_difftool_tabbed () {
+	: "${GIT_DIFFTOOL_TABBED:=$(git config --type=bool --default=false difftool.tabbed)}"
+	case $(printf "%s" "$GIT_DIFFTOOL_TABBED" | tr '[:upper:]' '[:lower:]') in
+	yes|on|true|1)
+		GIT_DIFFTOOL_TABBED=true
+		;;
+	no|off|false|0)
+		GIT_DIFFTOOL_TABBED=false
+		;;
+	*)
+		echo "error: bad boolean value of GIT_DIFFTOOL_TABBED" >&2
+		exit 1
+		;;
+	esac
+
+	test "$GIT_DIFFTOOL_TABBED" = true && test "$GIT_DIFF_PATH_TOTAL" -gt 1 \
+		&& type diff_combo_cmd >/dev/null 2>&1
+}
+
 
 # Entry point for running tools
 run_merge_tool () {
@@ -272,7 +293,20 @@ run_merge_tool () {
 
 # Run a either a configured or built-in diff tool
 run_diff_cmd () {
-	diff_cmd "$1"
+	if is_difftool_tabbed
+	then
+		temp_file="${TMPDIR:-/tmp}/git-${PPID}_tabbed-queue"
+		test "$GIT_DIFF_PATH_COUNTER" -eq 1 && > "$temp_file"
+		printf "%s " "$LOCAL" "$REMOTE" >> "$temp_file"
+
+		if [ "$GIT_DIFF_PATH_COUNTER" -eq "$GIT_DIFF_PATH_TOTAL" ]
+		then
+			diff_combo_cmd 3< "$temp_file"
+			rm -f -- "$temp_file"
+		fi
+	else
+		diff_cmd "$1"
+	fi
 }
 
 # Run a either a configured or built-in merge tool
diff --git a/mergetools/meld b/mergetools/meld
index aab4ebb93..6570bf0f8 100644
--- a/mergetools/meld
+++ b/mergetools/meld
@@ -2,6 +2,10 @@ diff_cmd () {
 	"$merge_tool_path" "$LOCAL" "$REMOTE"
 }
 
+diff_combo_cmd () {
+	( IFS=' '; "$merge_tool_path" $(printf ' --diff %s %s' `cat <&3`) 3<&- )
+}
+
 merge_cmd () {
 	check_meld_for_features
 
diff --git a/mergetools/vimdiff b/mergetools/vimdiff
index abc8ce4ec..31d6e1eaa 100644
--- a/mergetools/vimdiff
+++ b/mergetools/vimdiff
@@ -3,6 +3,23 @@ diff_cmd () {
 		-c 'wincmd l' -c 'cd $GIT_PREFIX' "$LOCAL" "$REMOTE"
 }
 
+multitabbed_script='
+	let i = 1
+	while i < argc()
+		execute "tabedit" fnameescape(argv(i - 1))
+		execute "diffsplit" fnameescape(argv(i))
+		wincmd L
+		let i = i + 2
+	endwhile
+	tabfirst
+	tabclose
+	unlet i
+'
+diff_combo_cmd () {
+	( IFS=' '; cd "$GIT_PREFIX" && "$merge_tool_path" -R -f \
+		-c "$multitabbed_script" `cat <&3` 3<&- )
+}
+
 merge_cmd () {
 	case "$1" in
 	*vimdiff)

[-- Attachment #1.3: meld_screenshot-1.png --]
[-- Type: image/png, Size: 58533 bytes --]

[-- Attachment #1.4: vimdiff_screenshot-2.png --]
[-- Type: image/png, Size: 42323 bytes --]

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

             reply	other threads:[~2021-01-13  6:04 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-13  5:59 Nicholas Guriev [this message]
2021-01-18 21:00 ` [RFC PATCH v2 0/3] implement tabbed mode in difftools Nicholas Guriev
2021-01-18 21:00   ` [RFC PATCH v2 1/3] mergetools: support difftool.tabbed setting Nicholas Guriev
2021-01-18 23:25     ` Junio C Hamano
2021-01-18 21:00   ` [RFC PATCH v2 2/3] difftool-helper: conciliate difftool.tabbed and difftool.prompt settings Nicholas Guriev
2021-01-18 21:00   ` [RFC PATCH v2 3/3] doc: describe new difftool.tabbed feature Nicholas Guriev
2021-01-25 21:21   ` [PATCH v3 0/4] difftools in tabbed mode Nicholas Guriev
2021-01-25 21:21     ` [PATCH v3 1/4] mergetools: support difftool.tabbed setting Nicholas Guriev
2021-01-25 21:21     ` [PATCH v3 2/4] difftool-helper: conciliate difftool.tabbed and difftool.prompt settings Nicholas Guriev
2021-01-25 23:04       ` Junio C Hamano
2021-01-25 21:21     ` [PATCH v3 3/4] doc: describe new difftool.tabbed feature Nicholas Guriev
2021-01-25 21:21     ` [PATCH v3 4/4] t7800: new tests of " Nicholas Guriev
2021-02-12  5:51 ` [RFC PATCH] mergetools: support difftool.tabbed setting David Aguilar
2021-02-12 22:21   ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2fb58fd30ae730ccd3e88ec51b5fe6d80ab7a8c7.camel@guriev.su \
    --to=nicholas@guriev.su \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).