[RFC PATCH 2/2] notes: create interface to iterate over notes for a given oid

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



format_display_notes() outputs notes in a specific format which is
suitable for displaying in a terminal with "git log"/"git show". Other
users may want a different format.

This patch adds a new function -- for_each_oid_note() -- which, given the
oid for a commit, iterates over notes refs and calls the given callback
function for each note ref that contains a corresponding note.

The old functionality can easily be implemented using the new interface,
so I'm doing that at the same time.

Cc: Johan Herland <johan@xxxxxxxxxxx>
Cc: Jason A. Donenfeld <Jason@xxxxxxxxx>
Cc: Christian Hesse <mail@xxxxxxxx>
Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxxx>
---
 notes.c | 108 ++++++++++++++++++++++++++++++++++----------------------
 notes.h |   5 +++
 2 files changed, 70 insertions(+), 43 deletions(-)

diff --git a/notes.c b/notes.c
index 90ec625192..4c7e883758 100644
--- a/notes.c
+++ b/notes.c
@@ -1242,56 +1242,68 @@ void free_notes(struct notes_tree *t)
 	memset(t, 0, sizeof(struct notes_tree));
 }
 
-/*
- * Fill the given strbuf with the notes associated with the given object.
- *
- * If the given notes_tree structure is not initialized, it will be auto-
- * initialized to the default value (see documentation for init_notes() above).
- * If the given notes_tree is NULL, the internal/default notes_tree will be
- * used instead.
- *
- * (raw != 0) gives the %N userformat; otherwise, the note message is given
- * for human consumption.
- */
-static void format_note(struct notes_tree *t, const struct object_id *object_oid,
-			struct strbuf *sb, const char *output_encoding, int raw)
+void for_each_oid_note(const struct object_id *object_oid,
+		       const char *output_encoding, int raw,
+		       each_oid_note_fn fn, void *cb_data)
 {
 	static const char utf8[] = "utf-8";
-	const struct object_id *oid;
-	char *msg, *msg_p;
-	unsigned long linelen, msglen;
-	enum object_type type;
 
-	if (!t)
-		t = &default_notes_tree;
-	if (!t->initialized)
-		init_notes(t, NULL, NULL, 0);
+	int i;
+	assert(display_notes_trees);
+	for (i = 0; display_notes_trees[i]; i++) {
+		struct notes_tree *t = display_notes_trees[i];
+		const struct object_id *oid;
+		char *msg;
+		unsigned long msglen;
+		enum object_type type;
+
+		if (!t)
+			t = &default_notes_tree;
+		if (!t->initialized)
+			init_notes(t, NULL, NULL, 0);
+
+		oid = get_note(t, object_oid);
+		if (!oid)
+			continue;
 
-	oid = get_note(t, object_oid);
-	if (!oid)
-		return;
+		if (!(msg = read_object_file(oid, &type, &msglen)) || type != OBJ_BLOB) {
+			free(msg);
+			continue;
+		}
+
+		if (output_encoding && *output_encoding &&
+		    !is_encoding_utf8(output_encoding)) {
+			char *reencoded = reencode_string(msg, output_encoding, utf8);
+			if (reencoded) {
+				free(msg);
+				msg = reencoded;
+				msglen = strlen(msg);
+			}
+		}
 
-	if (!(msg = read_object_file(oid, &type, &msglen)) || type != OBJ_BLOB) {
+		fn(t->ref, msg, msglen, cb_data);
 		free(msg);
-		return;
 	}
+}
 
-	if (output_encoding && *output_encoding &&
-	    !is_encoding_utf8(output_encoding)) {
-		char *reencoded = reencode_string(msg, output_encoding, utf8);
-		if (reencoded) {
-			free(msg);
-			msg = reencoded;
-			msglen = strlen(msg);
-		}
-	}
+struct format_display_notes_cb {
+	int raw;
+	struct strbuf *output;
+};
+
+static void format_note(const char *ref, const char *msg, unsigned long msglen, void *cb_data)
+{
+	struct format_display_notes_cb *cb = cb_data;
+	int raw = cb->raw;
+	struct strbuf *sb = cb->output;
+	const char *msg_p;
+	unsigned long linelen;
 
 	/* we will end the annotation by a newline anyway */
 	if (msglen && msg[msglen - 1] == '\n')
 		msglen--;
 
 	if (!raw) {
-		const char *ref = t->ref;
 		if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) {
 			strbuf_addstr(sb, "\nNotes:\n");
 		} else {
@@ -1309,18 +1321,28 @@ static void format_note(struct notes_tree *t, const struct object_id *object_oid
 		strbuf_add(sb, msg_p, linelen);
 		strbuf_addch(sb, '\n');
 	}
-
-	free(msg);
 }
 
+/*
+ * Fill the given strbuf with the notes associated with the given object.
+ *
+ * If the given notes_tree structure is not initialized, it will be auto-
+ * initialized to the default value (see documentation for init_notes() above).
+ * If the given notes_tree is NULL, the internal/default notes_tree will be
+ * used instead.
+ *
+ * (raw != 0) gives the %N userformat; otherwise, the note message is given
+ * for human consumption.
+ */
 void format_display_notes(const struct object_id *object_oid,
 			  struct strbuf *sb, const char *output_encoding, int raw)
 {
-	int i;
-	assert(display_notes_trees);
-	for (i = 0; display_notes_trees[i]; i++)
-		format_note(display_notes_trees[i], object_oid, sb,
-			    output_encoding, raw);
+	struct format_display_notes_cb cb = {
+		.raw = raw,
+		.output = sb,
+	};
+
+	for_each_oid_note(object_oid, output_encoding, raw, format_note, &cb);
 }
 
 int copy_note(struct notes_tree *t,
diff --git a/notes.h b/notes.h
index c7aae85ea6..833af94fae 100644
--- a/notes.h
+++ b/notes.h
@@ -309,6 +309,11 @@ void load_display_notes(struct display_notes_opt *opt);
 void format_display_notes(const struct object_id *object_oid,
 			  struct strbuf *sb, const char *output_encoding, int raw);
 
+typedef void (*each_oid_note_fn)(const char *ref, const char *msg, unsigned long msglen, void *cb_data);
+
+void for_each_oid_note(const struct object_id *object_oid,
+		       const char *output_encoding, int raw, each_oid_note_fn fn, void *cb_data);
+
 /*
  * Load the notes tree from each ref listed in 'refs'.  The output is
  * an array of notes_tree*, terminated by a NULL.
-- 
2.35.1.46.g38062e73e0




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux