1
#include "cache.h"
2
#include "notes.h"
3
+#include "blob.h"
4
#include "tree.h"
5
#include "utf8.h"
6
#include "strbuf.h"
128
return NULL;
129
}
130
130
-/* Create a new blob object by concatenating the two given blob objects */
131
-static int concatenate_notes(unsigned char *cur_sha1,
132
- const unsigned char *new_sha1)
133
-{
134
- char *cur_msg, *new_msg, *buf;
135
- unsigned long cur_len, new_len, buf_len;
136
- enum object_type cur_type, new_type;
137
- int ret;
138
-
139
- /* read in both note blob objects */
140
- new_msg = read_sha1_file(new_sha1, &new_type, &new_len);
141
- if (!new_msg || !new_len || new_type != OBJ_BLOB) {
142
- free(new_msg);
143
- return 0;
144
- }
145
- cur_msg = read_sha1_file(cur_sha1, &cur_type, &cur_len);
146
- if (!cur_msg || !cur_len || cur_type != OBJ_BLOB) {
147
- free(cur_msg);
148
- free(new_msg);
149
- hashcpy(cur_sha1, new_sha1);
150
- return 0;
151
- }
152
-
153
- /* we will separate the notes by a newline anyway */
154
- if (cur_msg[cur_len - 1] == '\n')
155
- cur_len--;
156
-
157
- /* concatenate cur_msg and new_msg into buf */
158
- buf_len = cur_len + 1 + new_len;
159
- buf = (char *) xmalloc(buf_len);
160
- memcpy(buf, cur_msg, cur_len);
161
- buf[cur_len] = '\n';
162
- memcpy(buf + cur_len + 1, new_msg, new_len);
163
-
164
- free(cur_msg);
165
- free(new_msg);
166
-
167
- /* create a new blob object from buf */
168
- ret = write_sha1_file(buf, buf_len, "blob", cur_sha1);
169
- free(buf);
170
- return ret;
171
-}
172
-
131
/*
132
* To insert a leaf_node:
133
* Search to the tree location appropriate for the given leaf_node's key:
134
* - If location is unused (NULL), store the tweaked pointer directly there
135
* - If location holds a note entry that matches the note-to-be-inserted, then
178
- * concatenate the two notes.
136
+ * combine the two notes (by calling the given combine_notes function).
137
* - If location holds a note entry that matches the subtree-to-be-inserted,
138
* then unpack the subtree-to-be-inserted into the location.
139
* - If location holds a matching subtree entry, unpack the subtree at that
142
* node-to-be-inserted, and store the new int_node into the location.
143
*/
144
static void note_tree_insert(struct int_node *tree, unsigned char n,
187
- struct leaf_node *entry, unsigned char type)
145
+ struct leaf_node *entry, unsigned char type,
146
+ combine_notes_fn combine_notes)
147
{
148
struct int_node *new_node;
149
struct leaf_node *l;
164
if (!hashcmp(l->val_sha1, entry->val_sha1))
165
return;
166
208
- if (concatenate_notes(l->val_sha1,
209
- entry->val_sha1))
210
- die("failed to concatenate note %s "
211
- "into note %s for object %s",
212
- sha1_to_hex(entry->val_sha1),
167
+ if (combine_notes(l->val_sha1, entry->val_sha1))
168
+ die("failed to combine notes %s and %s"
169
+ " for object %s",
170
sha1_to_hex(l->val_sha1),
171
+ sha1_to_hex(entry->val_sha1),
172
sha1_to_hex(l->key_sha1));
173
free(entry);
174
return;
191
*p = NULL;
192
load_subtree(l, tree, n);
193
free(l);
236
- note_tree_insert(tree, n, entry, type);
194
+ note_tree_insert(tree, n, entry, type, combine_notes);
195
return;
196
}
197
break;
201
assert(GET_PTR_TYPE(*p) == PTR_TYPE_NOTE ||
202
GET_PTR_TYPE(*p) == PTR_TYPE_SUBTREE);
203
new_node = (struct int_node *) xcalloc(sizeof(struct int_node), 1);
246
- note_tree_insert(new_node, n + 1, l, GET_PTR_TYPE(*p));
204
+ note_tree_insert(new_node, n + 1, l, GET_PTR_TYPE(*p), combine_notes);
205
*p = SET_PTR_TYPE(new_node, PTR_TYPE_INTERNAL);
248
- note_tree_insert(new_node, n + 1, entry, type);
206
+ note_tree_insert(new_node, n + 1, entry, type, combine_notes);
207
}
208
209
/*
364
l->key_sha1[19] = (unsigned char) len;
365
type = PTR_TYPE_SUBTREE;
366
}
409
- note_tree_insert(node, n, l, type);
367
+ note_tree_insert(node, n, l, type,
368
+ combine_notes_concatenate);
369
}
370
}
371
free(buf);
618
return write_each_note_helper(d->root, note_path, mode, note_sha1);
619
}
620
662
-void init_notes(struct notes_tree *t, const char *notes_ref, int flags)
621
+int combine_notes_concatenate(unsigned char *cur_sha1,
622
+ const unsigned char *new_sha1)
623
+{
624
+ char *cur_msg = NULL, *new_msg = NULL, *buf;
625
+ unsigned long cur_len, new_len, buf_len;
626
+ enum object_type cur_type, new_type;
627
+ int ret;
628
+
629
+ /* read in both note blob objects */
630
+ if (!is_null_sha1(new_sha1))
631
+ new_msg = read_sha1_file(new_sha1, &new_type, &new_len);
632
+ if (!new_msg || !new_len || new_type != OBJ_BLOB) {
633
+ free(new_msg);
634
+ return 0;
635
+ }
636
+ if (!is_null_sha1(cur_sha1))
637
+ cur_msg = read_sha1_file(cur_sha1, &cur_type, &cur_len);
638
+ if (!cur_msg || !cur_len || cur_type != OBJ_BLOB) {
639
+ free(cur_msg);
640
+ free(new_msg);
641
+ hashcpy(cur_sha1, new_sha1);
642
+ return 0;
643
+ }
644
+
645
+ /* we will separate the notes by a newline anyway */
646
+ if (cur_msg[cur_len - 1] == '\n')
647
+ cur_len--;
648
+
649
+ /* concatenate cur_msg and new_msg into buf */
650
+ buf_len = cur_len + 1 + new_len;
651
+ buf = (char *) xmalloc(buf_len);
652
+ memcpy(buf, cur_msg, cur_len);
653
+ buf[cur_len] = '\n';
654
+ memcpy(buf + cur_len + 1, new_msg, new_len);
655
+ free(cur_msg);
656
+ free(new_msg);
657
+
658
+ /* create a new blob object from buf */
659
+ ret = write_sha1_file(buf, buf_len, blob_type, cur_sha1);
660
+ free(buf);
661
+ return ret;
662
+}
663
+
664
+int combine_notes_overwrite(unsigned char *cur_sha1,
665
+ const unsigned char *new_sha1)
666
+{
667
+ hashcpy(cur_sha1, new_sha1);
668
+ return 0;
669
+}
670
+
671
+int combine_notes_ignore(unsigned char *cur_sha1,
672
+ const unsigned char *new_sha1)
673
+{
674
+ return 0;
675
+}
676
+
677
+void init_notes(struct notes_tree *t, const char *notes_ref,
678
+ combine_notes_fn combine_notes, int flags)
679
{
680
unsigned char sha1[20], object_sha1[20];
681
unsigned mode;
692
if (!notes_ref)
693
notes_ref = GIT_NOTES_DEFAULT_REF;
694
695
+ if (!combine_notes)
696
+ combine_notes = combine_notes_concatenate;
697
+
698
t->root = (struct int_node *) xcalloc(sizeof(struct int_node), 1);
699
t->ref = notes_ref ? xstrdup(notes_ref) : NULL;
700
+ t->combine_notes = combine_notes;
701
t->initialized = 1;
702
703
if (flags & NOTES_INIT_EMPTY || !notes_ref ||
713
}
714
715
void add_note(struct notes_tree *t, const unsigned char *object_sha1,
696
- const unsigned char *note_sha1)
716
+ const unsigned char *note_sha1, combine_notes_fn combine_notes)
717
{
718
struct leaf_node *l;
719
720
if (!t)
721
t = &default_notes_tree;
722
assert(t->initialized);
723
+ if (!combine_notes)
724
+ combine_notes = t->combine_notes;
725
l = (struct leaf_node *) xmalloc(sizeof(struct leaf_node));
726
hashcpy(l->key_sha1, object_sha1);
727
hashcpy(l->val_sha1, note_sha1);
706
- note_tree_insert(t->root, 0, l, PTR_TYPE_NOTE);
728
+ note_tree_insert(t->root, 0, l, PTR_TYPE_NOTE, combine_notes);
729
}
730
731
void remove_note(struct notes_tree *t, const unsigned char *object_sha1)
810
if (!t)
811
t = &default_notes_tree;
812
if (!t->initialized)
791
- init_notes(t, NULL, 0);
813
+ init_notes(t, NULL, NULL, 0);
814
815
sha1 = get_note(t, object_sha1);
816
if (!sha1)