int write_notes_tree(struct notes_tree *t, struct object_id *result) { struct tree_write_stack root; struct write_each_note_data cb_data; int ret; int flags; if (!t) t = &default_notes_tree; assert(t->initialized); /* Prepare for traversal of current notes tree */ root.next = NULL; /* last forward entry in list is grounded */ strbuf_init(&root.buf, 256 * (32 + GIT_SHA1_HEXSZ)); /* assume 256 entries */ root.path[0] = root.path[1] = '\0'; cb_data.root = &root; cb_data.next_non_note = t->first_non_note; /* Write tree objects representing current notes tree */ flags = FOR_EACH_NOTE_DONT_UNPACK_SUBTREES | FOR_EACH_NOTE_YIELD_SUBTREES; ret = for_each_note(t, flags, write_each_note, &cb_data) || write_each_non_note_until(NULL, &cb_data) || tree_write_stack_finish_subtree(&root) || write_object_file(root.buf.buf, root.buf.len, tree_type, result); strbuf_release(&root.buf); return ret; }
static int tree_write_stack_finish_subtree(struct tree_write_stack *tws) { int ret; struct tree_write_stack *n = tws->next; struct object_id s; if (n) { ret = tree_write_stack_finish_subtree(n); if (ret) return ret; ret = write_object_file(n->buf.buf, n->buf.len, tree_type, &s); if (ret) return ret; strbuf_release(&n->buf); free(n); tws->next = NULL; write_tree_entry(&tws->buf, 040000, tws->path, 2, s.hash); tws->path[0] = tws->path[1] = '\0'; } return 0; }
static int tree_write_stack_finish_subtree(struct tree_write_stack *tws) { int ret; struct tree_write_stack *n = tws->next; unsigned char s[20]; if (n) { ret = tree_write_stack_finish_subtree(n); if (ret) return ret; ret = write_sha1_file(n->buf.buf, n->buf.len, tree_type, s); if (ret) return ret; strbuf_release(&n->buf); free(n); tws->next = NULL; write_tree_entry(&tws->buf, 040000, tws->path, 2, s); tws->path[0] = tws->path[1] = '\0'; } return 0; }
static int write_each_note_helper(struct tree_write_stack *tws, const char *path, unsigned int mode, const struct object_id *oid) { size_t path_len = strlen(path); unsigned int n = 0; int ret; /* Determine common part of tree write stack */ while (tws && 3 * n < path_len && matches_tree_write_stack(tws, path + 3 * n)) { n++; tws = tws->next; } /* tws point to last matching tree_write_stack entry */ ret = tree_write_stack_finish_subtree(tws); if (ret) return ret; /* Start subtrees needed to satisfy path */ while (3 * n + 2 < path_len && path[3 * n + 2] == '/') { tree_write_stack_init_subtree(tws, path + 3 * n); n++; tws = tws->next; } /* There should be no more directory components in the given path */ assert(memchr(path + 3 * n, '/', path_len - (3 * n)) == NULL); /* Finally add given entry to the current tree object */ write_tree_entry(&tws->buf, mode, path + 3 * n, path_len - (3 * n), oid->hash); return 0; }