@@ -3437,6 +3437,22 @@ static int diff_filepair_is_phoney(struct diff_filespec *one,
34373437 return !DIFF_FILE_VALID (one ) && !DIFF_FILE_VALID (two );
34383438}
34393439
3440+ static int set_diff_algorithm (struct diff_options * opts ,
3441+ const char * alg )
3442+ {
3443+ long value = parse_algorithm_value (alg );
3444+
3445+ if (value < 0 )
3446+ return -1 ;
3447+
3448+ /* clear out previous settings */
3449+ DIFF_XDL_CLR (opts , NEED_MINIMAL );
3450+ opts -> xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK ;
3451+ opts -> xdl_opts |= value ;
3452+
3453+ return 0 ;
3454+ }
3455+
34403456static void builtin_diff (const char * name_a ,
34413457 const char * name_b ,
34423458 struct diff_filespec * one ,
@@ -4440,15 +4456,13 @@ static void run_diff_cmd(const char *pgm,
44404456 const char * xfrm_msg = NULL ;
44414457 int complete_rewrite = (p -> status == DIFF_STATUS_MODIFIED ) && p -> score ;
44424458 int must_show_header = 0 ;
4459+ struct userdiff_driver * drv = NULL ;
44434460
4444-
4445- if (o -> flags .allow_external ) {
4446- struct userdiff_driver * drv ;
4447-
4461+ if (o -> flags .allow_external || !o -> ignore_driver_algorithm )
44484462 drv = userdiff_find_by_path (o -> repo -> index , attr_path );
4449- if ( drv && drv -> external )
4450- pgm = drv -> external ;
4451- }
4463+
4464+ if ( o -> flags . allow_external && drv && drv -> external )
4465+ pgm = drv -> external ;
44524466
44534467 if (msg ) {
44544468 /*
@@ -4465,12 +4479,16 @@ static void run_diff_cmd(const char *pgm,
44654479 run_external_diff (pgm , name , other , one , two , xfrm_msg , o );
44664480 return ;
44674481 }
4468- if (one && two )
4482+ if (one && two ) {
4483+ if (!o -> ignore_driver_algorithm && drv && drv -> algorithm )
4484+ set_diff_algorithm (o , drv -> algorithm );
4485+
44694486 builtin_diff (name , other ? other : name ,
44704487 one , two , xfrm_msg , must_show_header ,
44714488 o , complete_rewrite );
4472- else
4489+ } else {
44734490 fprintf (o -> file , "* Unmerged path %s\n" , name );
4491+ }
44744492}
44754493
44764494static void diff_fill_oid_info (struct diff_filespec * one , struct index_state * istate )
@@ -4567,6 +4585,14 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
45674585 const char * name ;
45684586 const char * other ;
45694587
4588+ if (!o -> ignore_driver_algorithm ) {
4589+ struct userdiff_driver * drv = userdiff_find_by_path (o -> repo -> index ,
4590+ p -> one -> path );
4591+
4592+ if (drv && drv -> algorithm )
4593+ set_diff_algorithm (o , drv -> algorithm );
4594+ }
4595+
45704596 if (DIFF_PAIR_UNMERGED (p )) {
45714597 /* unmerged */
45724598 builtin_diffstat (p -> one -> path , NULL , NULL , NULL ,
@@ -5107,17 +5133,32 @@ static int diff_opt_diff_algorithm(const struct option *opt,
51075133 const char * arg , int unset )
51085134{
51095135 struct diff_options * options = opt -> value ;
5110- long value = parse_algorithm_value (arg );
51115136
51125137 BUG_ON_OPT_NEG (unset );
5113- if (value < 0 )
5138+
5139+ if (set_diff_algorithm (options , arg ))
51145140 return error (_ ("option diff-algorithm accepts \"myers\", "
51155141 "\"minimal\", \"patience\" and \"histogram\"" ));
51165142
5117- /* clear out previous settings */
5118- DIFF_XDL_CLR (options , NEED_MINIMAL );
5119- options -> xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK ;
5120- options -> xdl_opts |= value ;
5143+ options -> ignore_driver_algorithm = 1 ;
5144+
5145+ return 0 ;
5146+ }
5147+
5148+ static int diff_opt_diff_algorithm_no_arg (const struct option * opt ,
5149+ const char * arg , int unset )
5150+ {
5151+ struct diff_options * options = opt -> value ;
5152+
5153+ BUG_ON_OPT_NEG (unset );
5154+ BUG_ON_OPT_ARG (arg );
5155+
5156+ if (set_diff_algorithm (options , opt -> long_name ))
5157+ BUG ("available diff algorithms include \"myers\", "
5158+ "\"minimal\", \"patience\" and \"histogram\"" );
5159+
5160+ options -> ignore_driver_algorithm = 1 ;
5161+
51215162 return 0 ;
51225163}
51235164
@@ -5250,7 +5291,6 @@ static int diff_opt_patience(const struct option *opt,
52505291
52515292 BUG_ON_OPT_NEG (unset );
52525293 BUG_ON_OPT_ARG (arg );
5253- options -> xdl_opts = DIFF_WITH_ALG (options , PATIENCE_DIFF );
52545294 /*
52555295 * Both --patience and --anchored use PATIENCE_DIFF
52565296 * internally, so remove any anchors previously
@@ -5259,7 +5299,9 @@ static int diff_opt_patience(const struct option *opt,
52595299 for (i = 0 ; i < options -> anchors_nr ; i ++ )
52605300 free (options -> anchors [i ]);
52615301 options -> anchors_nr = 0 ;
5262- return 0 ;
5302+ options -> ignore_driver_algorithm = 1 ;
5303+
5304+ return set_diff_algorithm (options , "patience" );
52635305}
52645306
52655307static int diff_opt_ignore_regex (const struct option * opt ,
@@ -5562,9 +5604,10 @@ struct option *add_diff_options(const struct option *opts,
55625604 N_ ("prevent rename/copy detection if the number of rename/copy targets exceeds given limit" )),
55635605
55645606 OPT_GROUP (N_ ("Diff algorithm options" )),
5565- OPT_BIT (0 , "minimal" , & options -> xdl_opts ,
5566- N_ ("produce the smallest possible diff" ),
5567- XDF_NEED_MINIMAL ),
5607+ OPT_CALLBACK_F (0 , "minimal" , options , NULL ,
5608+ N_ ("produce the smallest possible diff" ),
5609+ PARSE_OPT_NONEG | PARSE_OPT_NOARG ,
5610+ diff_opt_diff_algorithm_no_arg ),
55685611 OPT_BIT_F ('w' , "ignore-all-space" , & options -> xdl_opts ,
55695612 N_ ("ignore whitespace when comparing lines" ),
55705613 XDF_IGNORE_WHITESPACE , PARSE_OPT_NONEG ),
@@ -5590,9 +5633,10 @@ struct option *add_diff_options(const struct option *opts,
55905633 N_ ("generate diff using the \"patience diff\" algorithm" ),
55915634 PARSE_OPT_NONEG | PARSE_OPT_NOARG ,
55925635 diff_opt_patience ),
5593- OPT_BITOP (0 , "histogram" , & options -> xdl_opts ,
5594- N_ ("generate diff using the \"histogram diff\" algorithm" ),
5595- XDF_HISTOGRAM_DIFF , XDF_DIFF_ALGORITHM_MASK ),
5636+ OPT_CALLBACK_F (0 , "histogram" , options , NULL ,
5637+ N_ ("generate diff using the \"histogram diff\" algorithm" ),
5638+ PARSE_OPT_NONEG | PARSE_OPT_NOARG ,
5639+ diff_opt_diff_algorithm_no_arg ),
55965640 OPT_CALLBACK_F (0 , "diff-algorithm" , options , N_ ("<algorithm>" ),
55975641 N_ ("choose a diff algorithm" ),
55985642 PARSE_OPT_NONEG , diff_opt_diff_algorithm ),
0 commit comments