notes.h 11.8 KB
Newer Older
Johannes Schindelin's avatar
Johannes Schindelin committed
1 2 3
#ifndef NOTES_H
#define NOTES_H

4 5
#include "string-list.h"

6 7 8 9 10 11
/*
 * Function type for combining two notes annotating the same object.
 *
 * When adding a new note annotating the same object as an existing note, it is
 * up to the caller to decide how to combine the two notes. The decision is
 * made by passing in a function of the following form. The function accepts
12
 * two object_ids -- of the existing note and the new note, respectively. The
13
 * function then combines the notes in whatever way it sees fit, and writes the
14
 * resulting oid into the first argument (cur_oid). A non-zero return
15 16
 * value indicates failure.
 *
17 18 19
 * The two given object_ids shall both be non-NULL and different from each
 * other. Either of them (but not both) may be == null_oid, which indicates an
 * empty/non-existent note. If the resulting oid (cur_oid) is == null_oid,
20
 * the note will be removed from the notes tree.
21 22 23 24 25
 *
 * The default combine_notes function (you get this when passing NULL) is
 * combine_notes_concatenate(), which appends the contents of the new note to
 * the contents of the existing note.
 */
26 27
typedef int (*combine_notes_fn)(struct object_id *cur_oid,
				const struct object_id *new_oid);
28 29

/* Common notes combinators */
30 31 32 33 34 35 36 37
int combine_notes_concatenate(struct object_id *cur_oid,
			      const struct object_id *new_oid);
int combine_notes_overwrite(struct object_id *cur_oid,
			    const struct object_id *new_oid);
int combine_notes_ignore(struct object_id *cur_oid,
			 const struct object_id *new_oid);
int combine_notes_cat_sort_uniq(struct object_id *cur_oid,
				const struct object_id *new_oid);
38

39 40 41 42 43 44 45 46 47 48 49
/*
 * Notes tree object
 *
 * Encapsulates the internal notes tree structure associated with a notes ref.
 * Whenever a struct notes_tree pointer is required below, you may pass NULL in
 * order to use the default/internal notes tree. E.g. you only need to pass a
 * non-NULL value if you need to refer to several different notes trees
 * simultaneously.
 */
extern struct notes_tree {
	struct int_node *root;
50
	struct non_note *first_non_note, *prev_non_note;
51
	char *ref;
52
	char *update_ref;
53
	combine_notes_fn combine_notes;
54
	int initialized;
55
	int dirty;
56 57
} default_notes_tree;

58 59 60 61 62 63 64 65 66 67 68 69 70 71
/*
 * Return the default notes ref.
 *
 * The default notes ref is the notes ref that is used when notes_ref == NULL
 * is passed to init_notes().
 *
 * This the first of the following to be defined:
 * 1. The '--ref' option to 'git notes', if given
 * 2. The $GIT_NOTES_REF environment variable, if set
 * 3. The value of the core.notesRef config variable, if set
 * 4. GIT_NOTES_DEFAULT_REF (i.e. "refs/notes/commits")
 */
const char *default_notes_ref(void);

72 73 74 75 76 77 78 79
/*
 * Flags controlling behaviour of notes tree initialization
 *
 * Default behaviour is to initialize the notes tree from the tree object
 * specified by the given (or default) notes ref.
 */
#define NOTES_INIT_EMPTY 1

80 81 82 83 84 85 86
/*
 * By default, the notes tree is only readable, and the notes ref can be
 * any treeish. The notes tree can however be made writable with this flag,
 * in which case only strict ref names can be used.
 */
#define NOTES_INIT_WRITABLE 2

