Support showing notes from more than one notes tree
With this patch, you can set notes.displayRef to a glob that points at your favourite notes refs, e.g., [notes] displayRef = refs/notes/* Then git-log and friends will show notes from all trees. Thanks to Junio C Hamano for lots of feedback, which greatly influenced the design of the entire series and this commit in particular. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Acked-by: Johan Herland <johan@herland.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
6ceeaee7ea
commit
894a9d333e
@@ -500,10 +500,12 @@ check that makes sure that existing object files will not get overwritten.
|
|||||||
core.notesRef::
|
core.notesRef::
|
||||||
When showing commit messages, also show notes which are stored in
|
When showing commit messages, also show notes which are stored in
|
||||||
the given ref. This ref is expected to contain files named
|
the given ref. This ref is expected to contain files named
|
||||||
after the full SHA-1 of the commit they annotate.
|
after the full SHA-1 of the commit they annotate. The ref
|
||||||
|
must be fully qualified.
|
||||||
+
|
+
|
||||||
If such a file exists in the given ref, the referenced blob is read, and
|
If such a file exists in the given ref, the referenced blob is read, and
|
||||||
appended to the commit message, separated by a "Notes:" line. If the
|
appended to the commit message, separated by a "Notes (<refname>):"
|
||||||
|
line (shortened to "Notes:" in the case of "refs/notes/commits"). If the
|
||||||
given ref itself does not exist, it is not an error, but means that no
|
given ref itself does not exist, it is not an error, but means that no
|
||||||
notes should be printed.
|
notes should be printed.
|
||||||
+
|
+
|
||||||
@@ -1286,6 +1288,23 @@ mergetool.keepTemporaries::
|
|||||||
mergetool.prompt::
|
mergetool.prompt::
|
||||||
Prompt before each invocation of the merge resolution program.
|
Prompt before each invocation of the merge resolution program.
|
||||||
|
|
||||||
|
notes.displayRef::
|
||||||
|
The (fully qualified) refname from which to show notes when
|
||||||
|
showing commit messages. The value of this variable can be set
|
||||||
|
to a glob, in which case notes from all matching refs will be
|
||||||
|
shown. You may also specify this configuration variable
|
||||||
|
several times. A warning will be issued for refs that do not
|
||||||
|
exist, but a glob that does not match any refs is silently
|
||||||
|
ignored.
|
||||||
|
+
|
||||||
|
This setting can be overridden with the `GIT_NOTES_DISPLAY_REF`
|
||||||
|
environment variable, which must be a colon separated list of refs or
|
||||||
|
globs.
|
||||||
|
+
|
||||||
|
The effective value of "core.notesRef" (possibly overridden by
|
||||||
|
GIT_NOTES_REF) is also implicitly added to the list of refs to be
|
||||||
|
displayed.
|
||||||
|
|
||||||
pack.window::
|
pack.window::
|
||||||
The size of the window used by linkgit:git-pack-objects[1] when no
|
The size of the window used by linkgit:git-pack-objects[1] when no
|
||||||
window size is given on the command line. Defaults to 10.
|
window size is given on the command line. Defaults to 10.
|
||||||
|
|||||||
@@ -27,12 +27,13 @@ A typical use of notes is to extend a commit message without having
|
|||||||
to change the commit itself. Such commit notes can be shown by `git log`
|
to change the commit itself. Such commit notes can be shown by `git log`
|
||||||
along with the original commit message. To discern these notes from the
|
along with the original commit message. To discern these notes from the
|
||||||
message stored in the commit object, the notes are indented like the
|
message stored in the commit object, the notes are indented like the
|
||||||
message, after an unindented line saying "Notes:".
|
message, after an unindented line saying "Notes (<refname>):" (or
|
||||||
|
"Notes:" for the default setting).
|
||||||
|
|
||||||
To disable notes, you have to set the config variable core.notesRef to
|
This command always manipulates the notes specified in "core.notesRef"
|
||||||
the empty string. Alternatively, you can set it to a different ref,
|
(see linkgit:git-config[1]), which can be overridden by GIT_NOTES_REF.
|
||||||
something like "refs/notes/bugzilla". This setting can be overridden
|
To change which notes are shown by 'git-log', see the
|
||||||
by the environment variable "GIT_NOTES_REF".
|
"notes.displayRef" configuration.
|
||||||
|
|
||||||
|
|
||||||
SUBCOMMANDS
|
SUBCOMMANDS
|
||||||
|
|||||||
@@ -30,9 +30,18 @@ people using 80-column terminals.
|
|||||||
defaults to UTF-8.
|
defaults to UTF-8.
|
||||||
|
|
||||||
--no-notes::
|
--no-notes::
|
||||||
--show-notes::
|
--show-notes[=<ref>]::
|
||||||
Show the notes (see linkgit:git-notes[1]) that annotate the
|
Show the notes (see linkgit:git-notes[1]) that annotate the
|
||||||
commit, when showing the commit log message. This is the default
|
commit, when showing the commit log message. This is the default
|
||||||
for `git log`, `git show` and `git whatchanged` commands when
|
for `git log`, `git show` and `git whatchanged` commands when
|
||||||
there is no `--pretty`, `--format` nor `--oneline` option is
|
there is no `--pretty`, `--format` nor `--oneline` option is
|
||||||
given on the command line.
|
given on the command line.
|
||||||
|
+
|
||||||
|
With an optional argument, add this ref to the list of notes. The ref
|
||||||
|
is taken to be in `refs/notes/` if it is not qualified.
|
||||||
|
|
||||||
|
--[no-]standard-notes::
|
||||||
|
Enable or disable populating the notes ref list from the
|
||||||
|
'core.notesRef' and 'notes.displayRef' variables (or
|
||||||
|
corresponding environment overrides). Enabled by default.
|
||||||
|
See linkgit:git-config[1].
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
|||||||
|
|
||||||
if (!rev->show_notes_given && !rev->pretty_given)
|
if (!rev->show_notes_given && !rev->pretty_given)
|
||||||
rev->show_notes = 1;
|
rev->show_notes = 1;
|
||||||
|
if (rev->show_notes)
|
||||||
|
init_display_notes(&rev->notes_opt);
|
||||||
|
|
||||||
if (rev->diffopt.pickaxe || rev->diffopt.filter)
|
if (rev->diffopt.pickaxe || rev->diffopt.filter)
|
||||||
rev->always_show_header = 0;
|
rev->always_show_header = 0;
|
||||||
@@ -1059,6 +1061,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
|
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
|
||||||
DIFF_OPT_SET(&rev.diffopt, BINARY);
|
DIFF_OPT_SET(&rev.diffopt, BINARY);
|
||||||
|
|
||||||
|
if (rev.show_notes)
|
||||||
|
init_display_notes(&rev.notes_opt);
|
||||||
|
|
||||||
if (!use_stdout)
|
if (!use_stdout)
|
||||||
output_directory = set_outdir(prefix, output_directory);
|
output_directory = set_outdir(prefix, output_directory);
|
||||||
|
|
||||||
|
|||||||
1
cache.h
1
cache.h
@@ -385,6 +385,7 @@ static inline enum object_type object_type(unsigned int mode)
|
|||||||
#define ATTRIBUTE_MACRO_PREFIX "[attr]"
|
#define ATTRIBUTE_MACRO_PREFIX "[attr]"
|
||||||
#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
|
#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
|
||||||
#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
|
#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
|
||||||
|
#define GIT_NOTES_DISPLAY_REF_ENVIRONMENT "GIT_NOTES_DISPLAY_REF"
|
||||||
|
|
||||||
extern int is_bare_repository_cfg;
|
extern int is_bare_repository_cfg;
|
||||||
extern int is_bare_repository(void);
|
extern int is_bare_repository(void);
|
||||||
|
|||||||
169
notes.c
169
notes.c
@@ -5,6 +5,8 @@
|
|||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "tree-walk.h"
|
#include "tree-walk.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
#include "refs.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use a non-balancing simple 16-tree structure with struct int_node as
|
* Use a non-balancing simple 16-tree structure with struct int_node as
|
||||||
@@ -68,6 +70,9 @@ struct non_note {
|
|||||||
|
|
||||||
struct notes_tree default_notes_tree;
|
struct notes_tree default_notes_tree;
|
||||||
|
|
||||||
|
static struct string_list display_notes_refs;
|
||||||
|
static struct notes_tree **display_notes_trees;
|
||||||
|
|
||||||
static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
|
static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
|
||||||
struct int_node *node, unsigned int n);
|
struct int_node *node, unsigned int n);
|
||||||
|
|
||||||
@@ -828,6 +833,83 @@ int combine_notes_ignore(unsigned char *cur_sha1,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int string_list_add_one_ref(const char *path, const unsigned char *sha1,
|
||||||
|
int flag, void *cb)
|
||||||
|
{
|
||||||
|
struct string_list *refs = cb;
|
||||||
|
if (!unsorted_string_list_has_string(refs, path))
|
||||||
|
string_list_append(path, refs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_list_add_refs_by_glob(struct string_list *list, const char *glob)
|
||||||
|
{
|
||||||
|
if (has_glob_specials(glob)) {
|
||||||
|
for_each_glob_ref(string_list_add_one_ref, glob, list);
|
||||||
|
} else {
|
||||||
|
unsigned char sha1[20];
|
||||||
|
if (get_sha1(glob, sha1))
|
||||||
|
warning("notes ref %s is invalid", glob);
|
||||||
|
if (!unsorted_string_list_has_string(list, glob))
|
||||||
|
string_list_append(glob, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_list_add_refs_from_colon_sep(struct string_list *list,
|
||||||
|
const char *globs)
|
||||||
|
{
|
||||||
|
struct strbuf globbuf = STRBUF_INIT;
|
||||||
|
struct strbuf **split;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
strbuf_addstr(&globbuf, globs);
|
||||||
|
split = strbuf_split(&globbuf, ':');
|
||||||
|
|
||||||
|
for (i = 0; split[i]; i++) {
|
||||||
|
if (!split[i]->len)
|
||||||
|
continue;
|
||||||
|
if (split[i]->buf[split[i]->len-1] == ':')
|
||||||
|
strbuf_setlen(split[i], split[i]->len-1);
|
||||||
|
string_list_add_refs_by_glob(list, split[i]->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf_list_free(split);
|
||||||
|
strbuf_release(&globbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int string_list_add_refs_from_list(struct string_list_item *item,
|
||||||
|
void *cb)
|
||||||
|
{
|
||||||
|
struct string_list *list = cb;
|
||||||
|
string_list_add_refs_by_glob(list, item->string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int notes_display_config(const char *k, const char *v, void *cb)
|
||||||
|
{
|
||||||
|
int *load_refs = cb;
|
||||||
|
|
||||||
|
if (*load_refs && !strcmp(k, "notes.displayref")) {
|
||||||
|
if (!v)
|
||||||
|
config_error_nonbool(k);
|
||||||
|
string_list_add_refs_by_glob(&display_notes_refs, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *default_notes_ref(void)
|
||||||
|
{
|
||||||
|
const char *notes_ref = NULL;
|
||||||
|
if (!notes_ref)
|
||||||
|
notes_ref = getenv(GIT_NOTES_REF_ENVIRONMENT);
|
||||||
|
if (!notes_ref)
|
||||||
|
notes_ref = notes_ref_name; /* value of core.notesRef config */
|
||||||
|
if (!notes_ref)
|
||||||
|
notes_ref = GIT_NOTES_DEFAULT_REF;
|
||||||
|
return notes_ref;
|
||||||
|
}
|
||||||
|
|
||||||
void init_notes(struct notes_tree *t, const char *notes_ref,
|
void init_notes(struct notes_tree *t, const char *notes_ref,
|
||||||
combine_notes_fn combine_notes, int flags)
|
combine_notes_fn combine_notes, int flags)
|
||||||
{
|
{
|
||||||
@@ -840,11 +922,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
|
|||||||
assert(!t->initialized);
|
assert(!t->initialized);
|
||||||
|
|
||||||
if (!notes_ref)
|
if (!notes_ref)
|
||||||
notes_ref = getenv(GIT_NOTES_REF_ENVIRONMENT);
|
notes_ref = default_notes_ref();
|
||||||
if (!notes_ref)
|
|
||||||
notes_ref = notes_ref_name; /* value of core.notesRef config */
|
|
||||||
if (!notes_ref)
|
|
||||||
notes_ref = GIT_NOTES_DEFAULT_REF;
|
|
||||||
|
|
||||||
if (!combine_notes)
|
if (!combine_notes)
|
||||||
combine_notes = combine_notes_concatenate;
|
combine_notes = combine_notes_concatenate;
|
||||||
@@ -868,6 +946,63 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
|
|||||||
load_subtree(t, &root_tree, t->root, 0);
|
load_subtree(t, &root_tree, t->root, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct load_notes_cb_data {
|
||||||
|
int counter;
|
||||||
|
struct notes_tree **trees;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int load_one_display_note_ref(struct string_list_item *item,
|
||||||
|
void *cb_data)
|
||||||
|
{
|
||||||
|
struct load_notes_cb_data *c = cb_data;
|
||||||
|
struct notes_tree *t = xcalloc(1, sizeof(struct notes_tree));
|
||||||
|
init_notes(t, item->string, combine_notes_ignore, 0);
|
||||||
|
c->trees[c->counter++] = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct notes_tree **load_notes_trees(struct string_list *refs)
|
||||||
|
{
|
||||||
|
struct notes_tree **trees;
|
||||||
|
struct load_notes_cb_data cb_data;
|
||||||
|
trees = xmalloc((refs->nr+1) * sizeof(struct notes_tree *));
|
||||||
|
cb_data.counter = 0;
|
||||||
|
cb_data.trees = trees;
|
||||||
|
for_each_string_list(load_one_display_note_ref, refs, &cb_data);
|
||||||
|
trees[cb_data.counter] = NULL;
|
||||||
|
return trees;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_display_notes(struct display_notes_opt *opt)
|
||||||
|
{
|
||||||
|
char *display_ref_env;
|
||||||
|
int load_config_refs = 0;
|
||||||
|
display_notes_refs.strdup_strings = 1;
|
||||||
|
|
||||||
|
assert(!display_notes_trees);
|
||||||
|
|
||||||
|
if (!opt || !opt->suppress_default_notes) {
|
||||||
|
string_list_append(default_notes_ref(), &display_notes_refs);
|
||||||
|
display_ref_env = getenv(GIT_NOTES_DISPLAY_REF_ENVIRONMENT);
|
||||||
|
if (display_ref_env) {
|
||||||
|
string_list_add_refs_from_colon_sep(&display_notes_refs,
|
||||||
|
display_ref_env);
|
||||||
|
load_config_refs = 0;
|
||||||
|
} else
|
||||||
|
load_config_refs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_config(notes_display_config, &load_config_refs);
|
||||||
|
|
||||||
|
if (opt && opt->extra_notes_refs)
|
||||||
|
for_each_string_list(string_list_add_refs_from_list,
|
||||||
|
opt->extra_notes_refs,
|
||||||
|
&display_notes_refs);
|
||||||
|
|
||||||
|
display_notes_trees = load_notes_trees(&display_notes_refs);
|
||||||
|
string_list_clear(&display_notes_refs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void add_note(struct notes_tree *t, const unsigned char *object_sha1,
|
void add_note(struct notes_tree *t, const unsigned char *object_sha1,
|
||||||
const unsigned char *note_sha1, combine_notes_fn combine_notes)
|
const unsigned char *note_sha1, combine_notes_fn combine_notes)
|
||||||
{
|
{
|
||||||
@@ -1016,8 +1151,18 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
|
|||||||
if (msglen && msg[msglen - 1] == '\n')
|
if (msglen && msg[msglen - 1] == '\n')
|
||||||
msglen--;
|
msglen--;
|
||||||
|
|
||||||
if (flags & NOTES_SHOW_HEADER)
|
if (flags & NOTES_SHOW_HEADER) {
|
||||||
strbuf_addstr(sb, "\nNotes:\n");
|
const char *ref = t->ref;
|
||||||
|
if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) {
|
||||||
|
strbuf_addstr(sb, "\nNotes:\n");
|
||||||
|
} else {
|
||||||
|
if (!prefixcmp(ref, "refs/"))
|
||||||
|
ref += 5;
|
||||||
|
if (!prefixcmp(ref, "notes/"))
|
||||||
|
ref += 6;
|
||||||
|
strbuf_addf(sb, "\nNotes (%s):\n", ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
|
for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
|
||||||
linelen = strchrnul(msg_p, '\n') - msg_p;
|
linelen = strchrnul(msg_p, '\n') - msg_p;
|
||||||
@@ -1030,3 +1175,13 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
|
|||||||
|
|
||||||
free(msg);
|
free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void format_display_notes(const unsigned char *object_sha1,
|
||||||
|
struct strbuf *sb, const char *output_encoding, int flags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
assert(display_notes_trees);
|
||||||
|
for (i = 0; display_notes_trees[i]; i++)
|
||||||
|
format_note(display_notes_trees[i], object_sha1, sb,
|
||||||
|
output_encoding, flags);
|
||||||
|
}
|
||||||
|
|||||||
55
notes.h
55
notes.h
@@ -198,4 +198,59 @@ void free_notes(struct notes_tree *t);
|
|||||||
void format_note(struct notes_tree *t, const unsigned char *object_sha1,
|
void format_note(struct notes_tree *t, const unsigned char *object_sha1,
|
||||||
struct strbuf *sb, const char *output_encoding, int flags);
|
struct strbuf *sb, const char *output_encoding, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
struct string_list;
|
||||||
|
|
||||||
|
struct display_notes_opt {
|
||||||
|
int suppress_default_notes:1;
|
||||||
|
struct string_list *extra_notes_refs;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the notes machinery for displaying several notes trees.
|
||||||
|
*
|
||||||
|
* If 'opt' is not NULL, then it specifies additional settings for the
|
||||||
|
* displaying:
|
||||||
|
*
|
||||||
|
* - suppress_default_notes indicates that the notes from
|
||||||
|
* core.notesRef and notes.displayRef should not be loaded.
|
||||||
|
*
|
||||||
|
* - extra_notes_refs may contain a list of globs (in the same style
|
||||||
|
* as notes.displayRef) where notes should be loaded from.
|
||||||
|
*/
|
||||||
|
void init_display_notes(struct display_notes_opt *opt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append notes for the given 'object_sha1' from all trees set up by
|
||||||
|
* init_display_notes() to 'sb'. The 'flags' are a bitwise
|
||||||
|
* combination of
|
||||||
|
*
|
||||||
|
* - NOTES_SHOW_HEADER: add a 'Notes (refname):' header
|
||||||
|
*
|
||||||
|
* - NOTES_INDENT: indent the notes by 4 places
|
||||||
|
*
|
||||||
|
* You *must* call init_display_notes() before using this function.
|
||||||
|
*/
|
||||||
|
void format_display_notes(const unsigned char *object_sha1,
|
||||||
|
struct strbuf *sb, const char *output_encoding, int flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the notes tree from each ref listed in 'refs'. The output is
|
||||||
|
* an array of notes_tree*, terminated by a NULL.
|
||||||
|
*/
|
||||||
|
struct notes_tree **load_notes_trees(struct string_list *refs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add all refs that match 'glob' to the 'list'.
|
||||||
|
*/
|
||||||
|
void string_list_add_refs_by_glob(struct string_list *list, const char *glob);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add all refs from a colon-separated glob list 'globs' to the end of
|
||||||
|
* 'list'. Empty components are ignored. This helper is used to
|
||||||
|
* parse GIT_NOTES_DISPLAY_REF style environment variables.
|
||||||
|
*/
|
||||||
|
void string_list_add_refs_from_colon_sep(struct string_list *list,
|
||||||
|
const char *globs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
6
pretty.c
6
pretty.c
@@ -775,7 +775,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
|
|||||||
}
|
}
|
||||||
return 0; /* unknown %g placeholder */
|
return 0; /* unknown %g placeholder */
|
||||||
case 'N':
|
case 'N':
|
||||||
format_note(NULL, commit->object.sha1, sb,
|
format_display_notes(commit->object.sha1, sb,
|
||||||
git_log_output_encoding ? git_log_output_encoding
|
git_log_output_encoding ? git_log_output_encoding
|
||||||
: git_commit_encoding, 0);
|
: git_commit_encoding, 0);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1096,8 +1096,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
|
|||||||
strbuf_addch(sb, '\n');
|
strbuf_addch(sb, '\n');
|
||||||
|
|
||||||
if (context->show_notes)
|
if (context->show_notes)
|
||||||
format_note(NULL, commit->object.sha1, sb, encoding,
|
format_display_notes(commit->object.sha1, sb, encoding,
|
||||||
NOTES_SHOW_HEADER | NOTES_INDENT);
|
NOTES_SHOW_HEADER | NOTES_INDENT);
|
||||||
|
|
||||||
free(reencoded);
|
free(reencoded);
|
||||||
}
|
}
|
||||||
|
|||||||
6
refs.c
6
refs.c
@@ -695,7 +695,6 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
|
|||||||
{
|
{
|
||||||
struct strbuf real_pattern = STRBUF_INIT;
|
struct strbuf real_pattern = STRBUF_INIT;
|
||||||
struct ref_filter filter;
|
struct ref_filter filter;
|
||||||
const char *has_glob_specials;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!prefix && prefixcmp(pattern, "refs/"))
|
if (!prefix && prefixcmp(pattern, "refs/"))
|
||||||
@@ -704,9 +703,8 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
|
|||||||
strbuf_addstr(&real_pattern, prefix);
|
strbuf_addstr(&real_pattern, prefix);
|
||||||
strbuf_addstr(&real_pattern, pattern);
|
strbuf_addstr(&real_pattern, pattern);
|
||||||
|
|
||||||
has_glob_specials = strpbrk(pattern, "?*[");
|
if (!has_glob_specials(pattern)) {
|
||||||
if (!has_glob_specials) {
|
/* Append implied '/' '*' if not present. */
|
||||||
/* Append impiled '/' '*' if not present. */
|
|
||||||
if (real_pattern.buf[real_pattern.len - 1] != '/')
|
if (real_pattern.buf[real_pattern.len - 1] != '/')
|
||||||
strbuf_addch(&real_pattern, '/');
|
strbuf_addch(&real_pattern, '/');
|
||||||
/* No need to check for '*', there is none. */
|
/* No need to check for '*', there is none. */
|
||||||
|
|||||||
5
refs.h
5
refs.h
@@ -28,6 +28,11 @@ extern int for_each_replace_ref(each_ref_fn, void *);
|
|||||||
extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);
|
extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);
|
||||||
extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);
|
extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);
|
||||||
|
|
||||||
|
static inline const char *has_glob_specials(const char *pattern)
|
||||||
|
{
|
||||||
|
return strpbrk(pattern, "?*[");
|
||||||
|
}
|
||||||
|
|
||||||
/* can be used to learn about broken ref and symref */
|
/* can be used to learn about broken ref and symref */
|
||||||
extern int for_each_rawref(each_ref_fn, void *);
|
extern int for_each_rawref(each_ref_fn, void *);
|
||||||
|
|
||||||
|
|||||||
21
revision.c
21
revision.c
@@ -12,6 +12,7 @@
|
|||||||
#include "patch-ids.h"
|
#include "patch-ids.h"
|
||||||
#include "decorate.h"
|
#include "decorate.h"
|
||||||
#include "log-tree.h"
|
#include "log-tree.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
|
||||||
volatile show_early_output_fn_t show_early_output;
|
volatile show_early_output_fn_t show_early_output;
|
||||||
|
|
||||||
@@ -1176,9 +1177,29 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
|||||||
} else if (!strcmp(arg, "--show-notes")) {
|
} else if (!strcmp(arg, "--show-notes")) {
|
||||||
revs->show_notes = 1;
|
revs->show_notes = 1;
|
||||||
revs->show_notes_given = 1;
|
revs->show_notes_given = 1;
|
||||||
|
} else if (!prefixcmp(arg, "--show-notes=")) {
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
revs->show_notes = 1;
|
||||||
|
revs->show_notes_given = 1;
|
||||||
|
if (!revs->notes_opt.extra_notes_refs)
|
||||||
|
revs->notes_opt.extra_notes_refs = xcalloc(1, sizeof(struct string_list));
|
||||||
|
if (!prefixcmp(arg+13, "refs/"))
|
||||||
|
/* happy */;
|
||||||
|
else if (!prefixcmp(arg+13, "notes/"))
|
||||||
|
strbuf_addstr(&buf, "refs/");
|
||||||
|
else
|
||||||
|
strbuf_addstr(&buf, "refs/notes/");
|
||||||
|
strbuf_addstr(&buf, arg+13);
|
||||||
|
string_list_append(strbuf_detach(&buf, NULL),
|
||||||
|
revs->notes_opt.extra_notes_refs);
|
||||||
} else if (!strcmp(arg, "--no-notes")) {
|
} else if (!strcmp(arg, "--no-notes")) {
|
||||||
revs->show_notes = 0;
|
revs->show_notes = 0;
|
||||||
revs->show_notes_given = 1;
|
revs->show_notes_given = 1;
|
||||||
|
} else if (!strcmp(arg, "--standard-notes")) {
|
||||||
|
revs->show_notes_given = 1;
|
||||||
|
revs->notes_opt.suppress_default_notes = 0;
|
||||||
|
} else if (!strcmp(arg, "--no-standard-notes")) {
|
||||||
|
revs->notes_opt.suppress_default_notes = 1;
|
||||||
} else if (!strcmp(arg, "--oneline")) {
|
} else if (!strcmp(arg, "--oneline")) {
|
||||||
revs->verbose_header = 1;
|
revs->verbose_header = 1;
|
||||||
get_commit_format("oneline", revs);
|
get_commit_format("oneline", revs);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
#include "grep.h"
|
#include "grep.h"
|
||||||
|
#include "notes.h"
|
||||||
|
|
||||||
#define SEEN (1u<<0)
|
#define SEEN (1u<<0)
|
||||||
#define UNINTERESTING (1u<<1)
|
#define UNINTERESTING (1u<<1)
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
|
|
||||||
struct rev_info;
|
struct rev_info;
|
||||||
struct log_info;
|
struct log_info;
|
||||||
|
struct string_list;
|
||||||
|
|
||||||
struct rev_info {
|
struct rev_info {
|
||||||
/* Starting list */
|
/* Starting list */
|
||||||
@@ -126,6 +128,9 @@ struct rev_info {
|
|||||||
struct reflog_walk_info *reflog_info;
|
struct reflog_walk_info *reflog_info;
|
||||||
struct decoration children;
|
struct decoration children;
|
||||||
struct decoration merge_simplification;
|
struct decoration merge_simplification;
|
||||||
|
|
||||||
|
/* notes-specific options: which refs to show */
|
||||||
|
struct display_notes_opt notes_opt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define REV_TREE_SAME 0
|
#define REV_TREE_SAME 0
|
||||||
|
|||||||
148
t/t3301-notes.sh
148
t/t3301-notes.sh
@@ -415,7 +415,7 @@ Date: Thu Apr 7 15:18:13 2005 -0700
|
|||||||
|
|
||||||
6th
|
6th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
other note
|
other note
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -448,7 +448,139 @@ test_expect_success 'Do not show note when core.notesRef is overridden' '
|
|||||||
test_cmp expect-not-other output
|
test_cmp expect-not-other output
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat > expect-both << EOF
|
||||||
|
commit 387a89921c73d7ed72cd94d179c1c7048ca47756
|
||||||
|
Author: A U Thor <author@example.com>
|
||||||
|
Date: Thu Apr 7 15:18:13 2005 -0700
|
||||||
|
|
||||||
|
6th
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
order test
|
||||||
|
|
||||||
|
Notes (other):
|
||||||
|
other note
|
||||||
|
|
||||||
|
commit bd1753200303d0a0344be813e504253b3d98e74d
|
||||||
|
Author: A U Thor <author@example.com>
|
||||||
|
Date: Thu Apr 7 15:17:13 2005 -0700
|
||||||
|
|
||||||
|
5th
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
replacement for deleted note
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
|
||||||
|
GIT_NOTES_REF=refs/notes/commits git notes add \
|
||||||
|
-m"replacement for deleted note" HEAD^ &&
|
||||||
|
GIT_NOTES_REF=refs/notes/commits git notes add -m"order test" &&
|
||||||
|
git config --unset core.notesRef &&
|
||||||
|
git config notes.displayRef "refs/notes/*" &&
|
||||||
|
git log -2 > output &&
|
||||||
|
test_cmp expect-both output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'core.notesRef is implicitly in notes.displayRef' '
|
||||||
|
git config core.notesRef refs/notes/commits &&
|
||||||
|
git config notes.displayRef refs/notes/other &&
|
||||||
|
git log -2 > output &&
|
||||||
|
test_cmp expect-both output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'notes.displayRef can be given more than once' '
|
||||||
|
git config --unset core.notesRef &&
|
||||||
|
git config notes.displayRef refs/notes/commits &&
|
||||||
|
git config --add notes.displayRef refs/notes/other &&
|
||||||
|
git log -2 > output &&
|
||||||
|
test_cmp expect-both output
|
||||||
|
'
|
||||||
|
|
||||||
|
cat > expect-both-reversed << EOF
|
||||||
|
commit 387a89921c73d7ed72cd94d179c1c7048ca47756
|
||||||
|
Author: A U Thor <author@example.com>
|
||||||
|
Date: Thu Apr 7 15:18:13 2005 -0700
|
||||||
|
|
||||||
|
6th
|
||||||
|
|
||||||
|
Notes (other):
|
||||||
|
other note
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
order test
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'notes.displayRef respects order' '
|
||||||
|
git config core.notesRef refs/notes/other &&
|
||||||
|
git config --unset-all notes.displayRef &&
|
||||||
|
git config notes.displayRef refs/notes/commits &&
|
||||||
|
git log -1 > output &&
|
||||||
|
test_cmp expect-both-reversed output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
|
||||||
|
git config --unset-all core.notesRef &&
|
||||||
|
git config --unset-all notes.displayRef &&
|
||||||
|
GIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \
|
||||||
|
git log -2 > output &&
|
||||||
|
test_cmp expect-both output
|
||||||
|
'
|
||||||
|
|
||||||
|
cat > expect-none << EOF
|
||||||
|
commit 387a89921c73d7ed72cd94d179c1c7048ca47756
|
||||||
|
Author: A U Thor <author@example.com>
|
||||||
|
Date: Thu Apr 7 15:18:13 2005 -0700
|
||||||
|
|
||||||
|
6th
|
||||||
|
|
||||||
|
commit bd1753200303d0a0344be813e504253b3d98e74d
|
||||||
|
Author: A U Thor <author@example.com>
|
||||||
|
Date: Thu Apr 7 15:17:13 2005 -0700
|
||||||
|
|
||||||
|
5th
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
|
||||||
|
git config notes.displayRef "refs/notes/*" &&
|
||||||
|
GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 > output &&
|
||||||
|
test_cmp expect-none output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
|
||||||
|
GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 > output &&
|
||||||
|
test_cmp expect-both output
|
||||||
|
'
|
||||||
|
|
||||||
|
cat > expect-commits << EOF
|
||||||
|
commit 387a89921c73d7ed72cd94d179c1c7048ca47756
|
||||||
|
Author: A U Thor <author@example.com>
|
||||||
|
Date: Thu Apr 7 15:18:13 2005 -0700
|
||||||
|
|
||||||
|
6th
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
order test
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success '--no-standard-notes' '
|
||||||
|
git log --no-standard-notes --show-notes=commits -1 > output &&
|
||||||
|
test_cmp expect-commits output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '--standard-notes' '
|
||||||
|
git log --no-standard-notes --show-notes=commits \
|
||||||
|
--standard-notes -2 > output &&
|
||||||
|
test_cmp expect-both output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '--show-notes=ref accumulates' '
|
||||||
|
git log --show-notes=other --show-notes=commits \
|
||||||
|
--no-standard-notes -1 > output &&
|
||||||
|
test_cmp expect-both-reversed output
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
|
test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
|
||||||
|
git config core.notesRef refs/notes/other &&
|
||||||
echo "Note on a tree" > expect
|
echo "Note on a tree" > expect
|
||||||
git notes add -m "Note on a tree" HEAD: &&
|
git notes add -m "Note on a tree" HEAD: &&
|
||||||
git notes show HEAD: > actual &&
|
git notes show HEAD: > actual &&
|
||||||
@@ -472,7 +604,7 @@ Date: Thu Apr 7 15:19:13 2005 -0700
|
|||||||
|
|
||||||
7th
|
7th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
other note
|
other note
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -503,7 +635,7 @@ Date: Thu Apr 7 15:21:13 2005 -0700
|
|||||||
|
|
||||||
9th
|
9th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
yet another note
|
yet another note
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -533,7 +665,7 @@ Date: Thu Apr 7 15:21:13 2005 -0700
|
|||||||
|
|
||||||
9th
|
9th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
yet another note
|
yet another note
|
||||||
$whitespace
|
$whitespace
|
||||||
yet another note
|
yet another note
|
||||||
@@ -552,7 +684,7 @@ Date: Thu Apr 7 15:22:13 2005 -0700
|
|||||||
|
|
||||||
10th
|
10th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
other note
|
other note
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -569,7 +701,7 @@ Date: Thu Apr 7 15:22:13 2005 -0700
|
|||||||
|
|
||||||
10th
|
10th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
other note
|
other note
|
||||||
$whitespace
|
$whitespace
|
||||||
yet another note
|
yet another note
|
||||||
@@ -588,7 +720,7 @@ Date: Thu Apr 7 15:23:13 2005 -0700
|
|||||||
|
|
||||||
11th
|
11th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
other note
|
other note
|
||||||
$whitespace
|
$whitespace
|
||||||
yet another note
|
yet another note
|
||||||
@@ -619,7 +751,7 @@ Date: Thu Apr 7 15:23:13 2005 -0700
|
|||||||
|
|
||||||
11th
|
11th
|
||||||
|
|
||||||
Notes:
|
Notes (other):
|
||||||
yet another note
|
yet another note
|
||||||
$whitespace
|
$whitespace
|
||||||
yet another note
|
yet another note
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ unset GIT_CEILING_DIRECTORIES
|
|||||||
unset SHA1_FILE_DIRECTORIES
|
unset SHA1_FILE_DIRECTORIES
|
||||||
unset SHA1_FILE_DIRECTORY
|
unset SHA1_FILE_DIRECTORY
|
||||||
unset GIT_NOTES_REF
|
unset GIT_NOTES_REF
|
||||||
|
unset GIT_NOTES_DISPLAY_REF
|
||||||
GIT_MERGE_VERBOSITY=5
|
GIT_MERGE_VERBOSITY=5
|
||||||
export GIT_MERGE_VERBOSITY
|
export GIT_MERGE_VERBOSITY
|
||||||
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
|
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
|
||||||
|
|||||||
Reference in New Issue
Block a user