notes.h 11.8 KB
Newer Older
1 2 3
#ifndef NOTES_H
#define NOTES_H

4 5
#include "string-list.h"

6 7 8
struct object_id;
struct strbuf;

9 10 11 12 13 14
/*
 * 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
15
 * two object_ids -- of the existing note and the new note, respectively. The
16
 * function then combines the notes in whatever way it sees fit, and writes the
17
 * resulting oid into the first argument (cur_oid). A non-zero return
18 19
 * value indicates failure.
 *
20 21 22
 * 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,
23
 * the note will be removed from the notes tree.
24 25 26 27 28
 *
 * 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.
 */
29 30
typedef int (*combine_notes_fn)(struct object_id *cur_oid,
				const struct object_id *new_oid);
31 32

/* Common notes combinators */
33 34 35 36 37 38 39 40
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);
41

42 43 44 45 46 47 48 49 50 51 52
/*
 * 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;
53
	struct non_note *first_non_note, *prev_non_note;
54
	char *ref;
55
	char *update_ref;
56
	combine_notes_fn combine_notes;
57
	int initialized;
58
	int dirty;
59 60
} default_notes_tree;

61 62 63 64 65 66 67 68 69 70 71 72 73 74
/*
 * 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);

75 76 77 78 79 80 81 82
/*
 * 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

83 84 85 86 87 88 89
/*
 * 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

90
/*
91
 * Initialize the given notes_tree with the notes tree structure at the given
92 93 94 95
 * 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
96
 * If you need to re-initialize a notes_tree structure (e.g. when switching from
97 98 99 100 101
 * 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.
 *
102 103 104 105
 * 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().
 *
106 107
 * Precondition: The notes_tree structure is zeroed (this can be achieved with
 * memset(t, 0, sizeof(struct notes_tree)))
108
 */
109 110
void init_notes(struct notes_tree *t, const char *notes_ref,
		combine_notes_fn combine_notes, int flags);
111

112
/*
113
 * Add the given note object to the given notes_tree structure
114
 *
115 116 117 118 119 120 121 122 123 124 125
 * 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.
 *
126 127
 * Returns zero on success; non-zero means combine_notes failed.
 *
128
 * IMPORTANT: The changes made by add_note() to the given notes_tree structure
129 130 131
 * are not persistent until a subsequent call to write_notes_tree() returns
 * zero.
 */
132 133
int add_note(struct notes_tree *t, const struct object_id *object_oid,
		const struct object_id *note_oid, combine_notes_fn combine_notes);
134

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

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

154 155 156
/*
 * Copy a note from one object to another in the given notes_tree.
 *
157 158 159 160
 * 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.
161 162 163 164
 *
 * 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.
165 166
 */
int copy_note(struct notes_tree *t,
167
	      const struct object_id *from_obj, const struct object_id *to_obj,
168
	      int force, combine_notes_fn combine_notes);
169

170 171 172 173
/*
 * Flags controlling behaviour of for_each_note()
 *
 * Default behaviour of for_each_note() is to traverse every single note object
174
 * in the given notes tree, unpacking subtree entries along the way.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
 * 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

/*
198
 * Invoke the specified callback function for each note in the given notes_tree
199 200 201 202 203 204 205 206 207 208 209
 *
 * 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()
210
 * - copy_note()
211 212
 * - free_notes()
 */
213 214
typedef int each_note_fn(const struct object_id *object_oid,
		const struct object_id *note_oid, char *note_path,
215
		void *cb_data);
216 217
int for_each_note(struct notes_tree *t, int flags, each_note_fn fn,
		void *cb_data);
218

219
/*
220
 * Write the given notes_tree structure to the object database
221
 *
222
 * Creates a new tree object encapsulating the current state of the given
223
 * notes_tree, and stores its object id into the 'result' argument.
224 225 226
 *
 * Returns zero on success, non-zero on failure.
 *
227 228 229
 * 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.
230
 */
231
int write_notes_tree(struct notes_tree *t, struct object_id *result);
232

233 234 235
/* Flags controlling the operation of prune */
#define NOTES_PRUNE_VERBOSE 1
#define NOTES_PRUNE_DRYRUN 2
236 237 238 239 240 241 242 243 244 245
/*
 * 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.
 */
246
void prune_notes(struct notes_tree *t, int flags);
247

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

256 257 258
struct string_list;

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

/*
 * 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.
 */
288
void format_display_notes(const struct object_id *object_oid,
289
			  struct strbuf *sb, const char *output_encoding, int raw);
290 291 292 293 294

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

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

310 311 312
/* Expand inplace a note ref like "foo" or "notes/foo" into "refs/notes/foo" */
void expand_notes_ref(struct strbuf *sb);

313 314 315 316 317 318 319
/*
 * 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);

320
#endif