87
/*
88
 * Initialize the given notes_tree with the notes tree structure at the given
89 90 91 92
 * ref. If given ref is NULL, the value of the $GIT_NOTES_REF environment
 * variable is used, and if that is missing, the default notes ref is used
 * ("refs/notes/commits").
 *
Ondřej Bílka's avatar
Ondřej Bílka committed
93
 * If you need to re-initialize a notes_tree structure (e.g. when switching from
94 95 96 97 98
 * one notes ref to another), you must first de-initialize the notes_tree
 * structure by calling free_notes(struct notes_tree *).
 *
 * If you pass t == NULL, the default internal notes_tree will be initialized.
 *
99 100 101 102
 * The combine_notes function that is passed becomes the default combine_notes
 * function for the given notes_tree. If NULL is passed, the default
 * combine_notes function is combine_notes_concatenate().
 *
103 104
 * Precondition: The notes_tree structure is zeroed (this can be achieved with
 * memset(t, 0, sizeof(struct notes_tree)))
105
 */
106 107
void init_notes(struct notes_tree *t, const char *notes_ref,
		combine_notes_fn combine_notes, int flags);
108

109
/*
110
 * Add the given note object to the given notes_tree structure
111
 *
112 113 114 115 116 117 118 119 120 121 122
 * If there already exists a note for the given object_sha1, the given
 * combine_notes function is invoked to break the tie. If not given (i.e.
 * combine_notes == NULL), the default combine_notes function for the given
 * notes_tree is used.
 *
 * Passing note_sha1 == null_sha1 indicates the addition of an
 * empty/non-existent note. This is a (potentially expensive) no-op unless
 * there already exists a note for the given object_sha1, AND combining that
 * note with the empty note (using the given combine_notes function) results
 * in a new/changed note.
 *
123 124
 * Returns zero on success; non-zero means combine_notes failed.
 *
125
 * IMPORTANT: The changes made by add_note() to the given notes_tree structure
126 127 128
 * are not persistent until a subsequent call to write_notes_tree() returns
 * zero.
 */
129 130
int add_note(struct notes_tree *t, const struct object_id *object_oid,
		const struct object_id *note_oid, combine_notes_fn combine_notes);
131

132
/*
133
 * Remove the given note object from the given notes_tree structure
134
 *
135
 * IMPORTANT: The changes made by remove_note() to the given notes_tree
136 137
 * structure are not persistent until a subsequent call to write_notes_tree()
 * returns zero.
138 139
 *
 * Return 0 if a note was removed; 1 if there was no note to remove.
140
 */
141
int remove_note(struct notes_tree *t, const unsigned char *object_sha1);
142

143 144 145 146 147
/*
 * Get the note object SHA1 containing the note data for the given object
 *
 * Return NULL if the given object has no notes.
 */
148
const struct object_id *get_note(struct notes_tree *t,
149
		const struct object_id *object_oid);
150

151 152 153
/*
 * Copy a note from one object to another in the given notes_tree.
 *
154 155 156 157
 * Returns 1 if the to_obj already has a note and 'force' is false. Otherwise,
 * returns non-zero if 'force' is true, but the given combine_notes function
 * failed to combine from_obj's note with to_obj's existing note.
 * Returns zero on success.
158 159 160 161
 *
 * IMPORTANT: The changes made by copy_note() to the given notes_tree structure
 * are not persistent until a subsequent call to write_notes_tree() returns
 * zero.
162 163
 */
int copy_note(struct notes_tree *t,
164
	      const struct object_id *from_obj, const struct object_id *to_obj,
165
	      int force, combine_notes_fn combine_notes);
166

167 168 169 170
/*
 * Flags controlling behaviour of for_each_note()
 *
 * Default behaviour of for_each_note() is to traverse every single note object
171
 * in the given notes tree, unpacking subtree entries along the way.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
 * The following flags can be used to alter the default behaviour:
 *
 * - DONT_UNPACK_SUBTREES causes for_each_note() NOT to unpack and recurse into
 *   subtree entries while traversing the notes tree. This causes notes within
 *   those subtrees NOT to be passed to the callback. Use this flag if you
 *   don't want to traverse _all_ notes, but only want to traverse the parts
 *   of the notes tree that have already been unpacked (this includes at least
 *   all notes that have been added/changed).
 *
 * - YIELD_SUBTREES causes any subtree entries that are encountered to be
 *   passed to the callback, before recursing into them. Subtree entries are
 *   not note objects, but represent intermediate directories in the notes
 *   tree. When passed to the callback, subtree entries will have a trailing
 *   slash in their path, which the callback may use to differentiate between
 *   note entries and subtree entries. Note that already-unpacked subtree
 *   entries are not part of the notes tree, and will therefore not be yielded.
 *   If this flag is used together with DONT_UNPACK_SUBTREES, for_each_note()
 *   will yield the subtree entry, but not recurse into it.
 */
