]> granicus.if.org Git - git/commitdiff
difftool: add a skeleton for the upcoming builtin
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Tue, 17 Jan 2017 15:54:57 +0000 (16:54 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 17 Jan 2017 21:32:47 +0000 (13:32 -0800)
This adds a builtin difftool that still falls back to the legacy Perl
version, which has been renamed to `legacy-difftool`.

The idea is that the new, experimental, builtin difftool immediately hands
off to the legacy difftool for now, unless the config variable
difftool.useBuiltin is set to true.

This feature flag will be used in the upcoming Git for Windows v2.11.0
release, to allow early testers to opt-in to use the builtin difftool and
flesh out any bugs.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
.gitignore
Makefile
builtin.h
builtin/difftool.c [new file with mode: 0644]
git-legacy-difftool.perl [moved from git-difftool.perl with 100% similarity]
git.c
t/t7800-difftool.sh

index 05cb58a3d4ef47295fa8ef02add44a0f0dd90d1f..f96e50ed40cc5283953ccbaa84694a9927070e42 100644 (file)
@@ -76,6 +76,7 @@
 /git-init-db
 /git-interpret-trailers
 /git-instaweb
+/git-legacy-difftool
 /git-log
 /git-ls-files
 /git-ls-remote
index f53fcc90d71b7e0ba95b94e9baf67d559085863c..7863bc2f3d2ee2127f879f1402d7197c3547895a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -527,7 +527,7 @@ SCRIPT_LIB += git-sh-setup
 SCRIPT_LIB += git-sh-i18n
 
 SCRIPT_PERL += git-add--interactive.perl
-SCRIPT_PERL += git-difftool.perl
+SCRIPT_PERL += git-legacy-difftool.perl
 SCRIPT_PERL += git-archimport.perl
 SCRIPT_PERL += git-cvsexportcommit.perl
 SCRIPT_PERL += git-cvsimport.perl
@@ -888,6 +888,7 @@ BUILTIN_OBJS += builtin/diff-files.o
 BUILTIN_OBJS += builtin/diff-index.o
 BUILTIN_OBJS += builtin/diff-tree.o
 BUILTIN_OBJS += builtin/diff.o
+BUILTIN_OBJS += builtin/difftool.o
 BUILTIN_OBJS += builtin/fast-export.o
 BUILTIN_OBJS += builtin/fetch-pack.o
 BUILTIN_OBJS += builtin/fetch.o
index b9122bc5f497ea2030aa4d5348c44da1a3bd8995..67f80519dafc4875434437a34e438453bc2c78c4 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -60,6 +60,7 @@ extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
 extern int cmd_diff(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_difftool(int argc, const char **argv, const char *prefix);
 extern int cmd_fast_export(int argc, const char **argv, const char *prefix);
 extern int cmd_fetch(int argc, const char **argv, const char *prefix);
 extern int cmd_fetch_pack(int argc, const char **argv, const char *prefix);
diff --git a/builtin/difftool.c b/builtin/difftool.c
new file mode 100644 (file)
index 0000000..53870bb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * "git difftool" builtin command
+ *
+ * This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
+ * git-difftool--helper script.
+ *
+ * This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.
+ * The GIT_DIFF* variables are exported for use by git-difftool--helper.
+ *
+ * Any arguments that are unknown to this script are forwarded to 'git diff'.
+ *
+ * Copyright (C) 2016 Johannes Schindelin
+ */
+#include "builtin.h"
+#include "run-command.h"
+#include "exec_cmd.h"
+
+/*
+ * NEEDSWORK: this function can go once the legacy-difftool Perl script is
+ * retired.
+ *
+ * We intentionally avoid reading the config directly here, to avoid messing up
+ * the GIT_* environment variables when we need to fall back to exec()ing the
+ * Perl script.
+ */
+static int use_builtin_difftool(void) {
+       struct child_process cp = CHILD_PROCESS_INIT;
+       struct strbuf out = STRBUF_INIT;
+       int ret;
+
+       argv_array_pushl(&cp.args,
+                        "config", "--bool", "difftool.usebuiltin", NULL);
+       cp.git_cmd = 1;
+       if (capture_command(&cp, &out, 6))
+               return 0;
+       strbuf_trim(&out);
+       ret = !strcmp("true", out.buf);
+       strbuf_release(&out);
+       return ret;
+}
+
+int cmd_difftool(int argc, const char **argv, const char *prefix)
+{
+       /*
+        * NEEDSWORK: Once the builtin difftool has been tested enough
+        * and git-legacy-difftool.perl is retired to contrib/, this preamble
+        * can be removed.
+        */
+       if (!use_builtin_difftool()) {
+               const char *path = mkpath("%s/git-legacy-difftool",
+                                         git_exec_path());
+
+               if (sane_execvp(path, (char **)argv) < 0)
+                       die_errno("could not exec %s", path);
+
+               return 0;
+       }
+       prefix = setup_git_directory();
+       trace_repo_setup(prefix);
+       setup_work_tree();
+
+       die("TODO");
+}
similarity index 100%
rename from git-difftool.perl
rename to git-legacy-difftool.perl
diff --git a/git.c b/git.c
index e8b2baf2d15c8a68553780c3137c55c3fea99b11..a8e6a15657a5aba77226aef9d1c0b38a88f5e2d5 100644 (file)
--- a/git.c
+++ b/git.c
@@ -424,6 +424,12 @@ static struct cmd_struct commands[] = {
        { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
        { "diff-index", cmd_diff_index, RUN_SETUP },
        { "diff-tree", cmd_diff_tree, RUN_SETUP },
+       /*
+        * NEEDSWORK: Once the redirection to git-legacy-difftool.perl in
+        * builtin/difftool.c has been removed, this entry should be changed to
+        * RUN_SETUP | NEED_WORK_TREE
+        */
+       { "difftool", cmd_difftool },
        { "fast-export", cmd_fast_export, RUN_SETUP },
        { "fetch", cmd_fetch, RUN_SETUP },
        { "fetch-pack", cmd_fetch_pack, RUN_SETUP },
index 70a2de461af58119f507a915104ba139dd0245df..b6a6c30f24313bd829c3c534e581ddac4a155ff0 100755 (executable)
@@ -23,6 +23,8 @@ prompt_given ()
        test "$prompt" = "Launch 'test-tool' [Y/n]? branch"
 }
 
+# NEEDSWORK: lose all the PERL prereqs once legacy-difftool is retired.
+
 # Create a file on master and change it on branch
 test_expect_success PERL 'setup' '
        echo master >file &&