summaryrefslogtreecommitdiff
path: root/notes.c
diff options
context:
space:
mode:
Diffstat (limited to 'notes.c')
-rw-r--r--notes.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/notes.c b/notes.c
index 5f07c0b7f2..2bab961ac1 100644
--- a/notes.c
+++ b/notes.c
@@ -70,7 +70,7 @@ struct non_note {
struct notes_tree default_notes_tree;
-static struct string_list display_notes_refs;
+static struct string_list display_notes_refs = STRING_LIST_INIT_NODUP;
static struct notes_tree **display_notes_trees;
static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
@@ -303,7 +303,7 @@ static int note_tree_insert(struct notes_tree *t, struct int_node *tree,
free(entry);
return 0;
}
- new_node = (struct int_node *) xcalloc(sizeof(struct int_node), 1);
+ new_node = (struct int_node *) xcalloc(1, sizeof(struct int_node));
ret = note_tree_insert(t, new_node, n + 1, l, GET_PTR_TYPE(*p),
combine_notes);
if (ret)
@@ -362,13 +362,14 @@ static int non_note_cmp(const struct non_note *a, const struct non_note *b)
return strcmp(a->path, b->path);
}
-static void add_non_note(struct notes_tree *t, const char *path,
+/* note: takes ownership of path string */
+static void add_non_note(struct notes_tree *t, char *path,
unsigned int mode, const unsigned char *sha1)
{
struct non_note *p = t->prev_non_note, *n;
n = (struct non_note *) xmalloc(sizeof(struct non_note));
n->next = NULL;
- n->path = xstrdup(path);
+ n->path = path;
n->mode = mode;
hashcpy(n->sha1, sha1);
t->prev_non_note = n;
@@ -443,9 +444,9 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
if (len <= 20) {
type = PTR_TYPE_NOTE;
l = (struct leaf_node *)
- xcalloc(sizeof(struct leaf_node), 1);
+ xcalloc(1, sizeof(struct leaf_node));
hashcpy(l->key_sha1, object_sha1);
- hashcpy(l->val_sha1, entry.sha1);
+ hashcpy(l->val_sha1, entry.oid->hash);
if (len < 20) {
if (!S_ISDIR(entry.mode) || path_len != 2)
goto handle_non_note; /* not subtree */
@@ -482,17 +483,17 @@ handle_non_note:
* component.
*/
{
- char non_note_path[PATH_MAX];
- char *p = non_note_path;
+ struct strbuf non_note_path = STRBUF_INIT;
const char *q = sha1_to_hex(subtree->key_sha1);
int i;
for (i = 0; i < prefix_len; i++) {
- *p++ = *q++;
- *p++ = *q++;
- *p++ = '/';
+ strbuf_addch(&non_note_path, *q++);
+ strbuf_addch(&non_note_path, *q++);
+ strbuf_addch(&non_note_path, '/');
}
- strcpy(p, entry.path);
- add_non_note(t, non_note_path, entry.mode, entry.sha1);
+ strbuf_addstr(&non_note_path, entry.path);
+ add_non_note(t, strbuf_detach(&non_note_path, NULL),
+ entry.mode, entry.oid->hash);
}
}
free(buf);
@@ -538,6 +539,9 @@ static unsigned char determine_fanout(struct int_node *tree, unsigned char n,
return fanout + 1;
}
+/* hex SHA1 + 19 * '/' + NUL */
+#define FANOUT_PATH_MAX 40 + 19 + 1
+
static void construct_path_with_fanout(const unsigned char *sha1,
unsigned char fanout, char *path)
{
@@ -550,7 +554,7 @@ static void construct_path_with_fanout(const unsigned char *sha1,
path[i++] = '/';
fanout--;
}
- strcpy(path + i, hex_sha1 + j);
+ xsnprintf(path + i, FANOUT_PATH_MAX - i, "%s", hex_sha1 + j);
}
static int for_each_note_helper(struct notes_tree *t, struct int_node *tree,
@@ -561,7 +565,7 @@ static int for_each_note_helper(struct notes_tree *t, struct int_node *tree,
void *p;
int ret = 0;
struct leaf_node *l;
- static char path[40 + 19 + 1]; /* hex SHA1 + 19 * '/' + NUL */
+ static char path[FANOUT_PATH_MAX];
fanout = determine_fanout(tree, n, fanout);
for (i = 0; i < 16; i++) {
@@ -594,7 +598,7 @@ redo:
/* invoke callback with subtree */
unsigned int path_len =
l->key_sha1[19] * 2 + fanout;
- assert(path_len < 40 + 19);
+ assert(path_len < FANOUT_PATH_MAX - 1);
construct_path_with_fanout(l->key_sha1, fanout,
path);
/* Create trailing slash, if needed */
@@ -902,7 +906,7 @@ int combine_notes_cat_sort_uniq(unsigned char *cur_sha1,
if (string_list_add_note_lines(&sort_uniq_list, new_sha1))
goto out;
string_list_remove_empty_items(&sort_uniq_list, 0);
- sort_string_list(&sort_uniq_list);
+ string_list_sort(&sort_uniq_list);
string_list_remove_duplicates(&sort_uniq_list, 0);
/* create a new blob object from sort_uniq_list */
@@ -918,7 +922,7 @@ out:
return ret;
}
-static int string_list_add_one_ref(const char *refname, const unsigned char *sha1,
+static int string_list_add_one_ref(const char *refname, const struct object_id *oid,
int flag, void *cb)
{
struct string_list *refs = cb;
@@ -989,7 +993,7 @@ const char *default_notes_ref(void)
void init_notes(struct notes_tree *t, const char *notes_ref,
combine_notes_fn combine_notes, int flags)
{
- unsigned char sha1[20], object_sha1[20];
+ struct object_id oid, object_oid;
unsigned mode;
struct leaf_node root_tree;
@@ -1003,35 +1007,38 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
if (!combine_notes)
combine_notes = combine_notes_concatenate;
- t->root = (struct int_node *) xcalloc(sizeof(struct int_node), 1);
+ t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node));
t->first_non_note = NULL;
t->prev_non_note = NULL;
- t->ref = notes_ref ? xstrdup(notes_ref) : NULL;
+ t->ref = xstrdup_or_null(notes_ref);
+ t->update_ref = (flags & NOTES_INIT_WRITABLE) ? t->ref : NULL;
t->combine_notes = combine_notes;
t->initialized = 1;
t->dirty = 0;
if (flags & NOTES_INIT_EMPTY || !notes_ref ||
- read_ref(notes_ref, object_sha1))
+ get_sha1_treeish(notes_ref, object_oid.hash))
return;
- if (get_tree_entry(object_sha1, "", sha1, &mode))
+ if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, object_oid.hash))
+ die("Cannot use notes ref %s", notes_ref);
+ if (get_tree_entry(object_oid.hash, "", oid.hash, &mode))
die("Failed to read notes tree referenced by %s (%s)",
- notes_ref, sha1_to_hex(object_sha1));
+ notes_ref, oid_to_hex(&object_oid));
hashclr(root_tree.key_sha1);
- hashcpy(root_tree.val_sha1, sha1);
+ hashcpy(root_tree.val_sha1, oid.hash);
load_subtree(t, &root_tree, t->root, 0);
}
-struct notes_tree **load_notes_trees(struct string_list *refs)
+struct notes_tree **load_notes_trees(struct string_list *refs, int flags)
{
struct string_list_item *item;
int counter = 0;
struct notes_tree **trees;
- trees = xmalloc((refs->nr+1) * sizeof(struct notes_tree *));
+ ALLOC_ARRAY(trees, refs->nr + 1);
for_each_string_list_item(item, refs) {
struct notes_tree *t = xcalloc(1, sizeof(struct notes_tree));
- init_notes(t, item->string, combine_notes_ignore, 0);
+ init_notes(t, item->string, combine_notes_ignore, flags);
trees[counter++] = t;
}
trees[counter] = NULL;
@@ -1067,7 +1074,7 @@ void init_display_notes(struct display_notes_opt *opt)
item->string);
}
- display_notes_trees = load_notes_trees(&display_notes_refs);
+ display_notes_trees = load_notes_trees(&display_notes_refs, 0);
string_list_clear(&display_notes_refs, 0);
}
@@ -1218,8 +1225,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1,
if (!sha1)
return;
- if (!(msg = read_sha1_file(sha1, &type, &msglen)) || !msglen ||
- type != OBJ_BLOB) {
+ if (!(msg = read_sha1_file(sha1, &type, &msglen)) || type != OBJ_BLOB) {
free(msg);
return;
}
@@ -1300,3 +1306,13 @@ void expand_notes_ref(struct strbuf *sb)
else
strbuf_insert(sb, 0, "refs/notes/", 11);
}
+
+void expand_loose_notes_ref(struct strbuf *sb)
+{
+ unsigned char object[20];
+
+ if (get_sha1(sb->buf, object)) {
+ /* fallback to expand_notes_ref */
+ expand_notes_ref(sb);
+ }
+}