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>
Thomas Rast committed
Mar 12, 2010 at 18:04 UTC
894a9d333e9e2015cad00d95250b7c5d3acea8b6
14 files changed
+437
-30
Documentation/config.txt
+21
-2
@@ -500,10 +500,12 @@ check that makes sure that existing object files will not get overwritten.
500
core.notesRef::
501
When showing commit messages, also show notes which are stored in
502
the given ref. This ref is expected to contain files named
503
- after the full SHA-1 of the commit they annotate.
503
+ after the full SHA-1 of the commit they annotate. The ref
504
+ must be fully qualified.
505
+
506
If such a file exists in the given ref, the referenced blob is read, and
506
-appended to the commit message, separated by a "Notes:" line. If the
507
+appended to the commit message, separated by a "Notes (<refname>):"
508
+line (shortened to "Notes:" in the case of "refs/notes/commits"). If the
509
given ref itself does not exist, it is not an error, but means that no
510
notes should be printed.
511
+
@@ -1286,6 +1288,23 @@ mergetool.keepTemporaries::
1288
mergetool.prompt::
1289
Prompt before each invocation of the merge resolution program.
1290
1291
+notes.displayRef::
1292
+ The (fully qualified) refname from which to show notes when
1293
+ showing commit messages. The value of this variable can be set
1294
+ to a glob, in which case notes from all matching refs will be
1295
+ shown. You may also specify this configuration variable
1296
+ several times. A warning will be issued for refs that do not
1297
+ exist, but a glob that does not match any refs is silently
1298
+ ignored.
1299
++
1300
+This setting can be overridden with the `GIT_NOTES_DISPLAY_REF`
1301
+environment variable, which must be a colon separated list of refs or
1302
+globs.
1303
++
1304
+The effective value of "core.notesRef" (possibly overridden by
1305
+GIT_NOTES_REF) is also implicitly added to the list of refs to be
1306
+displayed.
1307
+
1308
pack.window::
1309
The size of the window used by linkgit:git-pack-objects[1] when no
1310
window size is given on the command line. Defaults to 10.
Documentation/git-notes.txt
+6
-5
@@ -27,12 +27,13 @@ A typical use of notes is to extend a commit message without having
27
to change the commit itself. Such commit notes can be shown by `git log`
28
along with the original commit message. To discern these notes from the
29
message stored in the commit object, the notes are indented like the
30
-message, after an unindented line saying "Notes:".
30
+message, after an unindented line saying "Notes (<refname>):" (or
31
+"Notes:" for the default setting).
32
32
-To disable notes, you have to set the config variable core.notesRef to
33
-the empty string. Alternatively, you can set it to a different ref,
34
-something like "refs/notes/bugzilla". This setting can be overridden
35
-by the environment variable "GIT_NOTES_REF".
33
+This command always manipulates the notes specified in "core.notesRef"
34
+(see linkgit:git-config[1]), which can be overridden by GIT_NOTES_REF.
35
+To change which notes are shown by 'git-log', see the
36
+"notes.displayRef" configuration.
37
38
39
SUBCOMMANDS
Documentation/pretty-options.txt
+10
-1
@@ -30,9 +30,18 @@ people using 80-column terminals.
30
defaults to UTF-8.
31
32
--no-notes::
33
---show-notes::
33
+--show-notes[=<ref>]::
34
Show the notes (see linkgit:git-notes[1]) that annotate the
35
commit, when showing the commit log message. This is the default
36
for `git log`, `git show` and `git whatchanged` commands when
37
there is no `--pretty`, `--format` nor `--oneline` option is
38
given on the command line.
39
++
40
+With an optional argument, add this ref to the list of notes. The ref
41
+is taken to be in `refs/notes/` if it is not qualified.
42
+
43
+--[no-]standard-notes::
44
+ Enable or disable populating the notes ref list from the
45
+ 'core.notesRef' and 'notes.displayRef' variables (or
46
+ corresponding environment overrides). Enabled by default.
47
+ See linkgit:git-config[1].
builtin-log.c
+5
@@ -60,6 +60,8 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
60
61
if (!rev->show_notes_given && !rev->pretty_given)
62
rev->show_notes = 1;
63
+ if (rev->show_notes)
64
+ init_display_notes(&rev->notes_opt);
65
66
if (rev->diffopt.pickaxe || rev->diffopt.filter)
67
rev->always_show_header = 0;
@@ -1059,6 +1061,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1061
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
1062
DIFF_OPT_SET(&rev.diffopt, BINARY);
1063
1064
+ if (rev.show_notes)
1065
+ init_display_notes(&rev.notes_opt);
1066
+
1067
if (!use_stdout)
1068
output_directory = set_outdir(prefix, output_directory);
1069
cache.h
+1
@@ -385,6 +385,7 @@ static inline enum object_type object_type(unsigned int mode)
385
#define ATTRIBUTE_MACRO_PREFIX "[attr]"
386
#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
387
#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"
388
+#define GIT_NOTES_DISPLAY_REF_ENVIRONMENT "GIT_NOTES_DISPLAY_REF"
389
390
extern int is_bare_repository_cfg;
391
extern int is_bare_repository(void);
notes.c
+162
-7
@@ -5,6 +5,8 @@
5
#include "utf8.h"
6
#include "strbuf.h"
7
#include "tree-walk.h"
8
+#include "string-list.h"
9
+#include "refs.h"
10
11
/*
12
* Use a non-balancing simple 16-tree structure with struct int_node as
@@ -68,6 +70,9 @@ struct non_note {
70
71
struct notes_tree default_notes_tree;
72
73
+static struct string_list display_notes_refs;
74
+static struct notes_tree **display_notes_trees;
75
+
76
static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
77
struct int_node *node, unsigned int n);
78
@@ -828,6 +833,83 @@ int combine_notes_ignore(unsigned char *cur_sha1,
833
return 0;
834
}
835
836
+static int string_list_add_one_ref(const char *path, const unsigned char *sha1,
837
+ int flag, void *cb)
838
+{
839
+ struct string_list *refs = cb;
840
+ if (!unsorted_string_list_has_string(refs, path))
841
+ string_list_append(path, refs);
842
+ return 0;
843
+}
844
+
845
+void string_list_add_refs_by_glob(struct string_list *list, const char *glob)
846
+{
847
+ if (has_glob_specials(glob)) {
848
+ for_each_glob_ref(string_list_add_one_ref, glob, list);
849
+ } else {
850
+ unsigned char sha1[20];
851
+ if (get_sha1(glob, sha1))
852
+ warning("notes ref %s is invalid", glob);
853
+ if (!unsorted_string_list_has_string(list, glob))
854
+ string_list_append(glob, list);
855
+ }
856
+}
857
+
858
+void string_list_add_refs_from_colon_sep(struct string_list *list,
859
+ const char *globs)
860
+{
861
+ struct strbuf globbuf = STRBUF_INIT;
862
+ struct strbuf **split;
863
+ int i;
864
+
865
+ strbuf_addstr(&globbuf, globs);
866
+ split = strbuf_split(&globbuf, ':');
867
+
868
+ for (i = 0; split[i]; i++) {
869
+ if (!split[i]->len)
870
+ continue;
871
+ if (split[i]->buf[split[i]->len-1] == ':')
872
+ strbuf_setlen(split[i], split[i]->len-1);
873
+ string_list_add_refs_by_glob(list, split[i]->buf);
874
+ }
875
+
876
+ strbuf_list_free(split);
877
+ strbuf_release(&globbuf);
878
+}
879
+
880
+static int string_list_add_refs_from_list(struct string_list_item *item,
881
+ void *cb)
882
+{
883
+ struct string_list *list = cb;
884
+ string_list_add_refs_by_glob(list, item->string);
885
+ return 0;
886
+}
887
+
888
+static int notes_display_config(const char *k, const char *v, void *cb)
889
+{
890
+ int *load_refs = cb;
891
+
892
+ if (*load_refs && !strcmp(k, "notes.displayref")) {
893
+ if (!v)
894
+ config_error_nonbool(k);
895
+ string_list_add_refs_by_glob(&display_notes_refs, v);
896
+ }
897
+
898
+ return 0;
899
+}
900
+
901
+static const char *default_notes_ref(void)
902
+{
903
+ const char *notes_ref = NULL;
904
+ if (!notes_ref)
905
+ notes_ref = getenv(GIT_NOTES_REF_ENVIRONMENT);
906
+ if (!notes_ref)
907
+ notes_ref = notes_ref_name; /* value of core.notesRef config */
908
+ if (!notes_ref)
909
+ notes_ref = GIT_NOTES_DEFAULT_REF;
910
+ return notes_ref;
911
+}
912
+
913
void init_notes(struct notes_tree *t, const char *notes_ref,
914
combine_notes_fn combine_notes, int flags)
915
{
@@ -840,11 +922,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
922
assert(!t->initialized);
923
924
if (!notes_ref)
843
- notes_ref = getenv(GIT_NOTES_REF_ENVIRONMENT);
844
- if (!notes_ref)
845
- notes_ref = notes_ref_name; /* value of core.notesRef config */
846
- if (!notes_ref)
847
- notes_ref = GIT_NOTES_DEFAULT_REF;
925
+ notes_ref = default_notes_ref();
926
927
if (!combine_notes)
928
combine_notes = combine_notes_concatenate;
@@ -868,6 +946,63 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
946
load_subtree(t, &root_tree, t->root, 0);
947
}
948
949
+struct load_notes_cb_data {
950
+ int counter;
951
+ struct notes_tree **trees;
952
+};
953
+
954
+static int load_one_display_note_ref(struct string_list_item *item,
955
+ void *cb_data)
956
+{
957
+ struct load_notes_cb_data *c = cb_data;
958
+ struct notes_tree *t = xcalloc(1, sizeof(struct notes_tree));
959
+ init_notes(t, item->string, combine_notes_ignore, 0);
960
+ c->trees[c->counter++] = t;
961
+ return 0;
962
+}
963
+
964
+struct notes_tree **load_notes_trees(struct string_list *refs)
965
+{
966
+ struct notes_tree **trees;
967
+ struct load_notes_cb_data cb_data;
968
+ trees = xmalloc((refs->nr+1) * sizeof(struct notes_tree *));
969
+ cb_data.counter = 0;
970
+ cb_data.trees = trees;
971
+ for_each_string_list(load_one_display_note_ref, refs, &cb_data);
972
+ trees[cb_data.counter] = NULL;
973
+ return trees;
974
+}
975
+
976
+void init_display_notes(struct display_notes_opt *opt)
977
+{
978
+ char *display_ref_env;
979
+ int load_config_refs = 0;
980
+ display_notes_refs.strdup_strings = 1;
981
+
982
+ assert(!display_notes_trees);
983
+
984
+ if (!opt || !opt->suppress_default_notes) {
985
+ string_list_append(default_notes_ref(), &display_notes_refs);
986
+ display_ref_env = getenv(GIT_NOTES_DISPLAY_REF_ENVIRONMENT);
987
+ if (display_ref_env) {
988
+ string_list_add_refs_from_colon_sep(&display_notes_refs,
989
+ display_ref_env);
990
+ load_config_refs = 0;
991
+ } else
992
+ load_config_refs = 1;
993
+ }
994
+
995
+ git_config(notes_display_config, &load_config_refs);
996
+
997
+ if (opt && opt->extra_notes_refs)
998
+ for_each_string_list(string_list_add_refs_from_list,
999
+ opt->extra_notes_refs,
1000
+ &display_notes_refs);
1001
+
1002
+ display_notes_trees = load_notes_trees(&display_notes_refs);
1003
+ string_list_clear(&display_notes_refs, 0);
1004
+}
1005
+
1006
void add_note(struct notes_tree *t, const unsigned char *object_sha1,
1007
const unsigned char *note_sha1, combine_notes_fn combine_notes)
1008
{
@@ -1016,8 +1151,18 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
1151
if (msglen && msg[msglen - 1] == '\n')
1152
msglen--;
1153
1019
- if (flags & NOTES_SHOW_HEADER)
1020
- strbuf_addstr(sb, "\nNotes:\n");
1154
+ if (flags & NOTES_SHOW_HEADER) {
1155
+ const char *ref = t->ref;
1156
+ if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) {
1157
+ strbuf_addstr(sb, "\nNotes:\n");
1158
+ } else {
1159
+ if (!prefixcmp(ref, "refs/"))
1160
+ ref += 5;
1161
+ if (!prefixcmp(ref, "notes/"))
1162
+ ref += 6;
1163
+ strbuf_addf(sb, "\nNotes (%s):\n", ref);
1164
+ }
1165
+ }
1166
1167
for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
1168
linelen = strchrnul(msg_p, '\n') - msg_p;
@@ -1030,3 +1175,13 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
1175
1176
free(msg);
1177
}
1178
+
1179
+void format_display_notes(const unsigned char *object_sha1,
1180
+ struct strbuf *sb, const char *output_encoding, int flags)
1181
+{
1182
+ int i;
1183
+ assert(display_notes_trees);
1184
+ for (i = 0; display_notes_trees[i]; i++)
1185
+ format_note(display_notes_trees[i], object_sha1, sb,
1186
+ output_encoding, flags);
1187
+}
notes.h
+55
@@ -198,4 +198,59 @@ void free_notes(struct notes_tree *t);
198
void format_note(struct notes_tree *t, const unsigned char *object_sha1,
199
struct strbuf *sb, const char *output_encoding, int flags);
200
201
+
202
+struct string_list;
203
+
204
+struct display_notes_opt {
205
+ int suppress_default_notes:1;
206
+ struct string_list *extra_notes_refs;
207
+};
208
+
209
+/*
210
+ * Load the notes machinery for displaying several notes trees.
211
+ *
212
+ * If 'opt' is not NULL, then it specifies additional settings for the
213
+ * displaying:
214
+ *
215
+ * - suppress_default_notes indicates that the notes from
216
+ * core.notesRef and notes.displayRef should not be loaded.
217
+ *
218
+ * - extra_notes_refs may contain a list of globs (in the same style
219
+ * as notes.displayRef) where notes should be loaded from.
220
+ */
221
+void init_display_notes(struct display_notes_opt *opt);
222
+
223
+/*
224
+ * Append notes for the given 'object_sha1' from all trees set up by
225
+ * init_display_notes() to 'sb'. The 'flags' are a bitwise
226
+ * combination of
227
+ *
228
+ * - NOTES_SHOW_HEADER: add a 'Notes (refname):' header
229
+ *
230
+ * - NOTES_INDENT: indent the notes by 4 places
231
+ *
232
+ * You *must* call init_display_notes() before using this function.
233
+ */
234
+void format_display_notes(const unsigned char *object_sha1,
235
+ struct strbuf *sb, const char *output_encoding, int flags);
236
+
237
+/*
238
+ * Load the notes tree from each ref listed in 'refs'. The output is
239
+ * an array of notes_tree*, terminated by a NULL.
240
+ */
241
+struct notes_tree **load_notes_trees(struct string_list *refs);
242
+
243
+/*
244
+ * Add all refs that match 'glob' to the 'list'.
245
+ */
246
+void string_list_add_refs_by_glob(struct string_list *list, const char *glob);
247
+
248
+/*
249
+ * Add all refs from a colon-separated glob list 'globs' to the end of
250
+ * 'list'. Empty components are ignored. This helper is used to
251
+ * parse GIT_NOTES_DISPLAY_REF style environment variables.
252
+ */
253
+void string_list_add_refs_from_colon_sep(struct string_list *list,
254
+ const char *globs);
255
+
256
#endif
pretty.c
+3
-3
@@ -775,7 +775,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
775
}
776
return 0; /* unknown %g placeholder */
777
case 'N':
778
- format_note(NULL, commit->object.sha1, sb,
778
+ format_display_notes(commit->object.sha1, sb,
779
git_log_output_encoding ? git_log_output_encoding
780
: git_commit_encoding, 0);
781
return 1;
@@ -1096,8 +1096,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
1096
strbuf_addch(sb, '\n');
1097
1098
if (context->show_notes)
1099
- format_note(NULL, commit->object.sha1, sb, encoding,
1100
- NOTES_SHOW_HEADER | NOTES_INDENT);
1099
+ format_display_notes(commit->object.sha1, sb, encoding,
1100
+ NOTES_SHOW_HEADER | NOTES_INDENT);
1101
1102
free(reencoded);
1103
}
refs.c
+2
-4
@@ -695,7 +695,6 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
695
{
696
struct strbuf real_pattern = STRBUF_INIT;
697
struct ref_filter filter;
698
- const char *has_glob_specials;
698
int ret;
699
700
if (!prefix && prefixcmp(pattern, "refs/"))
@@ -704,9 +703,8 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
703
strbuf_addstr(&real_pattern, prefix);
704
strbuf_addstr(&real_pattern, pattern);
705
707
- has_glob_specials = strpbrk(pattern, "?*[");
708
- if (!has_glob_specials) {
709
- /* Append impiled '/' '*' if not present. */
706
+ if (!has_glob_specials(pattern)) {
707
+ /* Append implied '/' '*' if not present. */
708
if (real_pattern.buf[real_pattern.len - 1] != '/')
709
strbuf_addch(&real_pattern, '/');
710
/* No need to check for '*', there is none. */
refs.h
+5
@@ -28,6 +28,11 @@ extern int for_each_replace_ref(each_ref_fn, void *);
28
extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);
29
extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);
30
31
+static inline const char *has_glob_specials(const char *pattern)
32
+{
33
+ return strpbrk(pattern, "?*[");
34
+}
35
+
36
/* can be used to learn about broken ref and symref */
37
extern int for_each_rawref(each_ref_fn, void *);
38
revision.c
+21
@@ -12,6 +12,7 @@
12
#include "patch-ids.h"
13
#include "decorate.h"
14
#include "log-tree.h"
15
+#include "string-list.h"
16
17
volatile show_early_output_fn_t show_early_output;
18
@@ -1176,9 +1177,29 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
1177
} else if (!strcmp(arg, "--show-notes")) {
1178
revs->show_notes = 1;
1179
revs->show_notes_given = 1;
1180
+ } else if (!prefixcmp(arg, "--show-notes=")) {
1181
+ struct strbuf buf = STRBUF_INIT;
1182
+ revs->show_notes = 1;
1183
+ revs->show_notes_given = 1;
1184
+ if (!revs->notes_opt.extra_notes_refs)
1185
+ revs->notes_opt.extra_notes_refs = xcalloc(1, sizeof(struct string_list));
1186
+ if (!prefixcmp(arg+13, "refs/"))
1187
+ /* happy */;
1188
+ else if (!prefixcmp(arg+13, "notes/"))
1189
+ strbuf_addstr(&buf, "refs/");
1190
+ else
1191
+ strbuf_addstr(&buf, "refs/notes/");
1192
+ strbuf_addstr(&buf, arg+13);
1193
+ string_list_append(strbuf_detach(&buf, NULL),
1194
+ revs->notes_opt.extra_notes_refs);
1195
} else if (!strcmp(arg, "--no-notes")) {
1196
revs->show_notes = 0;
1197
revs->show_notes_given = 1;
1198
+ } else if (!strcmp(arg, "--standard-notes")) {
1199
+ revs->show_notes_given = 1;
1200
+ revs->notes_opt.suppress_default_notes = 0;
1201
+ } else if (!strcmp(arg, "--no-standard-notes")) {
1202
+ revs->notes_opt.suppress_default_notes = 1;
1203
} else if (!strcmp(arg, "--oneline")) {
1204
revs->verbose_header = 1;
1205
get_commit_format("oneline", revs);
revision.h
+5
@@ -3,6 +3,7 @@
3
4
#include "parse-options.h"
5
#include "grep.h"
6
+#include "notes.h"
7
8
#define SEEN (1u<<0)
9
#define UNINTERESTING (1u<<1)
@@ -20,6 +21,7 @@
21
22
struct rev_info;
23
struct log_info;
24
+struct string_list;
25
26
struct rev_info {
27
/* Starting list */
@@ -126,6 +128,9 @@ struct rev_info {
128
struct reflog_walk_info *reflog_info;
129
struct decoration children;
130
struct decoration merge_simplification;
131
+
132
+ /* notes-specific options: which refs to show */
133
+ struct display_notes_opt notes_opt;
134
};
135
136
#define REV_TREE_SAME 0
t/t3301-notes.sh
+140
-8
@@ -415,7 +415,7 @@ Date: Thu Apr 7 15:18:13 2005 -0700
415
416
6th
417
418
-Notes:
418
+Notes (other):
419
other note
420
EOF
421
@@ -448,7 +448,139 @@ test_expect_success 'Do not show note when core.notesRef is overridden' '
448
test_cmp expect-not-other output
449
'
450
451
+cat > expect-both << EOF
452
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
453
+Author: A U Thor <author@example.com>
454
+Date: Thu Apr 7 15:18:13 2005 -0700
455
+
456
+ 6th
457
+
458
+Notes:
459
+ order test
460
+
461
+Notes (other):
462
+ other note
463
+
464
+commit bd1753200303d0a0344be813e504253b3d98e74d
465
+Author: A U Thor <author@example.com>
466
+Date: Thu Apr 7 15:17:13 2005 -0700
467
+
468
+ 5th
469
+
470
+Notes:
471
+ replacement for deleted note
472
+EOF
473
+
474
+test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
475
+ GIT_NOTES_REF=refs/notes/commits git notes add \
476
+ -m"replacement for deleted note" HEAD^ &&
477
+ GIT_NOTES_REF=refs/notes/commits git notes add -m"order test" &&
478
+ git config --unset core.notesRef &&
479
+ git config notes.displayRef "refs/notes/*" &&
480
+ git log -2 > output &&
481
+ test_cmp expect-both output
482
+'
483
+
484
+test_expect_success 'core.notesRef is implicitly in notes.displayRef' '
485
+ git config core.notesRef refs/notes/commits &&
486
+ git config notes.displayRef refs/notes/other &&
487
+ git log -2 > output &&
488
+ test_cmp expect-both output
489
+'
490
+
491
+test_expect_success 'notes.displayRef can be given more than once' '
492
+ git config --unset core.notesRef &&
493
+ git config notes.displayRef refs/notes/commits &&
494
+ git config --add notes.displayRef refs/notes/other &&
495
+ git log -2 > output &&
496
+ test_cmp expect-both output
497
+'
498
+
499
+cat > expect-both-reversed << EOF
500
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
501
+Author: A U Thor <author@example.com>
502
+Date: Thu Apr 7 15:18:13 2005 -0700
503
+
504
+ 6th
505
+
506
+Notes (other):
507
+ other note
508
+
509
+Notes:
510
+ order test
511
+EOF
512
+
513
+test_expect_success 'notes.displayRef respects order' '
514
+ git config core.notesRef refs/notes/other &&
515
+ git config --unset-all notes.displayRef &&
516
+ git config notes.displayRef refs/notes/commits &&
517
+ git log -1 > output &&
518
+ test_cmp expect-both-reversed output
519
+'
520
+
521
+test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
522
+ git config --unset-all core.notesRef &&
523
+ git config --unset-all notes.displayRef &&
524
+ GIT_NOTES_DISPLAY_REF=refs/notes/commits:refs/notes/other \
525
+ git log -2 > output &&
526
+ test_cmp expect-both output
527
+'
528
+
529
+cat > expect-none << EOF
530
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
531
+Author: A U Thor <author@example.com>
532
+Date: Thu Apr 7 15:18:13 2005 -0700
533
+
534
+ 6th
535
+
536
+commit bd1753200303d0a0344be813e504253b3d98e74d
537
+Author: A U Thor <author@example.com>
538
+Date: Thu Apr 7 15:17:13 2005 -0700
539
+
540
+ 5th
541
+EOF
542
+
543
+test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
544
+ git config notes.displayRef "refs/notes/*" &&
545
+ GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log -2 > output &&
546
+ test_cmp expect-none output
547
+'
548
+
549
+test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
550
+ GIT_NOTES_REF= GIT_NOTES_DISPLAY_REF= git log --show-notes=* -2 > output &&
551
+ test_cmp expect-both output
552
+'
553
+
554
+cat > expect-commits << EOF
555
+commit 387a89921c73d7ed72cd94d179c1c7048ca47756
556
+Author: A U Thor <author@example.com>
557
+Date: Thu Apr 7 15:18:13 2005 -0700
558
+
559
+ 6th
560
+
561
+Notes:
562
+ order test
563
+EOF
564
+
565
+test_expect_success '--no-standard-notes' '
566
+ git log --no-standard-notes --show-notes=commits -1 > output &&
567
+ test_cmp expect-commits output
568
+'
569
+
570
+test_expect_success '--standard-notes' '
571
+ git log --no-standard-notes --show-notes=commits \
572
+ --standard-notes -2 > output &&
573
+ test_cmp expect-both output
574
+'
575
+
576
+test_expect_success '--show-notes=ref accumulates' '
577
+ git log --show-notes=other --show-notes=commits \
578
+ --no-standard-notes -1 > output &&
579
+ test_cmp expect-both-reversed output
580
+'
581
+
582
test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
583
+ git config core.notesRef refs/notes/other &&
584
echo "Note on a tree" > expect
585
git notes add -m "Note on a tree" HEAD: &&
586
git notes show HEAD: > actual &&
@@ -472,7 +604,7 @@ Date: Thu Apr 7 15:19:13 2005 -0700
604
605
7th
606
475
-Notes:
607
+Notes (other):
608
other note
609
EOF
610
@@ -503,7 +635,7 @@ Date: Thu Apr 7 15:21:13 2005 -0700
635
636
9th
637
506
-Notes:
638
+Notes (other):
639
yet another note
640
EOF
641
@@ -533,7 +665,7 @@ Date: Thu Apr 7 15:21:13 2005 -0700
665
666
9th
667
536
-Notes:
668
+Notes (other):
669
yet another note
670
$whitespace
671
yet another note
@@ -552,7 +684,7 @@ Date: Thu Apr 7 15:22:13 2005 -0700
684
685
10th
686
555
-Notes:
687
+Notes (other):
688
other note
689
EOF
690
@@ -569,7 +701,7 @@ Date: Thu Apr 7 15:22:13 2005 -0700
701
702
10th
703
572
-Notes:
704
+Notes (other):
705
other note
706
$whitespace
707
yet another note
@@ -588,7 +720,7 @@ Date: Thu Apr 7 15:23:13 2005 -0700
720
721
11th
722
591
-Notes:
723
+Notes (other):
724
other note
725
$whitespace
726
yet another note
@@ -619,7 +751,7 @@ Date: Thu Apr 7 15:23:13 2005 -0700
751
752
11th
753
622
-Notes:
754
+Notes (other):
755
yet another note
756
$whitespace
757
yet another note
t/test-lib.sh
+1
@@ -55,6 +55,7 @@ unset GIT_CEILING_DIRECTORIES
55
unset SHA1_FILE_DIRECTORIES
56
unset SHA1_FILE_DIRECTORY
57
unset GIT_NOTES_REF
58
+unset GIT_NOTES_DISPLAY_REF
59
GIT_MERGE_VERBOSITY=5
60
export GIT_MERGE_VERBOSITY
61
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME