git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[WIP/RFC PATCH] Support showing notes from more than one notes tree

From
Thomas Rast <trast@student.ethz.ch>
Date
Feb 20, 2010, 14:58 UTC
Message-ID
<8c3f1d66d306747d777f04621f1d43d7e07ddc6a.1266677264.git.trast@student.ethz.ch>
In-Reply-To
<7v7hqcww7z.fsf@alter.siamese.dyndns.org>

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. ---

I'm running out of git time today, so I'm floating this weatherbaloon to demonstrate how I would like to get around the limitations discussed by Junio:

Show 5 quoted lines
> I was envisioning that most of the time people would want to read from
> (and probably concatenate, or output with the origin information tagged in)
> multiple notes but want to create into a single one.  But updating for
> rewritten commits fundamentally need to happen in all of these multiple
> notes trees they would want to read from.

This patch is the display-several-trees bit. I'm assuming that it's ok to load all notes trees at once. (Obviously it lacks docs, and it also breaks test because of the new formatting that shows 'Notes from notes/someref'. Please ignore those for now.)

My actual intent was to allow more than one notes.displayref config setting, and loading all of them. But this doesn't seem to work; a debugging print confirms that notes_display_config sees the entry, but another debugging print shows that it only ever loads one of them. What am I doing wrong?

I plan on having another set of configs called notes.rewriteRef that gives the list of refs that should have their notes rewritten automatically along with their commits. [The rewriteMode setting could become '<mode> for <ref>' if we want to let the user configure it on a per-ref/glob basis.]

Finally, git-notes should probably grow a --ref option that serves as a more convenient way of setting GIT_NOTES_REF.

 notes.c  |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 notes.h  |    1 +
 pretty.c |    6 ++--
 3 files changed, 80 insertions(+), 9 deletions(-)
diff --git a/notes.c b/notes.c
index a5ff723..47eaa21 100644
--- a/notes.c
+++ b/notes.c
@@ -5,6 +5,8 @@
 #include "utf8.h"
 #include "strbuf.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
@@ -68,6 +70,9 @@ struct non_note {
 
 struct notes_tree default_notes_tree;
 
+struct string_list display_notes_refs;
+struct notes_tree **display_notes_trees;
+
 static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
 		struct int_node *node, unsigned int n);
 
@@ -828,6 +833,36 @@ int combine_notes_ignore(unsigned char *cur_sha1,
 	return 0;
 }
 
+static int read_one_display_ref(const char *path, const unsigned char *sha1,
+				int flag, void *cb)
+{
+	string_list_insert(path, &display_notes_refs);
+	return 0;
+}
+
+
+static int notes_display_config(const char *k, const char *v, void *cb)
+{
+	if (!strcmp(k, "notes.displayref")) {
+		for_each_glob_ref(read_one_display_ref, v, NULL);
+		return 0;
+	}
+
+	return 0;
+}
+
+static const char *default_notes_ref()
+{
+	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,
 		combine_notes_fn combine_notes, int flags)
 {
@@ -840,11 +875,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
 	assert(!t->initialized);
 
 	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;
+		notes_ref = default_notes_ref();
 
 	if (!combine_notes)
 		combine_notes = combine_notes_concatenate;
@@ -868,6 +899,29 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
 	load_subtree(t, &root_tree, t->root, 0);
 }
 
+static int load_one_display_note_ref(struct string_list_item *item,
+				     void *cb_data)
+{
+	int *counter = cb_data;
+	struct notes_tree *t = xcalloc(1, sizeof(struct notes_tree));
+	init_notes(t, item->string, combine_notes_ignore, 0);
+	display_notes_trees[(*counter)++] = t;
+	return 0;
+}
+
+void init_display_notes()
+{
+	int cb_counter = 0;
+	string_list_insert(default_notes_ref(), &display_notes_refs);
+	display_notes_refs.strdup_strings = 1;
+	git_config(notes_display_config, NULL);
+	display_notes_trees = xmalloc((display_notes_refs.nr+1)
+				      * sizeof(struct notes_tree *));
+	for_each_string_list(load_one_display_note_ref,
+			     &display_notes_refs, &cb_counter);
+	display_notes_trees[cb_counter] = NULL;
+}
+
 void add_note(struct notes_tree *t, const unsigned char *object_sha1,
 		const unsigned char *note_sha1, combine_notes_fn combine_notes)
 {
@@ -1016,7 +1070,12 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
 	if (msglen && msg[msglen - 1] == '\n')
 		msglen--;
 
-	if (flags & NOTES_SHOW_HEADER)
+	if (flags & NOTES_SHOW_HEADER_WITH_REF && t->ref) {
+		const char *ref = t->ref;
+		if (!prefixcmp(ref, "refs/"))
+			ref += 5;
+		strbuf_addf(sb, "\nNotes from %s:\n", ref);
+	} else if (flags & (NOTES_SHOW_HEADER|NOTES_SHOW_HEADER_WITH_REF))
 		strbuf_addstr(sb, "\nNotes:\n");
 
 	for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
@@ -1031,6 +1090,17 @@ void format_note(struct notes_tree *t, const unsigned char *object_sha1,
 	free(msg);
 }
 
+void format_display_notes(const unsigned char *object_sha1,
+			  struct strbuf *sb, const char *output_encoding, int flags)
+{
+	int i;
+	if (!display_notes_trees)
+		init_display_notes();
+	for (i = 0; display_notes_trees[i]; i++)
+		format_note(display_notes_trees[i], object_sha1, sb,
+			    output_encoding, flags);
+}
+
 int copy_note(struct notes_tree *t,
 	      const unsigned char *from_obj, const unsigned char *to_obj,
 	      int force, combine_notes_fn combine_fn)
diff --git a/notes.h b/notes.h
index b7547bf..f6a5229 100644
--- a/notes.h
+++ b/notes.h
@@ -193,6 +193,7 @@ int for_each_note(struct notes_tree *t, int flags, each_note_fn fn,
 /* Flags controlling how notes are formatted */
 #define NOTES_SHOW_HEADER 1
 #define NOTES_INDENT 2
+#define NOTES_SHOW_HEADER_WITH_REF 4
 
 /*
  * Fill the given strbuf with the notes associated with the given object.
diff --git a/pretty.c b/pretty.c
index f999485..c185fd2 100644
--- a/pretty.c
+++ b/pretty.c
@@ -775,7 +775,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
 		}
 		return 0;	/* unknown %g placeholder */
 	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_commit_encoding, 0);
 		return 1;
@@ -1096,8 +1096,8 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
 		strbuf_addch(sb, '\n');
 
 	if (context->show_notes)
-		format_note(NULL, commit->object.sha1, sb, encoding,
-			    NOTES_SHOW_HEADER | NOTES_INDENT);
+		format_display_notes(commit->object.sha1, sb, encoding,
+				     NOTES_SHOW_HEADER_WITH_REF | NOTES_INDENT);
 
 	free(reencoded);
 }
-- 
1.7.0.143.gbf2a7.dirty
Previous: Junio C HamanoNext: Thomas Rast
Message 27 of 34 in “post-rewrite hook and copying notes”
  1. 0/6 post-rewrite hook and copying notesThomas Rast, Feb 14, 2010
  2. 1/6 Documentation: document post-rewrite hookThomas Rast, Feb 14, 2010
  3. 2/6 commit --amend: invoke post-rewrite hookThomas Rast, Feb 14, 2010
  4. 3/6 filter-branch: invoke post-rewrite hookThomas Rast, Feb 14, 2010
  5. Johannes SixtFeb 15, 2010
  6. 4/6 rebase: invoke post-rewrite hookThomas Rast, Feb 14, 2010
  7. 5/6 rebase -i: invoke post-rewrite hookThomas Rast, Feb 14, 2010
  8. 6/6 contrib: add a hook that copies notes over rewritesThomas Rast, Feb 14, 2010
  9. Thomas RastFeb 14, 2010
  10. WIP: git notes copy --stdinThomas Rast, Feb 14, 2010
  11. Johan HerlandFeb 15, 2010
  12. 00/11 post-rewrite / automatic notes copyingThomas Rast, Feb 16, 2010
  13. 01/11 Documentation: document post-rewrite hookThomas Rast, Feb 16, 2010
  14. Junio C HamanoFeb 16, 2010
  15. Thomas RastFeb 17, 2010
  16. Junio C HamanoFeb 17, 2010
  17. 02/11 commit --amend: invoke post-rewrite hookThomas Rast, Feb 16, 2010
  18. 03/11 rebase: invoke post-rewrite hookThomas Rast, Feb 16, 2010
  19. 04/11 rebase -i: invoke post-rewrite hookThomas Rast, Feb 16, 2010
  20. 05/11 notes: clean up t3301Thomas Rast, Feb 16, 2010
  21. Junio C HamanoFeb 16, 2010
  22. 06/11 notes: implement 'git notes copy --stdin'Thomas Rast, Feb 16, 2010
  23. 07/11 notes: implement helpers needed for note copying during rewriteThomas Rast, Feb 16, 2010
  24. Junio C HamanoFeb 16, 2010
  25. Thomas RastFeb 17, 2010
  26. Junio C HamanoFeb 17, 2010
  27. Support showing notes from more than one notes treeThomas Rast, Feb 20, 2010
  28. Thomas RastFeb 20, 2010
  29. 08/11 rebase: support automatic notes copyingThomas Rast, Feb 16, 2010
  30. 09/11 commit --amend: copy notes to the new commitThomas Rast, Feb 16, 2010
  31. 10/11 filter-branch: invoke post-rewrite hookThomas Rast, Feb 16, 2010
  32. 11/11 filter-branch: learn how to filter notesThomas Rast, Feb 16, 2010
  33. Johannes SixtFeb 17, 2010
  34. Thomas RastFeb 17, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.