Merge branch 'jc/maint-log-grep'

* jc/maint-log-grep:
  log --author/--committer: really match only with name part
  diff --cumulative is a sub-option of --dirstat
  bash completion: Hide more plumbing commands
This commit is contained in:
Junio C Hamano 2008-09-04 22:30:44 -07:00
Родитель 1b23adadf3 a4d7d2c6db
Коммит 80d12c23de
7 изменённых файлов: 131 добавлений и 21 удалений

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

@ -386,7 +386,9 @@ __git_porcelain_commands ()
cat-file) : plumbing;;
check-attr) : plumbing;;
check-ref-format) : plumbing;;
checkout-index) : plumbing;;
commit-tree) : plumbing;;
count-objects) : infrequent;;
cvsexportcommit) : export;;
cvsimport) : import;;
cvsserver) : daemon;;
@ -395,6 +397,7 @@ __git_porcelain_commands ()
diff-index) : plumbing;;
diff-tree) : plumbing;;
fast-import) : import;;
fast-export) : export;;
fsck-objects) : plumbing;;
fetch-pack) : plumbing;;
fmt-merge-msg) : plumbing;;
@ -404,6 +407,10 @@ __git_porcelain_commands ()
index-pack) : plumbing;;
init-db) : deprecated;;
local-fetch) : plumbing;;
lost-found) : infrequent;;
ls-files) : plumbing;;
ls-remote) : plumbing;;
ls-tree) : plumbing;;
mailinfo) : plumbing;;
mailsplit) : plumbing;;
merge-*) : plumbing;;
@ -428,6 +435,7 @@ __git_porcelain_commands ()
runstatus) : plumbing;;
sh-setup) : internal;;
shell) : daemon;;
show-ref) : plumbing;;
send-pack) : plumbing;;
show-index) : plumbing;;
ssh-*) : transport;;
@ -442,6 +450,8 @@ __git_porcelain_commands ()
upload-archive) : plumbing;;
upload-pack) : plumbing;;
write-tree) : plumbing;;
var) : infrequent;;
verify-pack) : infrequent;;
verify-tag) : plumbing;;
*) echo $i;;
esac

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

@ -1078,7 +1078,7 @@ static void show_dirstat(struct diff_options *options)
dir.alloc = 0;
dir.nr = 0;
dir.percent = options->dirstat_percent;
dir.cumulative = options->output_format & DIFF_FORMAT_CUMULATIVE;
dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE);
changed = 0;
for (i = 0; i < q->nr; i++) {
@ -2300,6 +2300,7 @@ 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);
options->context = 3;
options->change = diff_change;
@ -2472,8 +2473,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->output_format |= DIFF_FORMAT_SHORTSTAT;
else if (opt_arg(arg, 'X', "dirstat", &options->dirstat_percent))
options->output_format |= DIFF_FORMAT_DIRSTAT;
else if (!strcmp(arg, "--cumulative"))
options->output_format |= DIFF_FORMAT_CUMULATIVE;
else if (!strcmp(arg, "--cumulative")) {
options->output_format |= DIFF_FORMAT_DIRSTAT;
DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
}
else if (!strcmp(arg, "--check"))
options->output_format |= DIFF_FORMAT_CHECKDIFF;
else if (!strcmp(arg, "--summary"))

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

@ -31,7 +31,6 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_FORMAT_PATCH 0x0010
#define DIFF_FORMAT_SHORTSTAT 0x0020
#define DIFF_FORMAT_DIRSTAT 0x0040
#define DIFF_FORMAT_CUMULATIVE 0x0080
/* These override all above */
#define DIFF_FORMAT_NAME 0x0100
@ -64,6 +63,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_CHECK_FAILED (1 << 16)
#define DIFF_OPT_RELATIVE_NAME (1 << 17)
#define DIFF_OPT_IGNORE_SUBMODULES (1 << 18)
#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19)
#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)

52
grep.c
Просмотреть файл

@ -2,6 +2,19 @@
#include "grep.h"
#include "xdiff-interface.h"
void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
{
struct grep_pat *p = xcalloc(1, sizeof(*p));
p->pattern = pat;
p->origin = "header";
p->no = 0;
p->token = GREP_PATTERN_HEAD;
p->field = field;
*opt->pattern_tail = p;
opt->pattern_tail = &p->next;
p->next = NULL;
}
void append_grep_pattern(struct grep_opt *opt, const char *pat,
const char *origin, int no, enum grep_pat_token t)
{
@ -247,16 +260,53 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match)
}
}
static int strip_timestamp(char *bol, char **eol_p)
{
char *eol = *eol_p;
int ch;
while (bol < --eol) {
if (*eol != '>')
continue;
*eol_p = ++eol;
ch = *eol;
*eol = '\0';
return ch;
}
return 0;
}
static struct {
const char *field;
size_t len;
} header_field[] = {
{ "author ", 7 },
{ "committer ", 10 },
};
static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx)
{
int hit = 0;
int at_true_bol = 1;
int saved_ch = 0;
regmatch_t pmatch[10];
if ((p->token != GREP_PATTERN) &&
((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
return 0;
if (p->token == GREP_PATTERN_HEAD) {
const char *field;
size_t len;
assert(p->field < ARRAY_SIZE(header_field));
field = header_field[p->field].field;
len = header_field[p->field].len;
if (strncmp(bol, field, len))
return 0;
bol += len;
saved_ch = strip_timestamp(bol, &eol);
}
again:
if (!opt->fixed) {
regex_t *exp = &p->regexp;
@ -298,6 +348,8 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
goto again;
}
}
if (p->token == GREP_PATTERN_HEAD && saved_ch)
*eol = saved_ch;
return hit;
}

7
grep.h
Просмотреть файл

@ -17,12 +17,18 @@ enum grep_context {
GREP_CONTEXT_BODY,
};
enum grep_header_field {
GREP_HEADER_AUTHOR = 0,
GREP_HEADER_COMMITTER,
};
struct grep_pat {
struct grep_pat *next;
const char *origin;
int no;
enum grep_pat_token token;
const char *pattern;
enum grep_header_field field;
regex_t regexp;
};
@ -74,6 +80,7 @@ struct grep_opt {
};
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
extern void compile_grep_patterns(struct grep_opt *opt);
extern void free_grep_patterns(struct grep_opt *opt);
extern int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size);

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

@ -953,22 +953,9 @@ static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token
append_grep_pattern(&revs->grep_filter, ptn, "command line", 0, what);
}
static void add_header_grep(struct rev_info *revs, const char *field, const char *pattern)
static void add_header_grep(struct rev_info *revs, enum grep_header_field field, const char *pattern)
{
char *pat;
const char *prefix;
int patlen, fldlen;
fldlen = strlen(field);
patlen = strlen(pattern);
pat = xmalloc(patlen + fldlen + 10);
prefix = ".*";
if (*pattern == '^') {
prefix = "";
pattern++;
}
sprintf(pat, "^%s %s%s", field, prefix, pattern);
add_grep(revs, pat, GREP_PATTERN_HEAD);
append_header_grep_pattern(&revs->grep_filter, field, pattern);
}
static void add_message_grep(struct rev_info *revs, const char *pattern)
@ -1159,9 +1146,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
* Grepping the commit log
*/
else if (!prefixcmp(arg, "--author=")) {
add_header_grep(revs, "author", arg+9);
add_header_grep(revs, GREP_HEADER_AUTHOR, arg+9);
} else if (!prefixcmp(arg, "--committer=")) {
add_header_grep(revs, "committer", arg+12);
add_header_grep(revs, GREP_HEADER_COMMITTER, arg+12);
} else if (!prefixcmp(arg, "--grep=")) {
add_message_grep(revs, arg+7);
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {

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

@ -22,6 +22,7 @@ test_expect_success setup '
mkdir t &&
echo test >t/t &&
git add file x y z t/t &&
test_tick &&
git commit -m initial
'
@ -113,4 +114,54 @@ do
done
test_expect_success 'log grep setup' '
echo a >>file &&
test_tick &&
GIT_AUTHOR_NAME="With * Asterisk" \
GIT_AUTHOR_EMAIL="xyzzy@frotz.com" \
git commit -a -m "second" &&
echo a >>file &&
test_tick &&
git commit -a -m "third"
'
test_expect_success 'log grep (1)' '
git log --author=author --pretty=tformat:%s >actual &&
( echo third ; echo initial ) >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (2)' '
git log --author=" * " -F --pretty=tformat:%s >actual &&
( echo second ) >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (3)' '
git log --author="^A U" --pretty=tformat:%s >actual &&
( echo third ; echo initial ) >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (4)' '
git log --author="frotz\.com>$" --pretty=tformat:%s >actual &&
( echo second ) >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (5)' '
git log --author=Thor -F --grep=Thu --pretty=tformat:%s >actual &&
( echo third ; echo initial ) >expect &&
test_cmp expect actual
'
test_expect_success 'log grep (6)' '
git log --author=-0700 --pretty=tformat:%s >actual &&
>expect &&
test_cmp expect actual
'
test_done