difftool: eliminate use of global variables

Move difftool's global variables into a difftools_option struct in preparation for removal of USE_THE_REPOSITORY_VARIABLE. Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Aguilar committed Feb 5, 2025 at 20:20 UTC 8241ae63d821efc7906d13654cb63523dc4f0a3a
1 file changed +33 -18
builtin/difftool.c
+33 -18
@@ -36,18 +36,27 @@
36 #include "entry.h"
37 #include "setup.h"
38
39 -static int trust_exit_code;
40 -
39 static const char *const builtin_difftool_usage[] = {
40 N_("git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]"),
41 NULL
42 };
43
44 +struct difftool_options {
45 + int has_symlinks;
46 + int symlinks;
47 + int trust_exit_code;
48 +};
49 +
50 static int difftool_config(const char *var, const char *value,
51 const struct config_context *ctx, void *cb)
52 {
53 + struct difftool_options *dt_options = (struct difftool_options *)cb;
54 if (!strcmp(var, "difftool.trustexitcode")) {
50 - trust_exit_code = git_config_bool(var, value);
55 + dt_options->trust_exit_code = git_config_bool(var, value);
56 + return 0;
57 + }
58 + if (!strcmp(var, "core.symlinks")) {
59 + dt_options->has_symlinks = git_config_bool(var, value);
60 return 0;
61 }
62
@@ -291,13 +300,14 @@ static int ensure_leading_directories(char *path)
300 * to compare the readlink(2) result as text, even on a filesystem that is
301 * capable of doing a symbolic link.
302 */
294 -static char *get_symlink(const struct object_id *oid, const char *path)
303 +static char *get_symlink(struct difftool_options *dt_options,
304 + const struct object_id *oid, const char *path)
305 {
306 char *data;
307 if (is_null_oid(oid)) {
308 /* The symlink is unknown to Git so read from the filesystem */
309 struct strbuf link = STRBUF_INIT;
300 - if (has_symlinks) {
310 + if (dt_options->has_symlinks) {
311 if (strbuf_readlink(&link, path, strlen(path)))
312 die(_("could not read symlink %s"), path);
313 } else if (strbuf_read_file(&link, path, 128))
@@ -355,7 +365,8 @@ static void write_standin_files(struct pair_entry *entry,
365 write_file_in_directory(rdir, rdir_len, entry->path, entry->right);
366 }
367
358 -static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
368 +static int run_dir_diff(struct difftool_options *dt_options,
369 + const char *extcmd, const char *prefix,
370 struct child_process *child)
371 {
372 struct strbuf info = STRBUF_INIT, lpath = STRBUF_INIT;
@@ -469,13 +480,13 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
480 }
481
482 if (S_ISLNK(lmode)) {
472 - char *content = get_symlink(&loid, src_path);
483 + char *content = get_symlink(dt_options, &loid, src_path);
484 add_left_or_right(&symlinks2, src_path, content, 0);
485 free(content);
486 }
487
488 if (S_ISLNK(rmode)) {
478 - char *content = get_symlink(&roid, dst_path);
489 + char *content = get_symlink(dt_options, &roid, dst_path);
490 add_left_or_right(&symlinks2, dst_path, content, 1);
491 free(content);
492 }
@@ -528,7 +539,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
539 goto finish;
540 }
541 add_path(&wtdir, wtdir_len, dst_path);
531 - if (symlinks) {
542 + if (dt_options->symlinks) {
543 if (symlink(wtdir.buf, rdir.buf)) {
544 ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf);
545 goto finish;
@@ -614,7 +625,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
625 if (lstat(rdir.buf, &st))
626 continue;
627
617 - if ((symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode))
628 + if ((dt_options->symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode))
629 continue;
630
631 if (!indices_loaded) {
@@ -704,9 +715,13 @@ int cmd_difftool(int argc,
715 const char *prefix,
716 struct repository *repo UNUSED)
717 {
707 - int use_gui_tool = -1, dir_diff = 0, prompt = -1, symlinks = 0,
708 - tool_help = 0, no_index = 0;
718 + int use_gui_tool = -1, dir_diff = 0, prompt = -1, tool_help = 0, no_index = 0;
719 static char *difftool_cmd = NULL, *extcmd = NULL;
720 + struct difftool_options dt_options = {
721 + .has_symlinks = 1,
722 + .symlinks = 1,
723 + .trust_exit_code = 0
724 + };
725 struct option builtin_difftool_options[] = {
726 OPT_BOOL('g', "gui", &use_gui_tool,
727 N_("use `diff.guitool` instead of `diff.tool`")),
@@ -717,14 +732,14 @@ int cmd_difftool(int argc,
732 0, PARSE_OPT_NONEG),
733 OPT_SET_INT_F(0, "prompt", &prompt, NULL,
734 1, PARSE_OPT_NONEG | PARSE_OPT_HIDDEN),
720 - OPT_BOOL(0, "symlinks", &symlinks,
735 + OPT_BOOL(0, "symlinks", &dt_options.symlinks,
736 N_("use symlinks in dir-diff mode")),
737 OPT_STRING('t', "tool", &difftool_cmd, N_("tool"),
738 N_("use the specified diff tool")),
739 OPT_BOOL(0, "tool-help", &tool_help,
740 N_("print a list of diff tools that may be used with "
741 "`--tool`")),
727 - OPT_BOOL(0, "trust-exit-code", &trust_exit_code,
742 + OPT_BOOL(0, "trust-exit-code", &dt_options.trust_exit_code,
743 N_("make 'git-difftool' exit when an invoked diff "
744 "tool returns a non-zero exit code")),
745 OPT_STRING('x', "extcmd", &extcmd, N_("command"),
@@ -734,8 +749,8 @@ int cmd_difftool(int argc,
749 };
750 struct child_process child = CHILD_PROCESS_INIT;
751
737 - git_config(difftool_config, NULL);
738 - symlinks = has_symlinks;
752 + git_config(difftool_config, &dt_options);
753 + dt_options.symlinks = dt_options.has_symlinks;
754
755 argc = parse_options(argc, argv, prefix, builtin_difftool_options,
756 builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN_OPT |
@@ -783,7 +798,7 @@ int cmd_difftool(int argc,
798 }
799
800 setenv("GIT_DIFFTOOL_TRUST_EXIT_CODE",
786 - trust_exit_code ? "true" : "false", 1);
801 + dt_options.trust_exit_code ? "true" : "false", 1);
802
803 /*
804 * In directory diff mode, 'git-difftool--helper' is called once
@@ -799,6 +814,6 @@ int cmd_difftool(int argc,
814 strvec_pushv(&child.args, argv);
815
816 if (dir_diff)
802 - return run_dir_diff(extcmd, symlinks, prefix, &child);
817 + return run_dir_diff(&dt_options, extcmd, prefix, &child);
818 return run_file_diff(prompt, prefix, &child);
819 }