зеркало из https://github.com/microsoft/git.git
Merge branch 'ds/log-exclude-decoration-config'
The "--decorate-refs" and "--decorate-refs-exclude" options "git log" takes have learned a companion configuration variable log.excludeDecoration that sits at the lowest priority in the family. * ds/log-exclude-decoration-config: log: add log.excludeDecoration config option log-tree: make ref_filter_match() a helper method
This commit is contained in:
Коммит
d3fc8dc53a
|
@ -18,6 +18,12 @@ log.decorate::
|
||||||
names are shown. This is the same as the `--decorate` option
|
names are shown. This is the same as the `--decorate` option
|
||||||
of the `git log`.
|
of the `git log`.
|
||||||
|
|
||||||
|
log.excludeDecoration::
|
||||||
|
Exclude the specified patterns from the log decorations. This is
|
||||||
|
similar to the `--decorate-refs-exclude` command-line option, but
|
||||||
|
the config option can be overridden by the `--decorate-refs`
|
||||||
|
option.
|
||||||
|
|
||||||
log.follow::
|
log.follow::
|
||||||
If `true`, `git log` will act as if the `--follow` option was used when
|
If `true`, `git log` will act as if the `--follow` option was used when
|
||||||
a single <path> is given. This has the same limitations as `--follow`,
|
a single <path> is given. This has the same limitations as `--follow`,
|
||||||
|
|
|
@ -43,7 +43,10 @@ OPTIONS
|
||||||
If no `--decorate-refs` is given, pretend as if all refs were
|
If no `--decorate-refs` is given, pretend as if all refs were
|
||||||
included. For each candidate, do not use it for decoration if it
|
included. For each candidate, do not use it for decoration if it
|
||||||
matches any patterns given to `--decorate-refs-exclude` or if it
|
matches any patterns given to `--decorate-refs-exclude` or if it
|
||||||
doesn't match any of the patterns given to `--decorate-refs`.
|
doesn't match any of the patterns given to `--decorate-refs`. The
|
||||||
|
`log.excludeDecoration` config option allows excluding refs from
|
||||||
|
the decorations, but an explicit `--decorate-refs` pattern will
|
||||||
|
override a match in `log.excludeDecoration`.
|
||||||
|
|
||||||
--source::
|
--source::
|
||||||
Print out the ref name given on the command line by which each
|
Print out the ref name given on the command line by which each
|
||||||
|
|
|
@ -166,9 +166,11 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
||||||
int quiet = 0, source = 0, mailmap;
|
int quiet = 0, source = 0, mailmap;
|
||||||
static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
|
static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
|
||||||
static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
|
static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
|
||||||
|
static struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP;
|
||||||
static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
|
static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
|
||||||
struct decoration_filter decoration_filter = {&decorate_refs_include,
|
struct decoration_filter decoration_filter = {&decorate_refs_include,
|
||||||
&decorate_refs_exclude};
|
&decorate_refs_exclude,
|
||||||
|
&decorate_refs_exclude_config};
|
||||||
static struct revision_sources revision_sources;
|
static struct revision_sources revision_sources;
|
||||||
|
|
||||||
const struct option builtin_log_options[] = {
|
const struct option builtin_log_options[] = {
|
||||||
|
@ -239,7 +241,19 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decoration_style) {
|
if (decoration_style) {
|
||||||
|
const struct string_list *config_exclude =
|
||||||
|
repo_config_get_value_multi(the_repository,
|
||||||
|
"log.excludeDecoration");
|
||||||
|
|
||||||
|
if (config_exclude) {
|
||||||
|
struct string_list_item *item;
|
||||||
|
for_each_string_list_item(item, config_exclude)
|
||||||
|
string_list_append(&decorate_refs_exclude_config,
|
||||||
|
item->string);
|
||||||
|
}
|
||||||
|
|
||||||
rev->show_decorations = 1;
|
rev->show_decorations = 1;
|
||||||
|
|
||||||
load_ref_decorations(&decoration_filter, decoration_style);
|
load_ref_decorations(&decoration_filter, decoration_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
log-tree.c
57
log-tree.c
|
@ -81,6 +81,56 @@ const struct name_decoration *get_name_decoration(const struct object *obj)
|
||||||
return lookup_decoration(&name_decoration, obj);
|
return lookup_decoration(&name_decoration, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int match_ref_pattern(const char *refname,
|
||||||
|
const struct string_list_item *item)
|
||||||
|
{
|
||||||
|
int matched = 0;
|
||||||
|
if (item->util == NULL) {
|
||||||
|
if (!wildmatch(item->string, refname, 0))
|
||||||
|
matched = 1;
|
||||||
|
} else {
|
||||||
|
const char *rest;
|
||||||
|
if (skip_prefix(refname, item->string, &rest) &&
|
||||||
|
(!*rest || *rest == '/'))
|
||||||
|
matched = 1;
|
||||||
|
}
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ref_filter_match(const char *refname,
|
||||||
|
const struct decoration_filter *filter)
|
||||||
|
{
|
||||||
|
struct string_list_item *item;
|
||||||
|
const struct string_list *exclude_patterns = filter->exclude_ref_pattern;
|
||||||
|
const struct string_list *include_patterns = filter->include_ref_pattern;
|
||||||
|
const struct string_list *exclude_patterns_config =
|
||||||
|
filter->exclude_ref_config_pattern;
|
||||||
|
|
||||||
|
if (exclude_patterns && exclude_patterns->nr) {
|
||||||
|
for_each_string_list_item(item, exclude_patterns) {
|
||||||
|
if (match_ref_pattern(refname, item))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (include_patterns && include_patterns->nr) {
|
||||||
|
for_each_string_list_item(item, include_patterns) {
|
||||||
|
if (match_ref_pattern(refname, item))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exclude_patterns_config && exclude_patterns_config->nr) {
|
||||||
|
for_each_string_list_item(item, exclude_patterns_config) {
|
||||||
|
if (match_ref_pattern(refname, item))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int add_ref_decoration(const char *refname, const struct object_id *oid,
|
static int add_ref_decoration(const char *refname, const struct object_id *oid,
|
||||||
int flags, void *cb_data)
|
int flags, void *cb_data)
|
||||||
{
|
{
|
||||||
|
@ -88,9 +138,7 @@ static int add_ref_decoration(const char *refname, const struct object_id *oid,
|
||||||
enum decoration_type type = DECORATION_NONE;
|
enum decoration_type type = DECORATION_NONE;
|
||||||
struct decoration_filter *filter = (struct decoration_filter *)cb_data;
|
struct decoration_filter *filter = (struct decoration_filter *)cb_data;
|
||||||
|
|
||||||
if (filter && !ref_filter_match(refname,
|
if (filter && !ref_filter_match(refname, filter))
|
||||||
filter->include_ref_pattern,
|
|
||||||
filter->exclude_ref_pattern))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (starts_with(refname, git_replace_ref_base)) {
|
if (starts_with(refname, git_replace_ref_base)) {
|
||||||
|
@ -155,6 +203,9 @@ void load_ref_decorations(struct decoration_filter *filter, int flags)
|
||||||
for_each_string_list_item(item, filter->include_ref_pattern) {
|
for_each_string_list_item(item, filter->include_ref_pattern) {
|
||||||
normalize_glob_ref(item, NULL, item->string);
|
normalize_glob_ref(item, NULL, item->string);
|
||||||
}
|
}
|
||||||
|
for_each_string_list_item(item, filter->exclude_ref_config_pattern) {
|
||||||
|
normalize_glob_ref(item, NULL, item->string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
decoration_loaded = 1;
|
decoration_loaded = 1;
|
||||||
decoration_flags = flags;
|
decoration_flags = flags;
|
||||||
|
|
|
@ -8,7 +8,9 @@ struct log_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct decoration_filter {
|
struct decoration_filter {
|
||||||
struct string_list *include_ref_pattern, *exclude_ref_pattern;
|
struct string_list *include_ref_pattern;
|
||||||
|
struct string_list *exclude_ref_pattern;
|
||||||
|
struct string_list *exclude_ref_config_pattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
int parse_decorate_color_config(const char *var, const char *slot_name, const char *value);
|
int parse_decorate_color_config(const char *var, const char *slot_name, const char *value);
|
||||||
|
|
44
refs.c
44
refs.c
|
@ -321,50 +321,6 @@ int ref_exists(const char *refname)
|
||||||
return refs_ref_exists(get_main_ref_store(the_repository), refname);
|
return refs_ref_exists(get_main_ref_store(the_repository), refname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_ref_pattern(const char *refname,
|
|
||||||
const struct string_list_item *item)
|
|
||||||
{
|
|
||||||
int matched = 0;
|
|
||||||
if (item->util == NULL) {
|
|
||||||
if (!wildmatch(item->string, refname, 0))
|
|
||||||
matched = 1;
|
|
||||||
} else {
|
|
||||||
const char *rest;
|
|
||||||
if (skip_prefix(refname, item->string, &rest) &&
|
|
||||||
(!*rest || *rest == '/'))
|
|
||||||
matched = 1;
|
|
||||||
}
|
|
||||||
return matched;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ref_filter_match(const char *refname,
|
|
||||||
const struct string_list *include_patterns,
|
|
||||||
const struct string_list *exclude_patterns)
|
|
||||||
{
|
|
||||||
struct string_list_item *item;
|
|
||||||
|
|
||||||
if (exclude_patterns && exclude_patterns->nr) {
|
|
||||||
for_each_string_list_item(item, exclude_patterns) {
|
|
||||||
if (match_ref_pattern(refname, item))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (include_patterns && include_patterns->nr) {
|
|
||||||
int found = 0;
|
|
||||||
for_each_string_list_item(item, include_patterns) {
|
|
||||||
if (match_ref_pattern(refname, item)) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int filter_refs(const char *refname, const struct object_id *oid,
|
static int filter_refs(const char *refname, const struct object_id *oid,
|
||||||
int flags, void *data)
|
int flags, void *data)
|
||||||
{
|
{
|
||||||
|
|
12
refs.h
12
refs.h
|
@ -361,18 +361,6 @@ int for_each_rawref(each_ref_fn fn, void *cb_data);
|
||||||
void normalize_glob_ref(struct string_list_item *item, const char *prefix,
|
void normalize_glob_ref(struct string_list_item *item, const char *prefix,
|
||||||
const char *pattern);
|
const char *pattern);
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns 0 if refname matches any of the exclude_patterns, or if it doesn't
|
|
||||||
* match any of the include_patterns. Returns 1 otherwise.
|
|
||||||
*
|
|
||||||
* If pattern list is NULL or empty, matching against that list is skipped.
|
|
||||||
* This has the effect of matching everything by default, unless the user
|
|
||||||
* specifies rules otherwise.
|
|
||||||
*/
|
|
||||||
int ref_filter_match(const char *refname,
|
|
||||||
const struct string_list *include_patterns,
|
|
||||||
const struct string_list *exclude_patterns);
|
|
||||||
|
|
||||||
static inline const char *has_glob_specials(const char *pattern)
|
static inline const char *has_glob_specials(const char *pattern)
|
||||||
{
|
{
|
||||||
return strpbrk(pattern, "?*[");
|
return strpbrk(pattern, "?*[");
|
||||||
|
|
|
@ -742,8 +742,24 @@ test_expect_success 'decorate-refs with glob' '
|
||||||
octopus-a (octopus-a)
|
octopus-a (octopus-a)
|
||||||
reach
|
reach
|
||||||
EOF
|
EOF
|
||||||
|
cat >expect.no-decorate <<-\EOF &&
|
||||||
|
Merge-tag-reach
|
||||||
|
Merge-tags-octopus-a-and-octopus-b
|
||||||
|
seventh
|
||||||
|
octopus-b
|
||||||
|
octopus-a
|
||||||
|
reach
|
||||||
|
EOF
|
||||||
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
--decorate-refs="heads/octopus*" >actual &&
|
--decorate-refs="heads/octopus*" >actual &&
|
||||||
|
test_cmp expect.decorate actual &&
|
||||||
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
|
--decorate-refs-exclude="heads/octopus*" \
|
||||||
|
--decorate-refs="heads/octopus*" >actual &&
|
||||||
|
test_cmp expect.no-decorate actual &&
|
||||||
|
git -c log.excludeDecoration="heads/octopus*" log \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
|
--decorate-refs="heads/octopus*" >actual &&
|
||||||
test_cmp expect.decorate actual
|
test_cmp expect.decorate actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -787,6 +803,9 @@ test_expect_success 'decorate-refs-exclude with glob' '
|
||||||
EOF
|
EOF
|
||||||
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
--decorate-refs-exclude="heads/octopus*" >actual &&
|
--decorate-refs-exclude="heads/octopus*" >actual &&
|
||||||
|
test_cmp expect.decorate actual &&
|
||||||
|
git -c log.excludeDecoration="heads/octopus*" log \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" >actual &&
|
||||||
test_cmp expect.decorate actual
|
test_cmp expect.decorate actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -801,6 +820,9 @@ test_expect_success 'decorate-refs-exclude without globs' '
|
||||||
EOF
|
EOF
|
||||||
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
--decorate-refs-exclude="tags/reach" >actual &&
|
--decorate-refs-exclude="tags/reach" >actual &&
|
||||||
|
test_cmp expect.decorate actual &&
|
||||||
|
git -c log.excludeDecoration="tags/reach" log \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" >actual &&
|
||||||
test_cmp expect.decorate actual
|
test_cmp expect.decorate actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -816,11 +838,19 @@ test_expect_success 'multiple decorate-refs-exclude' '
|
||||||
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
--decorate-refs-exclude="heads/octopus*" \
|
--decorate-refs-exclude="heads/octopus*" \
|
||||||
--decorate-refs-exclude="tags/reach" >actual &&
|
--decorate-refs-exclude="tags/reach" >actual &&
|
||||||
|
test_cmp expect.decorate actual &&
|
||||||
|
git -c log.excludeDecoration="heads/octopus*" \
|
||||||
|
-c log.excludeDecoration="tags/reach" log \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" >actual &&
|
||||||
|
test_cmp expect.decorate actual &&
|
||||||
|
git -c log.excludeDecoration="heads/octopus*" log \
|
||||||
|
--decorate-refs-exclude="tags/reach" \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" >actual &&
|
||||||
test_cmp expect.decorate actual
|
test_cmp expect.decorate actual
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'decorate-refs and decorate-refs-exclude' '
|
test_expect_success 'decorate-refs and decorate-refs-exclude' '
|
||||||
cat >expect.decorate <<-\EOF &&
|
cat >expect.no-decorate <<-\EOF &&
|
||||||
Merge-tag-reach (master)
|
Merge-tag-reach (master)
|
||||||
Merge-tags-octopus-a-and-octopus-b
|
Merge-tags-octopus-a-and-octopus-b
|
||||||
seventh
|
seventh
|
||||||
|
@ -831,6 +861,21 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' '
|
||||||
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
--decorate-refs="heads/*" \
|
--decorate-refs="heads/*" \
|
||||||
--decorate-refs-exclude="heads/oc*" >actual &&
|
--decorate-refs-exclude="heads/oc*" >actual &&
|
||||||
|
test_cmp expect.no-decorate actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'deocrate-refs and log.excludeDecoration' '
|
||||||
|
cat >expect.decorate <<-\EOF &&
|
||||||
|
Merge-tag-reach (master)
|
||||||
|
Merge-tags-octopus-a-and-octopus-b
|
||||||
|
seventh
|
||||||
|
octopus-b (octopus-b)
|
||||||
|
octopus-a (octopus-a)
|
||||||
|
reach (reach)
|
||||||
|
EOF
|
||||||
|
git -c log.excludeDecoration="heads/oc*" log \
|
||||||
|
--decorate-refs="heads/*" \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" >actual &&
|
||||||
test_cmp expect.decorate actual
|
test_cmp expect.decorate actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -846,6 +891,10 @@ test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
|
||||||
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
git log -n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
--decorate-refs-exclude="*octopus*" \
|
--decorate-refs-exclude="*octopus*" \
|
||||||
--simplify-by-decoration >actual &&
|
--simplify-by-decoration >actual &&
|
||||||
|
test_cmp expect.decorate actual &&
|
||||||
|
git -c log.excludeDecoration="*octopus*" log \
|
||||||
|
-n6 --decorate=short --pretty="tformat:%f%d" \
|
||||||
|
--simplify-by-decoration >actual &&
|
||||||
test_cmp expect.decorate actual
|
test_cmp expect.decorate actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче