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 get_commit_notes(const struct commit
*commit
, struct strbuf
*sb
,
109 const char *output_encoding
)
111 static const char *utf8
= "utf-8";
114 unsigned long linelen
, msglen
;
115 enum object_type type
;
118 const char *env
= getenv(GIT_NOTES_REF_ENVIRONMENT
);
120 notes_ref_name
= getenv(GIT_NOTES_REF_ENVIRONMENT
);
121 else if (!notes_ref_name
)
122 notes_ref_name
= GIT_NOTES_DEFAULT_REF
;
123 initialize_hash_map(notes_ref_name
);
127 sha1
= lookup_notes(commit
->object
.sha1
);
131 if (!(msg
= read_sha1_file(sha1
, &type
, &msglen
)) || !msglen
||
135 if (output_encoding
&& *output_encoding
&&
136 strcmp(utf8
, output_encoding
)) {
137 char *reencoded
= reencode_string(msg
, output_encoding
, utf8
);
141 msglen
= strlen(msg
);
145 /* we will end the annotation by a newline anyway */
146 if (msglen
&& msg
[msglen
- 1] == '\n')
149 strbuf_addstr(sb
, "\nNotes:\n");
151 for (msg_p
= msg
; msg_p
< msg
+ msglen
; msg_p
+= linelen
+ 1) {
152 linelen
= strchrnul(msg_p
, '\n') - msg_p
;
154 strbuf_addstr(sb
, " ");
155 strbuf_add(sb
, msg_p
, linelen
);
156 strbuf_addch(sb
, '\n');