12 const char *type_names
[] = {
13 "none", "blob", "tree", "commit", "bad"
16 int track_object_refs
= 0;
18 static int hashtable_index(const unsigned char *sha1
)
21 memcpy(&i
, sha1
, sizeof(unsigned int));
22 return (int)(i
% obj_allocs
);
25 static int find_object(const unsigned char *sha1
)
32 i
= hashtable_index(sha1
);
34 if (memcmp(sha1
, objs
[i
]->sha1
, 20) == 0)
43 struct object
*lookup_object(const unsigned char *sha1
)
45 int pos
= find_object(sha1
);
51 void created_object(const unsigned char *sha1
, struct object
*obj
)
56 memcpy(obj
->sha1
, sha1
, 20);
57 obj
->type
= TYPE_NONE
;
61 if (obj_allocs
- 1 <= nr_objs
* 2) {
62 int i
, count
= obj_allocs
;
63 obj_allocs
= (obj_allocs
< 32 ? 32 : 2 * obj_allocs
);
64 objs
= xrealloc(objs
, obj_allocs
* sizeof(struct object
*));
65 memset(objs
+ count
, 0, (obj_allocs
- count
)
66 * sizeof(struct object
*));
67 for (i
= 0; i
< obj_allocs
; i
++)
69 int j
= find_object(objs
[i
]->sha1
);
78 pos
= find_object(sha1
);
80 die("Inserting %s twice\n", sha1_to_hex(sha1
));
87 struct object_refs
*alloc_object_refs(unsigned count
)
89 struct object_refs
*refs
;
90 size_t size
= sizeof(*refs
) + count
*sizeof(struct object
*);
92 refs
= xcalloc(1, size
);
97 static int compare_object_pointers(const void *a
, const void *b
)
99 const struct object
* const *pa
= a
;
100 const struct object
* const *pb
= b
;
109 void set_object_refs(struct object
*obj
, struct object_refs
*refs
)
113 /* Do not install empty list of references */
114 if (refs
->count
< 1) {
119 /* Sort the list and filter out duplicates */
120 qsort(refs
->ref
, refs
->count
, sizeof(refs
->ref
[0]),
121 compare_object_pointers
);
122 for (i
= j
= 1; i
< refs
->count
; i
++) {
123 if (refs
->ref
[i
] != refs
->ref
[i
- 1])
124 refs
->ref
[j
++] = refs
->ref
[i
];
126 if (j
< refs
->count
) {
127 /* Duplicates were found - reallocate list */
128 size_t size
= sizeof(*refs
) + j
*sizeof(struct object
*);
130 refs
= xrealloc(refs
, size
);
133 for (i
= 0; i
< refs
->count
; i
++)
134 refs
->ref
[i
]->used
= 1;
138 void mark_reachable(struct object
*obj
, unsigned int mask
)
140 if (!track_object_refs
)
141 die("cannot do reachability with object refs turned off");
142 /* If we've been here already, don't bother */
143 if (obj
->flags
& mask
)
147 const struct object_refs
*refs
= obj
->refs
;
149 for (i
= 0; i
< refs
->count
; i
++)
150 mark_reachable(refs
->ref
[i
], mask
);
154 struct object
*lookup_object_type(const unsigned char *sha1
, const char *type
)
157 return lookup_unknown_object(sha1
);
158 } else if (!strcmp(type
, blob_type
)) {
159 return &lookup_blob(sha1
)->object
;
160 } else if (!strcmp(type
, tree_type
)) {
161 return &lookup_tree(sha1
)->object
;
162 } else if (!strcmp(type
, commit_type
)) {
163 return &lookup_commit(sha1
)->object
;
164 } else if (!strcmp(type
, tag_type
)) {
165 return &lookup_tag(sha1
)->object
;
167 error("Unknown type %s", type
);
173 struct object object
;
174 struct commit commit
;
180 struct object
*lookup_unknown_object(const unsigned char *sha1
)
182 struct object
*obj
= lookup_object(sha1
);
184 union any_object
*ret
= xcalloc(1, sizeof(*ret
));
185 created_object(sha1
, &ret
->object
);
186 ret
->object
.type
= TYPE_NONE
;
192 struct object
*parse_object(const unsigned char *sha1
)
196 void *buffer
= read_sha1_file(sha1
, type
, &size
);
199 if (check_sha1_signature(sha1
, buffer
, size
, type
) < 0)
200 printf("sha1 mismatch %s\n", sha1_to_hex(sha1
));
201 if (!strcmp(type
, blob_type
)) {
202 struct blob
*blob
= lookup_blob(sha1
);
203 parse_blob_buffer(blob
, buffer
, size
);
205 } else if (!strcmp(type
, tree_type
)) {
206 struct tree
*tree
= lookup_tree(sha1
);
208 if (!tree
->object
.parsed
) {
209 parse_tree_buffer(tree
, buffer
, size
);
212 } else if (!strcmp(type
, commit_type
)) {
213 struct commit
*commit
= lookup_commit(sha1
);
214 parse_commit_buffer(commit
, buffer
, size
);
215 if (!commit
->buffer
) {
216 commit
->buffer
= buffer
;
219 obj
= &commit
->object
;
220 } else if (!strcmp(type
, tag_type
)) {
221 struct tag
*tag
= lookup_tag(sha1
);
222 parse_tag_buffer(tag
, buffer
, size
);
233 struct object_list
*object_list_insert(struct object
*item
,
234 struct object_list
**list_p
)
236 struct object_list
*new_list
= xmalloc(sizeof(struct object_list
));
237 new_list
->item
= item
;
238 new_list
->next
= *list_p
;
243 void object_list_append(struct object
*item
,
244 struct object_list
**list_p
)
247 list_p
= &((*list_p
)->next
);
249 *list_p
= xmalloc(sizeof(struct object_list
));
250 (*list_p
)->next
= NULL
;
251 (*list_p
)->item
= item
;
254 unsigned object_list_length(struct object_list
*list
)
264 int object_list_contains(struct object_list
*list
, struct object
*obj
)
267 if (list
->item
== obj
)