diff_opt: track whether flags have been set explicitly

The diff_opt infrastructure sets flags based on defaults and command
line options.  It is impossible to tell whether a flag has been set
as a default or on explicit request.  Update the structure so that
this detection is possible:

 * Add an extra "opt->touched_flags" that keeps track of all the
   fields that have been touched by DIFF_OPT_SET and DIFF_OPT_CLR.

 * You may continue setting the default values to the flags, like
   commands in the "log" family do in cmd_log_init_defaults(), but
   after you finished setting the defaults, you clear the
   touched_flags field;

 * And then you let the usual callchain call diff_opt_parse(),
   allowing the opt->flags be set or unset, while keeping track of
   which bits the user touched;

 * There is an optional callback "opt->set_default" that is called
   at the very beginning to let you inspect touched_flags and update
   opt->flags appropriately, before the remainder of the diffcore
   machinery is set up, taking the opt->flags value into account.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano 2013-05-10 17:10:11 +02:00
Родитель 4bd52d0956
Коммит 6c374008b1
4 изменённых файлов: 19 добавлений и 3 удалений

Просмотреть файл

@ -28,7 +28,8 @@ Calling sequence
* Call `diff_setup_done()`; this inspects the options set up so far for
internal consistency and make necessary tweaking to it (e.g. if
textual patch output was asked, recursive behaviour is turned on).
textual patch output was asked, recursive behaviour is turned on);
the callback set_default in diff_options can be used to tweak this more.
* As you find different pairs of files, call `diff_change()` to feed
modified files, `diff_addremove()` to feed created or deleted files,
@ -115,6 +116,13 @@ Notable members are:
operation, but some do not have anything to do with the diffcore
library.
`touched_flags`::
Records whether a flag has been changed due to user request
(rather than just set/unset by default).
`set_default`::
Callback which allows tweaking the options in diff_setup_done().
BINARY, TEXT;;
Affects the way how a file that is seemingly binary is treated.

Просмотреть файл

@ -91,6 +91,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
if (default_date_mode)
rev->date_mode = parse_date_format(default_date_mode);
rev->diffopt.touched_flags = 0;
}
static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,

3
diff.c
Просмотреть файл

@ -3213,6 +3213,9 @@ void diff_setup_done(struct diff_options *options)
{
int count = 0;
if (options->set_default)
options->set_default(options);
if (options->output_format & DIFF_FORMAT_NAME)
count++;
if (options->output_format & DIFF_FORMAT_NAME_STATUS)

8
diff.h
Просмотреть файл

@ -87,8 +87,9 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
#define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
#define DIFF_OPT_TOUCHED(opts, flag) ((opts)->touched_flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) (((opts)->flags |= DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag))
#define DIFF_OPT_CLR(opts, flag) (((opts)->flags &= ~DIFF_OPT_##flag),((opts)->touched_flags |= DIFF_OPT_##flag))
#define DIFF_XDL_TST(opts, flag) ((opts)->xdl_opts & XDF_##flag)
#define DIFF_XDL_SET(opts, flag) ((opts)->xdl_opts |= XDF_##flag)
#define DIFF_XDL_CLR(opts, flag) ((opts)->xdl_opts &= ~XDF_##flag)
@ -109,6 +110,7 @@ struct diff_options {
const char *single_follow;
const char *a_prefix, *b_prefix;
unsigned flags;
unsigned touched_flags;
int use_color;
int context;
int interhunkcontext;
@ -145,6 +147,8 @@ struct diff_options {
/* to support internal diff recursion by --follow hack*/
int found_follow;
void (*set_default)(struct diff_options *);
FILE *file;
int close_file;