1 #define USE_THE_REPOSITORY_VARIABLE
3 #include "git-compat-util.h"
6 #include "object-store.h"
14 static const char *loose_object_header
= "# loose-object-idx\n";
16 static inline int should_use_loose_object_map(struct repository
*repo
)
18 return repo
->compat_hash_algo
&& repo
->gitdir
;
21 void loose_object_map_init(struct loose_object_map
**map
)
23 struct loose_object_map
*m
;
24 m
= xmalloc(sizeof(**map
));
25 m
->to_compat
= kh_init_oid_map();
26 m
->to_storage
= kh_init_oid_map();
30 static int insert_oid_pair(kh_oid_map_t
*map
, const struct object_id
*key
, const struct object_id
*value
)
34 struct object_id
*stored
;
36 pos
= kh_put_oid_map(map
, *key
, &ret
);
38 /* This item already exists in the map. */
42 stored
= xmalloc(sizeof(*stored
));
43 oidcpy(stored
, value
);
44 kh_value(map
, pos
) = stored
;
48 static int insert_loose_map(struct object_directory
*odb
,
49 const struct object_id
*oid
,
50 const struct object_id
*compat_oid
)
52 struct loose_object_map
*map
= odb
->loose_map
;
55 inserted
|= insert_oid_pair(map
->to_compat
, oid
, compat_oid
);
56 inserted
|= insert_oid_pair(map
->to_storage
, compat_oid
, oid
);
58 oidtree_insert(odb
->loose_objects_cache
, compat_oid
);
63 static int load_one_loose_object_map(struct repository
*repo
, struct object_directory
*dir
)
65 struct strbuf buf
= STRBUF_INIT
, path
= STRBUF_INIT
;
69 loose_object_map_init(&dir
->loose_map
);
70 if (!dir
->loose_objects_cache
) {
71 ALLOC_ARRAY(dir
->loose_objects_cache
, 1);
72 oidtree_init(dir
->loose_objects_cache
);
75 insert_loose_map(dir
, repo
->hash_algo
->empty_tree
, repo
->compat_hash_algo
->empty_tree
);
76 insert_loose_map(dir
, repo
->hash_algo
->empty_blob
, repo
->compat_hash_algo
->empty_blob
);
77 insert_loose_map(dir
, repo
->hash_algo
->null_oid
, repo
->compat_hash_algo
->null_oid
);
79 strbuf_git_common_path(&path
, repo
, "objects/loose-object-idx");
80 fp
= fopen(path
.buf
, "rb");
82 strbuf_release(&path
);
87 if (strbuf_getwholeline(&buf
, fp
, '\n') || strcmp(buf
.buf
, loose_object_header
))
89 while (!strbuf_getline_lf(&buf
, fp
)) {
91 struct object_id oid
, compat_oid
;
92 if (parse_oid_hex_algop(buf
.buf
, &oid
, &p
, repo
->hash_algo
) ||
94 parse_oid_hex_algop(p
, &compat_oid
, &p
, repo
->compat_hash_algo
) ||
95 p
!= buf
.buf
+ buf
.len
)
97 insert_loose_map(dir
, &oid
, &compat_oid
);
100 strbuf_release(&buf
);
101 strbuf_release(&path
);
102 return errno
? -1 : 0;
104 strbuf_release(&buf
);
105 strbuf_release(&path
);
109 int repo_read_loose_object_map(struct repository
*repo
)
111 struct object_directory
*dir
;
113 if (!should_use_loose_object_map(repo
))
116 prepare_alt_odb(repo
);
118 for (dir
= repo
->objects
->odb
; dir
; dir
= dir
->next
) {
119 if (load_one_loose_object_map(repo
, dir
) < 0) {
126 int repo_write_loose_object_map(struct repository
*repo
)
128 kh_oid_map_t
*map
= repo
->objects
->odb
->loose_map
->to_compat
;
129 struct lock_file lock
;
132 struct strbuf buf
= STRBUF_INIT
, path
= STRBUF_INIT
;
134 if (!should_use_loose_object_map(repo
))
137 strbuf_git_common_path(&path
, repo
, "objects/loose-object-idx");
138 fd
= hold_lock_file_for_update_timeout(&lock
, path
.buf
, LOCK_DIE_ON_ERROR
, -1);
139 iter
= kh_begin(map
);
140 if (write_in_full(fd
, loose_object_header
, strlen(loose_object_header
)) < 0)
143 for (; iter
!= kh_end(map
); iter
++) {
144 if (kh_exist(map
, iter
)) {
145 if (oideq(&kh_key(map
, iter
), the_hash_algo
->empty_tree
) ||
146 oideq(&kh_key(map
, iter
), the_hash_algo
->empty_blob
))
148 strbuf_addf(&buf
, "%s %s\n", oid_to_hex(&kh_key(map
, iter
)), oid_to_hex(kh_value(map
, iter
)));
149 if (write_in_full(fd
, buf
.buf
, buf
.len
) < 0)
154 strbuf_release(&buf
);
155 if (commit_lock_file(&lock
) < 0) {
156 error_errno(_("could not write loose object index %s"), path
.buf
);
157 strbuf_release(&path
);
160 strbuf_release(&path
);
163 rollback_lock_file(&lock
);
164 strbuf_release(&buf
);
165 error_errno(_("failed to write loose object index %s\n"), path
.buf
);
166 strbuf_release(&path
);
170 static int write_one_object(struct repository
*repo
, const struct object_id
*oid
,
171 const struct object_id
*compat_oid
)
173 struct lock_file lock
;
176 struct strbuf buf
= STRBUF_INIT
, path
= STRBUF_INIT
;
178 strbuf_git_common_path(&path
, repo
, "objects/loose-object-idx");
179 hold_lock_file_for_update_timeout(&lock
, path
.buf
, LOCK_DIE_ON_ERROR
, -1);
181 fd
= open(path
.buf
, O_WRONLY
| O_CREAT
| O_APPEND
, 0666);
184 if (fstat(fd
, &st
) < 0)
186 if (!st
.st_size
&& write_in_full(fd
, loose_object_header
, strlen(loose_object_header
)) < 0)
189 strbuf_addf(&buf
, "%s %s\n", oid_to_hex(oid
), oid_to_hex(compat_oid
));
190 if (write_in_full(fd
, buf
.buf
, buf
.len
) < 0)
194 adjust_shared_perm(path
.buf
);
195 rollback_lock_file(&lock
);
196 strbuf_release(&buf
);
197 strbuf_release(&path
);
200 error_errno(_("failed to write loose object index %s\n"), path
.buf
);
202 rollback_lock_file(&lock
);
203 strbuf_release(&buf
);
204 strbuf_release(&path
);
208 int repo_add_loose_object_map(struct repository
*repo
, const struct object_id
*oid
,
209 const struct object_id
*compat_oid
)
213 if (!should_use_loose_object_map(repo
))
216 inserted
= insert_loose_map(repo
->objects
->odb
, oid
, compat_oid
);
218 return write_one_object(repo
, oid
, compat_oid
);
222 int repo_loose_object_map_oid(struct repository
*repo
,
223 const struct object_id
*src
,
224 const struct git_hash_algo
*to
,
225 struct object_id
*dest
)
227 struct object_directory
*dir
;
231 for (dir
= repo
->objects
->odb
; dir
; dir
= dir
->next
) {
232 struct loose_object_map
*loose_map
= dir
->loose_map
;
235 map
= (to
== repo
->compat_hash_algo
) ?
236 loose_map
->to_compat
:
237 loose_map
->to_storage
;
238 pos
= kh_get_oid_map(map
, *src
);
239 if (pos
< kh_end(map
)) {
240 oidcpy(dest
, kh_value(map
, pos
));
247 void loose_object_map_clear(struct loose_object_map
**map
)
249 struct loose_object_map
*m
= *map
;
250 struct object_id
*oid
;
255 kh_foreach_value(m
->to_compat
, oid
, free(oid
));
256 kh_foreach_value(m
->to_storage
, oid
, free(oid
));
257 kh_destroy_oid_map(m
->to_compat
);
258 kh_destroy_oid_map(m
->to_storage
);