while (tree_entry(&desc, &entry)) {
unsigned char type;
struct leaf_node *l;
- int len, path_len = strlen(entry.path);
+ int path_len = strlen(entry.path);
+
+ if (path_len == 2 * (GIT_SHA1_RAWSZ - prefix_len)) {
+ /* This is potentially the remainder of the SHA-1 */
+ if (get_oid_hex_segment(entry.path, path_len,
+ object_oid.hash + prefix_len,
+ GIT_SHA1_RAWSZ - prefix_len) < 0)
+ goto handle_non_note; /* entry.path is not a SHA1 */
+
+ type = PTR_TYPE_NOTE;
+ l = (struct leaf_node *)
+ xcalloc(1, sizeof(struct leaf_node));
+ oidcpy(&l->key_oid, &object_oid);
+ oidcpy(&l->val_oid, entry.oid);
+ } else if (path_len == 2) {
+ /* This is potentially an internal node */
+
+ if (!S_ISDIR(entry.mode))
+ /* internal nodes must be trees */
+ goto handle_non_note;
+
+ if (get_oid_hex_segment(entry.path, 2,
+ object_oid.hash + prefix_len,
+ GIT_SHA1_RAWSZ - prefix_len) < 0)
+ goto handle_non_note; /* entry.path is not a SHA1 */
- len = get_oid_hex_segment(entry.path, path_len,
- object_oid.hash + prefix_len, GIT_SHA1_RAWSZ - prefix_len);
- if (len < 0)
- goto handle_non_note; /* entry.path is not a SHA1 */
- len += prefix_len;
-
- /*
- * If object SHA1 is complete (len == 20), assume note object
- * If object SHA1 is incomplete (len < 20), and current
- * component consists of 2 hex chars, assume note subtree
- */
- type = PTR_TYPE_NOTE;
- l = (struct leaf_node *)
- xcalloc(1, sizeof(struct leaf_node));
- oidcpy(&l->key_oid, &object_oid);
- oidcpy(&l->val_oid, entry.oid);
- if (len < GIT_SHA1_RAWSZ) {
- if (!S_ISDIR(entry.mode) || path_len != 2)
- goto handle_non_note; /* not subtree */
- l->key_oid.hash[KEY_INDEX] = (unsigned char) len;
type = PTR_TYPE_SUBTREE;
+ l = (struct leaf_node *)
+ xcalloc(1, sizeof(struct leaf_node));
+ oidcpy(&l->key_oid, &object_oid);
+ oidcpy(&l->val_oid, entry.oid);
+ l->key_oid.hash[KEY_INDEX] = (unsigned char) (prefix_len + 1);
+ } else {
+ /* This can't be part of a note */
+ goto handle_non_note;
}
+
if (note_tree_insert(t, node, n, l, type,
combine_notes_concatenate))
die("Failed to load %s %s into notes tree "
handle_non_note:
/*
- * Determine full path for this non-note entry:
- * The filename is already found in entry.path, but the
- * directory part of the path must be deduced from the subtree
- * containing this entry. We assume here that the overall notes
- * tree follows a strict byte-based progressive fanout
- * structure (i.e. using 2/38, 2/2/36, etc. fanouts, and not
- * e.g. 4/36 fanout). This means that if a non-note is found at
- * path "dead/beef", the following code will register it as
- * being found on "de/ad/beef".
- * On the other hand, if you use such non-obvious non-note
- * paths in the middle of a notes tree, you deserve what's
- * coming to you ;). Note that for non-notes that are not
- * SHA1-like at the top level, there will be no problems.
- *
- * To conclude, it is strongly advised to make sure non-notes
- * have at least one non-hex character in the top-level path
- * component.
+ * Determine full path for this non-note entry. The
+ * filename is already found in entry.path, but the
+ * directory part of the path must be deduced from the
+ * subtree containing this entry based on our
+ * knowledge that the overall notes tree follows a
+ * strict byte-based progressive fanout structure
+ * (i.e. using 2/38, 2/2/36, etc. fanouts).
*/
{
struct strbuf non_note_path = STRBUF_INIT;