3636#include "entry.h"
3737#include "setup.h"
3838
39- static int trust_exit_code ;
40-
4139static const char * const builtin_difftool_usage [] = {
4240 N_ ("git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]" ),
4341 NULL
4442};
4543
44+ struct difftool_options {
45+ int has_symlinks ;
46+ int symlinks ;
47+ int trust_exit_code ;
48+ };
49+
4650static int difftool_config (const char * var , const char * value ,
4751 const struct config_context * ctx , void * cb )
4852{
53+ struct difftool_options * dt_options = (struct difftool_options * )cb ;
4954 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 );
5160 return 0 ;
5261 }
5362
@@ -291,13 +300,14 @@ static int ensure_leading_directories(char *path)
291300 * to compare the readlink(2) result as text, even on a filesystem that is
292301 * capable of doing a symbolic link.
293302 */
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 )
295305{
296306 char * data ;
297307 if (is_null_oid (oid )) {
298308 /* The symlink is unknown to Git so read from the filesystem */
299309 struct strbuf link = STRBUF_INIT ;
300- if (has_symlinks ) {
310+ if (dt_options -> has_symlinks ) {
301311 if (strbuf_readlink (& link , path , strlen (path )))
302312 die (_ ("could not read symlink %s" ), path );
303313 } else if (strbuf_read_file (& link , path , 128 ))
@@ -355,7 +365,8 @@ static void write_standin_files(struct pair_entry *entry,
355365 write_file_in_directory (rdir , rdir_len , entry -> path , entry -> right );
356366}
357367
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 ,
359370 struct child_process * child )
360371{
361372 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,
469480 }
470481
471482 if (S_ISLNK (lmode )) {
472- char * content = get_symlink (& loid , src_path );
483+ char * content = get_symlink (dt_options , & loid , src_path );
473484 add_left_or_right (& symlinks2 , src_path , content , 0 );
474485 free (content );
475486 }
476487
477488 if (S_ISLNK (rmode )) {
478- char * content = get_symlink (& roid , dst_path );
489+ char * content = get_symlink (dt_options , & roid , dst_path );
479490 add_left_or_right (& symlinks2 , dst_path , content , 1 );
480491 free (content );
481492 }
@@ -528,7 +539,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
528539 goto finish ;
529540 }
530541 add_path (& wtdir , wtdir_len , dst_path );
531- if (symlinks ) {
542+ if (dt_options -> symlinks ) {
532543 if (symlink (wtdir .buf , rdir .buf )) {
533544 ret = error_errno ("could not symlink '%s' to '%s'" , wtdir .buf , rdir .buf );
534545 goto finish ;
@@ -614,7 +625,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
614625 if (lstat (rdir .buf , & st ))
615626 continue ;
616627
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 ))
618629 continue ;
619630
620631 if (!indices_loaded ) {
@@ -704,9 +715,13 @@ int cmd_difftool(int argc,
704715 const char * prefix ,
705716 struct repository * repo UNUSED )
706717{
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 ;
709719 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+ };
710725 struct option builtin_difftool_options [] = {
711726 OPT_BOOL ('g' , "gui" , & use_gui_tool ,
712727 N_ ("use `diff.guitool` instead of `diff.tool`" )),
@@ -717,14 +732,14 @@ int cmd_difftool(int argc,
717732 0 , PARSE_OPT_NONEG ),
718733 OPT_SET_INT_F (0 , "prompt" , & prompt , NULL ,
719734 1 , PARSE_OPT_NONEG | PARSE_OPT_HIDDEN ),
720- OPT_BOOL (0 , "symlinks" , & symlinks ,
735+ OPT_BOOL (0 , "symlinks" , & dt_options . symlinks ,
721736 N_ ("use symlinks in dir-diff mode" )),
722737 OPT_STRING ('t' , "tool" , & difftool_cmd , N_ ("tool" ),
723738 N_ ("use the specified diff tool" )),
724739 OPT_BOOL (0 , "tool-help" , & tool_help ,
725740 N_ ("print a list of diff tools that may be used with "
726741 "`--tool`" )),
727- OPT_BOOL (0 , "trust-exit-code" , & trust_exit_code ,
742+ OPT_BOOL (0 , "trust-exit-code" , & dt_options . trust_exit_code ,
728743 N_ ("make 'git-difftool' exit when an invoked diff "
729744 "tool returns a non-zero exit code" )),
730745 OPT_STRING ('x' , "extcmd" , & extcmd , N_ ("command" ),
@@ -734,8 +749,8 @@ int cmd_difftool(int argc,
734749 };
735750 struct child_process child = CHILD_PROCESS_INIT ;
736751
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 ;
739754
740755 argc = parse_options (argc , argv , prefix , builtin_difftool_options ,
741756 builtin_difftool_usage , PARSE_OPT_KEEP_UNKNOWN_OPT |
@@ -783,7 +798,7 @@ int cmd_difftool(int argc,
783798 }
784799
785800 setenv ("GIT_DIFFTOOL_TRUST_EXIT_CODE" ,
786- trust_exit_code ? "true" : "false" , 1 );
801+ dt_options . trust_exit_code ? "true" : "false" , 1 );
787802
788803 /*
789804 * In directory diff mode, 'git-difftool--helper' is called once
@@ -799,6 +814,6 @@ int cmd_difftool(int argc,
799814 strvec_pushv (& child .args , argv );
800815
801816 if (dir_diff )
802- return run_dir_diff (extcmd , symlinks , prefix , & child );
817+ return run_dir_diff (& dt_options , extcmd , prefix , & child );
803818 return run_file_diff (prompt , prefix , & child );
804819}
0 commit comments