summaryrefslogtreecommitdiff
path: root/builtin/difftool.c
blob: 53870bbaf7528546fb862fe0ea501bdbf437cdcc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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");
}