#define FOR_EACH_NOTE_DONT_UNPACK_SUBTREES 1
#define FOR_EACH_NOTE_YIELD_SUBTREES 2

/*
195
 * Invoke the specified callback function for each note in the given notes_tree
196 197 198 199 200 201 202 203 204 205 206
 *
 * If the callback returns nonzero, the note walk is aborted, and the return
 * value from the callback is returned from for_each_note(). Hence, a zero
 * return value from for_each_note() indicates that all notes were walked
 * successfully.
 *
 * IMPORTANT: The callback function is NOT allowed to change the notes tree.
 * In other words, the following functions can NOT be invoked (on the current
 * notes tree) from within the callback:
 * - add_note()
 * - remove_note()
207
 * - copy_note()
208 209
 * - free_notes()
 */
210 211
typedef int each_note_fn(const struct object_id *object_oid,
		const struct object_id *note_oid, char *note_path,
212
		void *cb_data);
213 214
int for_each_note(struct notes_tree *t, int flags, each_note_fn fn,
		void *cb_data);
215

216
/*
217
 * Write the given notes_tree structure to the object database
218
 *
219
 * Creates a new tree object encapsulating the current state of the given
220
 * notes_tree, and stores its object id into the 'result' argument.
221 222 223
 *
 * Returns zero on success, non-zero on failure.
 *
224 225 226
 * IMPORTANT: Changes made to the given notes_tree are not persistent until
 * this function has returned zero. Please also remember to create a
 * corresponding commit object, and update the appropriate notes ref.
227
 */
228
int write_notes_tree(struct notes_tree *t, struct object_id *result);
229

230 231 232
/* Flags controlling the operation of prune */
#define NOTES_PRUNE_VERBOSE 1
#define NOTES_PRUNE_DRYRUN 2
233 234 235 236 237 238 239 240 241 242
/*
 * Remove all notes annotating non-existing objects from the given notes tree
 *
 * All notes in the given notes_tree that are associated with objects that no
 * longer exist in the database, are removed from the notes tree.
 *
 * IMPORTANT: The changes made by prune_notes() to the given notes_tree
 * structure are not persistent until a subsequent call to write_notes_tree()
 * returns zero.
 */
243
void prune_notes(struct notes_tree *t, int flags);
244

245
/*
246
 * Free (and de-initialize) the given notes_tree structure
247
 *
248
 * IMPORTANT: Changes made to the given notes_tree since the last, successful
249 250
 * call to write_notes_tree() will be lost.
 */
251
void free_notes(struct notes_tree *t);
252

253 254 255
struct string_list;

struct display_notes_opt {
256
	int use_default_notes;
257
	struct string_list extra_notes_refs;
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
};

/*
 * 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.
 */
285
void format_display_notes(const struct object_id *object_oid,
Junio C Hamano's avatar
Junio C Hamano committed
286
			  struct strbuf *sb, const char *output_encoding, int raw);
287 288 289 290 291

/*
 * Load the notes tree from each ref listed in 'refs'.  The output is
 * an array of notes_tree*, terminated by a NULL.
 */
292
struct notes_tree **load_notes_trees(struct string_list *refs, int flags);
293 294 295 296 297 298 299 300 301 302 303 304 305 306

/*
 * 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);

307 308 309
/* Expand inplace a note ref like "foo" or "notes/foo" into "refs/notes/foo" */
void expand_notes_ref(struct strbuf *sb);

310 311 312 313 314 315 316
/*
 * Similar to expand_notes_ref, but will check whether the ref can be located
 * via get_sha1 first, and only falls back to expand_notes_ref in the case
 * where get_sha1 fails.
 */
void expand_loose_notes_ref(struct strbuf *sb);

Johannes Schindelin's avatar
Johannes Schindelin committed
317
#endif