From: Keith Cascio <keith@cs.ucla.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: [PATCH v2 1/2] Introduce config variable "diff.primer"
Date: Mon, 2 Feb 2009 10:20:54 -0800 [thread overview]
Message-ID: <1233598855-1088-2-git-send-email-keith@cs.ucla.edu> (raw)
In-Reply-To: <1233598855-1088-1-git-send-email-keith@cs.ucla.edu>
Introduce config variable "diff.primer".
Improve porcelain diff's accommodation of user preference by allowing
some settings to (a) persist over all invocations and (b) stay consistent
over multiple tools (e.g. command-line and gui). The approach taken here
is good because it delivers the consistency a user expects without breaking
any plumbing. It works by allowing the user, via git-config, to specify
arbitrary options to pass to porcelain diff on every invocation, including
internal invocations from other programs, e.g. git-gui. Introduce diff
command-line options --primer and --no-primer. Affect only porcelain diff:
we suppress primer options for plumbing diff-{files,index,tree},
format-patch, and all other commands unless explicitly requested using
--primer (opt-in). Teach gitk to use --primer, but protect it from
inapplicable options like --color.
Signed-off-by: Keith Cascio <keith@cs.ucla.edu>
---
Documentation/config.txt | 14 +++++++
Documentation/diff-options.txt | 10 +++++
builtin-diff.c | 2 +
diff.c | 77 +++++++++++++++++++++++++++++++++++-----
diff.h | 14 ++++++--
gitk-git/gitk | 16 ++++----
6 files changed, 113 insertions(+), 20 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index e2b8775..bd85c4a 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -601,6 +601,20 @@ diff.autorefreshindex::
affects only 'git-diff' Porcelain, and not lower level
'diff' commands, such as 'git-diff-files'.
+diff.primer::
+ Whitespace-separated list of options to pass to 'git-diff'
+ on every invocation, including internal invocations from
+ linkgit:git-gui[1] and linkgit:gitk[1],
+ e.g. `"--patience --color --ignore-space-at-eol --exit-code"`.
+ See linkgit:git-diff[1]. You can suppress these at run time with
+ option `--no-primer`. Supports a subset of
+ 'git-diff'\'s many options, at least:
+ `-b --binary --color --color-words --cumulative --dirstat-by-file
+--exit-code --ext-diff --find-copies-harder --follow --full-index
+--ignore-all-space --ignore-space-at-eol --ignore-space-change
+--ignore-submodules --no-color --no-ext-diff --no-textconv --patience -q
+--quiet -R -r --relative -t --text --textconv -w`
+
diff.external::
If this config variable is set, diff generation is not
performed using the internal diff machinery, but using the
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 813a7b1..f422055 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -254,5 +254,15 @@ override configuration settings.
--no-prefix::
Do not show any source or destination prefix.
+--no-primer::
+ Ignore default options specified in '.git/config', i.e.
+ those that were set using a command like
+ `git config diff.primer "--patience --color --ignore-space-at-eol --exit-code"`
+
+--primer::
+ Opt-in for default options specified in '.git/config'. This option is
+ most often used with the three plumbing commands diff-{files,index,tree}.
+ These commands normally suppress default options.
+
For more detailed explanation on these common options, see also
linkgit:gitdiffcore[7].
diff --git a/builtin-diff.c b/builtin-diff.c
index d75d69b..b3c3e87 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -284,6 +284,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
init_revisions(&rev, prefix);
+ DIFF_OPT_SET(&rev.diffopt, PRIMER);
+
/* If this is a no-index diff, just run it and exit there. */
diff_no_index(&rev, argc, argv, nongit, prefix);
diff --git a/diff.c b/diff.c
index a5a540f..32455c3 100644
--- a/diff.c
+++ b/diff.c
@@ -26,6 +26,8 @@ static int diff_suppress_blank_empty;
int diff_use_color_default = -1;
static const char *diff_word_regex_cfg;
static const char *external_diff_cmd_cfg;
+static const char *diff_primer;
+static struct diff_options *primer;
int diff_auto_refresh_index = 1;
static int diff_mnemonic_prefix;
@@ -106,6 +108,8 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
diff_rename_limit_default = git_config_int(var, value);
return 0;
}
+ if (!strcmp(var, "diff.primer"))
+ return git_config_string(&diff_primer, var, value);
switch (userdiff_config(var, value)) {
case 0: break;
@@ -2316,6 +2320,45 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
builtin_checkdiff(name, other, attr_path, p->one, p->two, o);
}
+static const char blank[] = " \t\r\n";
+
+void parse_diff_primer(struct diff_options *options)
+{
+ char *str1, *token, *saveptr;
+ int len;
+
+ if ((! diff_primer) || ((len = (strlen(diff_primer)+1)) < 3))
+ return;
+
+ token = str1 = strncpy((char*) malloc(len), diff_primer, len);
+ if ((saveptr = strpbrk(token += strspn(token, blank), blank)))
+ *(saveptr++) = '\0';
+ while (token) {
+ if (*token == '-')
+ diff_opt_parse(options, (const char **) &token, -1);
+ if ((token = saveptr))
+ if ((saveptr = strpbrk(token += strspn(token, blank), blank)))
+ *(saveptr++) = '\0';
+ }
+
+ free( str1 );
+}
+
+struct diff_options* flatten_diff_options(struct diff_options *master, struct diff_options *slave)
+{
+ unsigned x0 = master->flags, x1 = master->mask, x2 = slave->flags, x3 = slave->mask;
+ long w = master->xdl_opts, x = master->xdl_mask, y = slave->xdl_opts, z = slave->xdl_mask;
+
+ //minimized by Quine-McCluskey
+ master->flags = (~x1&x2&x3)|(x0&~x3)|(x0&x1);
+ master->mask = x1|x3;
+
+ master->xdl_opts = (~x&y&z)|(w&~z)|(w&x);
+ master->xdl_mask = x|z;
+
+ return master;
+}
+
void diff_setup(struct diff_options *options)
{
memset(options, 0, sizeof(*options));
@@ -2326,14 +2369,15 @@ void diff_setup(struct diff_options *options)
options->break_opt = -1;
options->rename_limit = -1;
options->dirstat_percent = 3;
- DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE);
+ if (DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE))
+ DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE);
options->context = 3;
options->change = diff_change;
options->add_remove = diff_addremove;
if (diff_use_color_default > 0)
DIFF_OPT_SET(options, COLOR_DIFF);
- else
+ else if (DIFF_OPT_TST(options, COLOR_DIFF))
DIFF_OPT_CLR(options, COLOR_DIFF);
options->detect_rename = diff_detect_rename_default;
@@ -2423,6 +2467,14 @@ int diff_setup_done(struct diff_options *options)
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
}
+ if (DIFF_OPT_TST(options, PRIMER)) {
+ if (! primer) {
+ diff_setup(primer = (struct diff_options *) malloc(sizeof(struct diff_options)));
+ parse_diff_primer(primer);
+ }
+ flatten_diff_options(options, primer);
+ }
+
return 0;
}
@@ -2570,13 +2622,13 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
/* xdiff options */
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
- options->xdl_opts |= XDF_IGNORE_WHITESPACE;
+ DIFF_XDL_SET(options, IGNORE_WHITESPACE);
else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
- options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
+ DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
else if (!strcmp(arg, "--ignore-space-at-eol"))
- options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
+ DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
else if (!strcmp(arg, "--patience"))
- options->xdl_opts |= XDF_PATIENCE_DIFF;
+ DIFF_XDL_SET(options, PATIENCE_DIFF);
/* flags options */
else if (!strcmp(arg, "--binary")) {
@@ -2597,10 +2649,13 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_SET(options, COLOR_DIFF);
else if (!strcmp(arg, "--no-color"))
DIFF_OPT_CLR(options, COLOR_DIFF);
- else if (!strcmp(arg, "--color-words"))
- options->flags |= DIFF_OPT_COLOR_DIFF | DIFF_OPT_COLOR_DIFF_WORDS;
+ else if (!strcmp(arg, "--color-words")) {
+ DIFF_OPT_SET(options, COLOR_DIFF);
+ DIFF_OPT_SET(options, COLOR_DIFF_WORDS);
+ }
else if (!prefixcmp(arg, "--color-words=")) {
- options->flags |= DIFF_OPT_COLOR_DIFF | DIFF_OPT_COLOR_DIFF_WORDS;
+ DIFF_OPT_SET(options, COLOR_DIFF);
+ DIFF_OPT_SET(options, COLOR_DIFF_WORDS);
options->word_regex = arg + 14;
}
else if (!strcmp(arg, "--exit-code"))
@@ -2617,6 +2672,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
else if (!strcmp(arg, "--ignore-submodules"))
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
+ else if (!strcmp(arg, "--primer"))
+ DIFF_OPT_SET(options, PRIMER);
+ else if (!strcmp(arg, "--no-primer"))
+ DIFF_OPT_CLR(options, PRIMER);
/* misc options */
else if (!strcmp(arg, "-z"))
diff --git a/diff.h b/diff.h
index 23cd90c..7f11b12 100644
--- a/diff.h
+++ b/diff.h
@@ -66,9 +66,15 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19)
#define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20)
#define DIFF_OPT_ALLOW_TEXTCONV (1 << 21)
-#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_PRIMER (1 << 22)
+#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
+#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag), ((opts)->mask |= DIFF_OPT_##flag)
+#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag), ((opts)->mask |= DIFF_OPT_##flag)
+#define DIFF_OPT_DRT(opts, flag) ((opts)->mask & 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), ((opts)->xdl_mask |= XDF_##flag)
+#define DIFF_XDL_CLR(opts, flag) ((opts)->xdl_opts &= ~XDF_##flag), ((opts)->xdl_mask |= XDF_##flag)
+#define DIFF_XDL_DRT(opts, flag) ((opts)->xdl_mask & XDF_##flag)
struct diff_options {
const char *filter;
@@ -77,6 +83,7 @@ struct diff_options {
const char *single_follow;
const char *a_prefix, *b_prefix;
unsigned flags;
+ unsigned mask;
int context;
int interhunkcontext;
int break_opt;
@@ -95,6 +102,7 @@ struct diff_options {
int prefix_length;
const char *stat_sep;
long xdl_opts;
+ long xdl_mask;
int stat_width;
int stat_name_width;
diff --git a/gitk-git/gitk b/gitk-git/gitk
index dc2a439..b67bbaa 100644
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -4259,7 +4259,7 @@ proc do_file_hl {serial} {
# must be "containing:", i.e. we're searching commit info
return
}
- set cmd [concat | git diff-tree -r -s --stdin $gdtargs]
+ set cmd [concat | git diff-tree --primer --no-color -r -s --stdin $gdtargs]
set filehighlight [open $cmd r+]
fconfigure $filehighlight -blocking 0
filerun $filehighlight readfhighlight
@@ -4753,7 +4753,7 @@ proc dodiffindex {} {
if {!$showlocalchanges || !$isworktree} return
incr lserial
- set cmd "|git diff-index --cached HEAD"
+ set cmd "|git diff-index --primer --no-color --cached HEAD"
if {$vfilelimit($curview) ne {}} {
set cmd [concat $cmd -- $vfilelimit($curview)]
}
@@ -4782,7 +4782,7 @@ proc readdiffindex {fd serial inst} {
}
# now see if there are any local changes not checked in to the index
- set cmd "|git diff-files"
+ set cmd "|git diff-files --primer --no-color"
if {$vfilelimit($curview) ne {}} {
set cmd [concat $cmd -- $vfilelimit($curview)]
}
@@ -7068,7 +7068,7 @@ proc diffcmd {ids flags} {
if {$i >= 0} {
if {[llength $ids] > 1 && $j < 0} {
# comparing working directory with some specific revision
- set cmd [concat | git diff-index $flags]
+ set cmd [concat | git diff-index --primer --no-color $flags]
if {$i == 0} {
lappend cmd -R [lindex $ids 1]
} else {
@@ -7076,13 +7076,13 @@ proc diffcmd {ids flags} {
}
} else {
# comparing working directory with index
- set cmd [concat | git diff-files $flags]
+ set cmd [concat | git diff-files --primer --no-color $flags]
if {$j == 1} {
lappend cmd -R
}
}
} elseif {$j >= 0} {
- set cmd [concat | git diff-index --cached $flags]
+ set cmd [concat | git diff-index --primer --no-color --cached $flags]
if {[llength $ids] > 1} {
# comparing index with specific revision
if {$i == 0} {
@@ -7095,7 +7095,7 @@ proc diffcmd {ids flags} {
lappend cmd HEAD
}
} else {
- set cmd [concat | git diff-tree -r $flags $ids]
+ set cmd [concat | git diff-tree --primer --no-color -r $flags $ids]
}
return $cmd
}
@@ -10657,7 +10657,7 @@ if {[catch {package require Tk 8.4} err]} {
}
# defaults...
-set wrcomcmd "git diff-tree --stdin -p --pretty"
+set wrcomcmd "git diff-tree --primer --no-color --stdin -p --pretty"
set gitencoding {}
catch {
--
1.6.1
next parent reply other threads:[~2009-02-02 18:39 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1233598855-1088-1-git-send-email-keith@cs.ucla.edu>
2009-02-02 18:20 ` Keith Cascio [this message]
2009-02-02 18:20 ` [PATCH v2 2/2] Test functionality of new config variable "diff.primer" Keith Cascio
2009-02-02 20:45 ` [PATCH v2 0/2] Introduce " Keith Cascio
2009-02-02 21:03 ` Keith Cascio
2009-02-03 7:15 ` [PATCH v2 1/2] " Jeff King
2009-02-03 17:55 ` Keith Cascio
2009-02-04 5:43 ` Junio C Hamano
2009-02-04 6:36 ` Keith Cascio
2009-02-06 16:54 ` Jeff King
2009-02-06 16:19 ` Jeff King
2009-02-07 21:45 ` Junio C Hamano
2009-02-09 17:24 ` Keith Cascio
2009-02-13 22:22 ` Jeff King
2009-02-14 6:03 ` Johannes Schindelin
2009-02-14 6:15 ` Jeff King
2009-02-14 6:24 ` Johannes Schindelin
2009-02-14 15:17 ` Jeff King
2009-02-15 23:26 ` Keith Cascio
2009-02-15 23:39 ` Junio C Hamano
2009-02-17 7:24 ` diff.defaultOptions implementation design [was diff.primer] Keith Cascio
2009-02-17 19:56 ` Jeff King
2009-03-17 16:05 ` [PATCH v2 1/2] Introduce config variable "diff.defaultOptions" Keith Cascio
2009-03-20 7:01 ` Jeff King
2009-03-20 17:11 ` Keith Cascio
2009-03-20 19:49 ` Jeff King
2009-03-21 2:00 ` [PATCH/RFC v3] Introduce config variable "diff.defaultoptions" Keith Cascio
2009-03-21 3:15 ` [PATCH] Allow setting default diff options via diff.defaultOptions Johannes Schindelin
2009-04-03 0:04 ` Keith Cascio
2009-04-09 8:45 ` Johannes Schindelin
2009-04-09 8:49 ` Jeff King
2009-04-09 10:43 ` Johannes Schindelin
2009-04-10 8:01 ` Jeff King
2009-04-13 22:37 ` [PATCH] Add the diff option --no-defaults Johannes Schindelin
2009-04-16 8:34 ` Jeff King
2009-04-16 9:25 ` Johannes Schindelin
2009-04-16 9:41 ` Jeff King
2009-04-16 16:52 ` Junio C Hamano
2009-04-16 17:36 ` Johannes Schindelin
2009-04-17 11:54 ` Jeff King
2009-04-17 13:15 ` Johannes Schindelin
2009-04-18 16:41 ` Keith Cascio
2009-04-18 17:40 ` Johannes Schindelin
2009-04-18 20:32 ` Keith Cascio
2009-04-18 21:15 ` Johannes Schindelin
2009-04-09 16:29 ` [PATCH] Allow setting default diff options via diff.defaultOptions Keith Cascio
2009-04-09 0:44 ` Keith Cascio
2009-04-09 8:29 ` Johannes Schindelin
2009-04-09 8:31 ` Jeff King
2009-02-03 18:56 ` [PATCH v2 1/2] Introduce config variable "diff.primer" Jakub Narebski
2009-02-03 19:13 ` Keith Cascio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1233598855-1088-2-git-send-email-keith@cs.ucla.edu \
--to=keith@cs.ucla.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).