10 unsigned char commit_sha1
[20];
11 unsigned char notes_sha1
[20];
15 struct entry
*entries
;
19 static int initialized
;
20 static struct hash_map hash_map
;
22 static int hash_index(struct hash_map
*map
, const unsigned char *sha1
)
24 int i
= ((*(unsigned int *)sha1
) % map
->size
);
27 unsigned char *current
= map
->entries
[i
].commit_sha1
;
29 if (!hashcmp(sha1
, current
))
32 if (is_null_sha1(current
))
40 static void add_entry(const unsigned char *commit_sha1
,
41 const unsigned char *notes_sha1
)
45 if (hash_map
.count
+ 1 > hash_map
.size
>> 1) {
46 int i
, old_size
= hash_map
.size
;
47 struct entry
*old
= hash_map
.entries
;
49 hash_map
.size
= old_size
? old_size
<< 1 : 64;
50 hash_map
.entries
= (struct entry
*)
51 xcalloc(sizeof(struct entry
), hash_map
.size
);
53 for (i
= 0; i
< old_size
; i
++)
54 if (!is_null_sha1(old
[i
].commit_sha1
)) {
55 index
= -1 - hash_index(&hash_map
,
57 memcpy(hash_map
.entries
+ index
, old
+ i
,
58 sizeof(struct entry
));
63 index
= hash_index(&hash_map
, commit_sha1
);
69 hashcpy(hash_map
.entries
[index
].commit_sha1
, commit_sha1
);
70 hashcpy(hash_map
.entries
[index
].notes_sha1
, notes_sha1
);
73 static void initialize_hash_map(const char *notes_ref_name
)
75 unsigned char sha1
[20], commit_sha1
[20];
77 struct tree_desc desc
;
78 struct name_entry entry
;
81 if (!notes_ref_name
|| read_ref(notes_ref_name
, commit_sha1
) ||
82 get_tree_entry(commit_sha1
, "", sha1
, &mode
))
85 buf
= fill_tree_descriptor(&desc
, sha1
);
87 die("Could not read %s for notes-index", sha1_to_hex(sha1
));
89 while (tree_entry(&desc
, &entry
))
90 if (!get_sha1(entry
.path
, commit_sha1
))
91 add_entry(commit_sha1
, entry
.sha1
);
95 static unsigned char *lookup_notes(const unsigned char *commit_sha1
)
102 index
= hash_index(&hash_map
, commit_sha1
);
105 return hash_map
.entries
[index
].notes_sha1
;
108 void free_notes(void)
110 free(hash_map
.entries
);
111 memset(&hash_map
, 0, sizeof(struct hash_map
));
115 void get_commit_notes(const struct commit
*commit
, struct strbuf
*sb
,
116 const char *output_encoding
, int flags
)
118 static const char utf8
[] = "utf-8";
121 unsigned long linelen
, msglen
;
122 enum object_type type
;
125 const char *env
= getenv(GIT_NOTES_REF_ENVIRONMENT
);
127 notes_ref_name
= getenv(GIT_NOTES_REF_ENVIRONMENT
);
128 else if (!notes_ref_name
)
129 notes_ref_name
= GIT_NOTES_DEFAULT_REF
;
130 initialize_hash_map(notes_ref_name
);
134 sha1
= lookup_notes(commit
->object
.sha1
);
138 if (!(msg
= read_sha1_file(sha1
, &type
, &msglen
)) || !msglen
||
144 if (output_encoding
&& *output_encoding
&&
145 strcmp(utf8
, output_encoding
)) {
146 char *reencoded
= reencode_string(msg
, output_encoding
, utf8
);
150 msglen
= strlen(msg
);
154 /* we will end the annotation by a newline anyway */
155 if (msglen
&& msg
[msglen
- 1] == '\n')
158 if (flags
& NOTES_SHOW_HEADER
)
159 strbuf_addstr(sb
, "\nNotes:\n");
161 for (msg_p
= msg
; msg_p
< msg
+ msglen
; msg_p
+= linelen
+ 1) {
162 linelen
= strchrnul(msg_p
, '\n') - msg_p
;
164 if (flags
& NOTES_INDENT
)
165 strbuf_addstr(sb
, " ");
166 strbuf_add(sb
, msg_p
, linelen
);
167 strbuf_addch(sb
, '\n');