Raw
1 #include "git-compat-util.h"
2 #include "abspath.h"
3 #include "blob.h"
4 #include "chdir-notify.h"
5 #include "config.h"
6 #include "gettext.h"
7 #include "lockfile.h"
8 #include "object-file.h"
9 #include "odb.h"
10 #include "odb/source.h"
11 #include "odb/source-files.h"
12 #include "odb/source-loose.h"
13 #include "pack-objects.h"
14 #include "packfile.h"
15 #include "path.h"
16 #include "promisor-remote.h"
17 #include "repack.h"
18 #include "run-command.h"
19 #include "strbuf.h"
20 #include "string-list.h"
21 #include "strvec.h"
22 #include "tree.h"
23 #include "write-or-die.h"
24
25 static void odb_source_files_reparent(const char *name UNUSED,
26 const char *old_cwd,
27 const char *new_cwd,
28 void *cb_data)
29 {
30 struct odb_source_files *files = cb_data;
31 char *path = reparent_relative_path(old_cwd, new_cwd,
32 files->base.path);
33 free(files->base.path);
34 files->base.path = path;
35 }
36
37 static void odb_source_files_free(struct odb_source *source)
38 {
39 struct odb_source_files *files = odb_source_files_downcast(source);
40 chdir_notify_unregister(NULL, odb_source_files_reparent, files);
41 odb_source_free(&files->loose->base);
42 odb_source_free(&files->packed->base);
43 odb_source_release(&files->base);
44 free(files);
45 }
46
47 static void odb_source_files_close(struct odb_source *source)
48 {
49 struct odb_source_files *files = odb_source_files_downcast(source);
50 odb_source_close(&files->loose->base);
51 odb_source_close(&files->packed->base);
52 }
53
54 static void odb_source_files_prepare(struct odb_source *source,
55 enum odb_prepare_flags flags)
56 {
57 struct odb_source_files *files = odb_source_files_downcast(source);
58 odb_source_prepare(&files->loose->base, flags);
59 odb_source_prepare(&files->packed->base, flags);
60 }
61
62 static int odb_source_files_read_object_info(struct odb_source *source,
63 const struct object_id *oid,
64 struct object_info *oi,
65 enum object_info_flags flags)
66 {
67 struct odb_source_files *files = odb_source_files_downcast(source);
68
69 if (!odb_source_read_object_info(&files->packed->base, oid, oi, flags) ||
70 !odb_source_read_object_info(&files->loose->base, oid, oi, flags))
71 return 0;
72
73 return -1;
74 }
75
76 static int odb_source_files_read_object_stream(struct odb_read_stream **out,
77 struct odb_source *source,
78 const struct object_id *oid)
79 {
80 struct odb_source_files *files = odb_source_files_downcast(source);
81 if (!odb_source_read_object_stream(out, &files->packed->base, oid) ||
82 !odb_source_read_object_stream(out, &files->loose->base, oid))
83 return 0;
84 return -1;
85 }
86
87 static int odb_source_files_for_each_object(struct odb_source *source,
88 const struct object_info *request,
89 odb_for_each_object_cb cb,
90 void *cb_data,
91 const struct odb_for_each_object_options *opts)
92 {
93 struct odb_source_files *files = odb_source_files_downcast(source);
94 int ret;
95
96 if (!(opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY)) {
97 ret = odb_source_for_each_object(&files->loose->base, request, cb, cb_data, opts);
98 if (ret)
99 return ret;
100 }
101
102 ret = odb_source_for_each_object(&files->packed->base, request, cb, cb_data, opts);
103 if (ret)
104 return ret;
105
106 return 0;
107 }
108
109 static int odb_source_files_count_objects(struct odb_source *source,
110 enum odb_count_objects_flags flags,
111 unsigned long *out)
112 {
113 struct odb_source_files *files = odb_source_files_downcast(source);
114 unsigned long count;
115 int ret;
116
117 ret = odb_source_count_objects(&files->packed->base, flags, &count);
118 if (ret < 0)
119 goto out;
120
121 if (!(flags & ODB_COUNT_OBJECTS_APPROXIMATE)) {
122 unsigned long loose_count;
123
124 ret = odb_source_count_objects(&files->loose->base, flags, &loose_count);
125 if (ret < 0)
126 goto out;
127
128 count += loose_count;
129 }
130
131 *out = count;
132 ret = 0;
133
134 out:
135 return ret;
136 }
137
138 static int odb_source_files_find_abbrev_len(struct odb_source *source,
139 const struct object_id *oid,
140 unsigned min_len,
141 unsigned *out)
142 {
143 struct odb_source_files *files = odb_source_files_downcast(source);
144 unsigned len = min_len;
145 int ret;
146
147 ret = odb_source_find_abbrev_len(&files->packed->base, oid, len, &len);
148 if (ret < 0)
149 goto out;
150
151 ret = odb_source_find_abbrev_len(&files->loose->base, oid, len, &len);
152 if (ret < 0)
153 goto out;
154
155 *out = len;
156 ret = 0;
157
158 out:
159 return ret;
160 }
161
162 static int odb_source_files_freshen_object(struct odb_source *source,
163 const struct object_id *oid,
164 const time_t *mtime)
165 {
166 struct odb_source_files *files = odb_source_files_downcast(source);
167 if (odb_source_freshen_object(&files->packed->base, oid, mtime) ||
168 odb_source_freshen_object(&files->loose->base, oid, mtime))
169 return 1;
170 return 0;
171 }
172
173 static int odb_source_files_write_object(struct odb_source *source,
174 const void *buf, size_t len,
175 enum object_type type,
176 const struct object_id *oid,
177 const struct object_id *compat_oid,
178 const time_t *mtime,
179 enum odb_write_object_flags flags)
180 {
181 struct odb_source_files *files = odb_source_files_downcast(source);
182 return odb_source_write_object(&files->loose->base, buf, len, type,
183 oid, compat_oid, mtime, flags);
184 }
185
186 static int odb_source_files_write_object_stream(struct odb_source *source,
187 struct odb_write_stream *stream,
188 size_t len,
189 struct object_id *oid)
190 {
191 struct odb_source_files *files = odb_source_files_downcast(source);
192 return odb_source_write_object_stream(&files->loose->base, stream, len, oid);
193 }
194
195 static int odb_source_files_begin_transaction(struct odb_source *source,
196 struct odb_transaction **out,
197 enum odb_transaction_flags flags)
198 {
199 return odb_transaction_files_begin(source, out, flags);
200 }
201
202 static int odb_source_files_read_alternates(struct odb_source *source,
203 struct strvec *out)
204 {
205 struct strbuf buf = STRBUF_INIT;
206 char *path;
207
208 path = xstrfmt("%s/info/alternates", source->path);
209 if (strbuf_read_file(&buf, path, 1024) < 0) {
210 warn_on_fopen_errors(path);
211 free(path);
212 return 0;
213 }
214 parse_alternates(buf.buf, '\n', source->path, out);
215
216 strbuf_release(&buf);
217 free(path);
218 return 0;
219 }
220
221 static int odb_source_files_write_alternate(struct odb_source *source,
222 const char *alternate)
223 {
224 struct lock_file lock = LOCK_INIT;
225 char *path = xstrfmt("%s/%s", source->path, "info/alternates");
226 FILE *in, *out;
227 int found = 0;
228 int ret;
229
230 repo_hold_lock_file_for_update(source->odb->repo, &lock, path,
231 LOCK_DIE_ON_ERROR);
232 out = fdopen_lock_file(&lock, "w");
233 if (!out) {
234 ret = error_errno(_("unable to fdopen alternates lockfile"));
235 goto out;
236 }
237
238 in = fopen(path, "r");
239 if (in) {
240 struct strbuf line = STRBUF_INIT;
241
242 while (strbuf_getline(&line, in) != EOF) {
243 if (!strcmp(alternate, line.buf)) {
244 found = 1;
245 break;
246 }
247 fprintf_or_die(out, "%s\n", line.buf);
248 }
249
250 strbuf_release(&line);
251 fclose(in);
252 } else if (errno != ENOENT) {
253 ret = error_errno(_("unable to read alternates file"));
254 goto out;
255 }
256
257 if (found) {
258 rollback_lock_file(&lock);
259 } else {
260 fprintf_or_die(out, "%s\n", alternate);
261 if (commit_lock_file(&lock)) {
262 ret = error_errno(_("unable to move new alternates file into place"));
263 goto out;
264 }
265 }
266
267 ret = 0;
268
269 out:
270 free(path);
271 return ret;
272 }
273
274 static int too_many_loose_objects(struct odb_source_files *files, int limit)
275 {
276 unsigned long loose_count;
277
278 if (limit <= 0)
279 return 0;
280
281 if (odb_source_count_objects(&files->loose->base, ODB_COUNT_OBJECTS_APPROXIMATE,
282 &loose_count) < 0)
283 return 0;
284
285 /*
286 * This is weird, but stems from legacy behaviour: the GC auto
287 * threshold was always essentially interpreted as if it was rounded up
288 * to the next multiple 256 of, so we retain this behaviour for now.
289 */
290 return loose_count > (DIV_ROUND_UP(((unsigned long) limit), 256) * 256);
291 }
292
293 static struct packed_git *find_base_packs(struct odb_source_files *files,
294 struct string_list *packs,
295 unsigned long limit)
296 {
297 struct packfile_list_entry *e;
298 struct packed_git *base = NULL;
299
300 for (e = packfile_store_get_packs(files->packed); e; e = e->next) {
301 if (e->pack->is_cruft)
302 continue;
303 if (limit) {
304 if ((uintmax_t) e->pack->pack_size >= limit)
305 string_list_append(packs, e->pack->pack_name);
306 } else if (!base || base->pack_size < e->pack->pack_size) {
307 base = e->pack;
308 }
309 }
310
311 if (base)
312 string_list_append(packs, base->pack_name);
313
314 return base;
315 }
316
317 static int too_many_packs(struct odb_source_files *files, int gc_auto_pack_limit)
318 {
319 struct packfile_list_entry *e;
320 int cnt = 0;
321
322 if (gc_auto_pack_limit <= 0)
323 return 0;
324
325 for (e = packfile_store_get_packs(files->packed); e; e = e->next) {
326 if (e->pack->pack_keep)
327 continue;
328 /*
329 * Perhaps check the size of the pack and count only
330 * very small ones here?
331 */
332 cnt++;
333 }
334 return gc_auto_pack_limit < cnt;
335 }
336
337 static uint64_t total_ram(void)
338 {
339 #if defined(HAVE_SYSINFO)
340 struct sysinfo si;
341
342 if (!sysinfo(&si)) {
343 uint64_t total = si.totalram;
344
345 if (si.mem_unit > 1)
346 total *= (uint64_t)si.mem_unit;
347 return total;
348 }
349 #elif defined(HAVE_BSD_SYSCTL) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM) || defined(HW_PHYSMEM64))
350 uint64_t physical_memory;
351 int mib[2];
352 size_t length;
353
354 mib[0] = CTL_HW;
355 # if defined(HW_MEMSIZE)
356 mib[1] = HW_MEMSIZE;
357 # elif defined(HW_PHYSMEM64)
358 mib[1] = HW_PHYSMEM64;
359 # else
360 mib[1] = HW_PHYSMEM;
361 # endif
362 length = sizeof(physical_memory);
363 if (!sysctl(mib, 2, &physical_memory, &length, NULL, 0)) {
364 if (length == 4) {
365 uint32_t mem;
366
367 if (!sysctl(mib, 2, &mem, &length, NULL, 0))
368 physical_memory = mem;
369 }
370 return physical_memory;
371 }
372 #elif defined(GIT_WINDOWS_NATIVE)
373 MEMORYSTATUSEX memInfo;
374
375 memInfo.dwLength = sizeof(MEMORYSTATUSEX);
376 if (GlobalMemoryStatusEx(&memInfo))
377 return memInfo.ullTotalPhys;
378 #endif
379 return 0;
380 }
381
382 static uint64_t estimate_repack_memory(struct odb_source_files *files,
383 struct packed_git *pack)
384 {
385 unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
386 unsigned long delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT;
387 unsigned long nr_objects;
388 size_t os_cache, heap;
389
390 if (odb_source_count_objects(&files->base, ODB_COUNT_OBJECTS_APPROXIMATE,
391 &nr_objects) < 0)
392 return 0;
393
394 if (!pack || !nr_objects)
395 return 0;
396
397 repo_config_get_ulong(files->base.odb->repo, "pack.deltacachesize",
398 &max_delta_cache_size);
399 repo_config_get_ulong(files->base.odb->repo, "core.deltabasecachelimit",
400 &delta_base_cache_limit);
401
402 /*
403 * First we have to scan through at least one pack.
404 * Assume enough room in OS file cache to keep the entire pack
405 * or we may accidentally evict data of other processes from
406 * the cache.
407 */
408 os_cache = pack->pack_size + pack->index_size;
409 /* then pack-objects needs lots more for book keeping */
410 heap = sizeof(struct object_entry) * nr_objects;
411 /*
412 * internal rev-list --all --objects takes up some memory too,
413 * let's say half of it is for blobs
414 */
415 heap += sizeof(struct blob) * nr_objects / 2;
416 /*
417 * and the other half is for trees (commits and tags are
418 * usually insignificant)
419 */
420 heap += sizeof(struct tree) * nr_objects / 2;
421 /* and then obj_hash[], underestimated in fact */
422 heap += sizeof(struct object *) * nr_objects;
423 /* revindex is used also */
424 heap += (sizeof(off_t) + sizeof(uint32_t)) * nr_objects;
425 /*
426 * read_sha1_file() (either at delta calculation phase, or
427 * writing phase) also fills up the delta base cache
428 */
429 heap += delta_base_cache_limit;
430 /* and of course pack-objects has its own delta cache */
431 heap += max_delta_cache_size;
432
433 return os_cache + heap;
434 }
435
436 static int keep_one_pack(struct string_list_item *item, void *data)
437 {
438 struct strvec *args = data;
439 strvec_pushf(args, "--keep-pack=%s", basename(item->string));
440 return 0;
441 }
442
443 static void add_repack_all_option(struct repository *repo,
444 const struct odb_optimize_options *opts,
445 struct string_list *keep_pack,
446 struct strvec *args)
447 {
448 char *repack_filter = NULL;
449 char *repack_filter_to = NULL;
450
451 repo_config_get_string(repo, "gc.repackfilter", &repack_filter);
452 repo_config_get_string(repo, "gc.repackfilterto", &repack_filter_to);
453
454 if (opts->prune_expire && !strcmp(opts->prune_expire, "now") &&
455 !(opts->cruft_packs && opts->expire_to))
456 strvec_push(args, "-a");
457 else if (opts->cruft_packs) {
458 strvec_push(args, "--cruft");
459 if (opts->prune_expire)
460 strvec_pushf(args, "--cruft-expiration=%s", opts->prune_expire);
461 if (opts->max_cruft_size)
462 strvec_pushf(args, "--max-cruft-size=%lu",
463 opts->max_cruft_size);
464 if (opts->expire_to)
465 strvec_pushf(args, "--expire-to=%s", opts->expire_to);
466 } else {
467 strvec_push(args, "-A");
468 if (opts->prune_expire)
469 strvec_pushf(args, "--unpack-unreachable=%s", opts->prune_expire);
470 }
471
472 if (keep_pack)
473 for_each_string_list(keep_pack, keep_one_pack, args);
474
475 if (repack_filter && *repack_filter)
476 strvec_pushf(args, "--filter=%s", repack_filter);
477 if (repack_filter_to && *repack_filter_to)
478 strvec_pushf(args, "--filter-to=%s", repack_filter_to);
479
480 free(repack_filter);
481 free(repack_filter_to);
482 }
483
484 static void add_repack_incremental_option(struct strvec *args)
485 {
486 strvec_push(args, "--no-write-bitmap-index");
487 }
488
489 bool odb_source_files_optimize_required(struct odb_source *source,
490 const struct odb_optimize_options *opts)
491 {
492 struct odb_source_files *files = odb_source_files_downcast(source);
493 struct repository *repo = source->odb->repo;
494
495 switch (opts->strategy) {
496 case ODB_OPTIMIZE_INCREMENTAL: {
497 int gc_auto_threshold = 6700;
498 int gc_auto_pack_limit = 50;
499
500 repo_config_get_int(repo, "gc.auto", &gc_auto_threshold);
501 repo_config_get_int(repo, "gc.autopacklimit", &gc_auto_pack_limit);
502
503 /*
504 * Setting gc.auto to 0 or negative can disable the
505 * automatic gc.
506 */
507 if (gc_auto_threshold <= 0)
508 return false;
509 if (!too_many_packs(files, gc_auto_pack_limit) &&
510 !too_many_loose_objects(files, gc_auto_threshold))
511 return false;
512
513 return true;
514 }
515 case ODB_OPTIMIZE_GEOMETRIC: {
516 struct pack_geometry geometry = {
517 .split_factor = 2,
518 };
519 struct pack_objects_args po_args = {
520 .local = 1,
521 };
522 struct existing_packs existing_packs = EXISTING_PACKS_INIT;
523 struct string_list kept_packs = STRING_LIST_INIT_DUP;
524 int auto_value = 100;
525 bool ret;
526
527 repo_config_get_int(repo, "maintenance.geometric-repack.auto",
528 &auto_value);
529 if (!auto_value)
530 return false;
531 if (auto_value < 0)
532 return true;
533
534 repo_config_get_int(repo, "maintenance.geometric-repack.splitFactor",
535 &geometry.split_factor);
536
537 existing_packs.repo = repo;
538 existing_packs_collect(&existing_packs, &kept_packs);
539 pack_geometry_init(&geometry, &existing_packs, &po_args);
540 pack_geometry_split(&geometry);
541
542 /*
543 * When we'd merge at least two packs with one another we always
544 * perform the repack.
545 */
546 if (geometry.split) {
547 ret = true;
548 goto out;
549 }
550
551 /*
552 * Otherwise, we estimate the number of loose objects to determine
553 * whether we want to create a new packfile or not.
554 */
555 if (too_many_loose_objects(files, auto_value)) {
556 ret = true;
557 goto out;
558 }
559
560 ret = false;
561
562 out:
563 existing_packs_release(&existing_packs);
564 pack_geometry_release(&geometry);
565 return ret;
566 }
567 default:
568 BUG("unknown maintenance strategy '%d'", opts->strategy);
569 }
570 }
571
572 int odb_source_files_optimize(struct odb_source *source,
573 const struct odb_optimize_options *opts)
574 {
575 struct odb_source_files *files = odb_source_files_downcast(source);
576 struct repository *repo = source->odb->repo;
577 struct child_process repack_cmd = CHILD_PROCESS_INIT;
578 unsigned long big_pack_threshold = 0;
579 int gc_auto_threshold = 6700;
580 int gc_auto_pack_limit = 50;
581 int ret;
582
583 repo_config_get_int(repo, "gc.auto", &gc_auto_threshold);
584 repo_config_get_int(repo, "gc.autopacklimit", &gc_auto_pack_limit);
585 repo_config_get_ulong(repo, "gc.bigpackthreshold", &big_pack_threshold);
586
587 if (repo->repository_format_precious_objects)
588 return 0;
589
590 repack_cmd.git_cmd = 1;
591 repack_cmd.odb_to_close = repo->objects;
592
593 strvec_pushl(&repack_cmd.args, "repack", "-d", "-l", NULL);
594 if (opts->flags & ODB_OPTIMIZE_NO_REUSE_DELTAS)
595 strvec_push(&repack_cmd.args, "-f");
596 if (opts->depth > 0)
597 strvec_pushf(&repack_cmd.args, "--depth=%d", opts->depth);
598 if (opts->window > 0)
599 strvec_pushf(&repack_cmd.args, "--window=%d", opts->window);
600 if (!(opts->flags & ODB_OPTIMIZE_VERBOSE))
601 strvec_push(&repack_cmd.args, "-q");
602
603 /*
604 * There's three cases we need to consider:
605 *
606 * - If we're invoked without `--auto` we'll need to perform a full
607 * repack.
608 *
609 * - If we're invoked with `--auto` and there's too many packs, then
610 * we perform a full repack, as well.
611 *
612 * - Otherwise we perform an incremental repack.
613 */
614 switch (opts->strategy) {
615 case ODB_OPTIMIZE_INCREMENTAL:
616 if (!(opts->flags & ODB_OPTIMIZE_AUTO)) {
617 struct string_list keep_pack = STRING_LIST_INIT_NODUP;
618
619 if (opts->keep_largest_pack != -1) {
620 if (opts->keep_largest_pack)
621 find_base_packs(files, &keep_pack, 0);
622 } else if (big_pack_threshold) {
623 find_base_packs(files, &keep_pack, big_pack_threshold);
624 }
625
626 add_repack_all_option(repo, opts, &keep_pack, &repack_cmd.args);
627 string_list_clear(&keep_pack, 0);
628 } else {
629 if (too_many_packs(files, gc_auto_pack_limit)) {
630 struct string_list keep_pack = STRING_LIST_INIT_NODUP;
631
632 if (big_pack_threshold) {
633 find_base_packs(files, &keep_pack, big_pack_threshold);
634 if (keep_pack.nr >= (unsigned long) gc_auto_pack_limit) {
635 string_list_clear(&keep_pack, 0);
636 find_base_packs(files, &keep_pack, 0);
637 }
638 } else {
639 struct packed_git *p = find_base_packs(files, &keep_pack, 0);
640 uint64_t mem_have, mem_want;
641
642 mem_have = total_ram();
643 mem_want = estimate_repack_memory(files, p);
644
645 /*
646 * Only allow 1/2 of memory for pack-objects, leave
647 * the rest for the OS and other processes in the
648 * system.
649 */
650 if (!mem_have || mem_want < mem_have / 2)
651 string_list_clear(&keep_pack, 0);
652 }
653
654 add_repack_all_option(repo, opts, &keep_pack, &repack_cmd.args);
655 string_list_clear(&keep_pack, 0);
656 } else {
657 add_repack_incremental_option(&repack_cmd.args);
658 }
659 }
660
661 break;
662 case ODB_OPTIMIZE_GEOMETRIC: {
663 struct pack_geometry geometry = {
664 .split_factor = 2,
665 };
666 struct pack_objects_args po_args = {
667 .local = 1,
668 };
669 struct existing_packs existing_packs = EXISTING_PACKS_INIT;
670 struct string_list kept_packs = STRING_LIST_INIT_DUP;
671
672 repo_config_get_int(repo, "maintenance.geometric-repack.splitFactor",
673 &geometry.split_factor);
674
675 existing_packs.repo = repo;
676 existing_packs_collect(&existing_packs, &kept_packs);
677 pack_geometry_init(&geometry, &existing_packs, &po_args);
678 pack_geometry_split(&geometry);
679
680 if (geometry.split < geometry.pack_nr) {
681 strvec_pushf(&repack_cmd.args, "--geometric=%d",
682 geometry.split_factor);
683 } else {
684 add_repack_all_option(repo, opts, NULL, &repack_cmd.args);
685 }
686 if (repo->settings.core_multi_pack_index)
687 strvec_push(&repack_cmd.args, "--write-midx");
688
689 existing_packs_release(&existing_packs);
690 pack_geometry_release(&geometry);
691 break;
692 }
693 default:
694 die("unknown maintenance strategy '%d'", opts->strategy);
695 }
696
697 if (run_command(&repack_cmd)) {
698 ret = error("failed to run %s", repack_cmd.args.v[0]);
699 goto out;
700 }
701
702 /* Geometric repacking uses cruft packs, so we don't have to prune separately. */
703 if (opts->strategy != ODB_OPTIMIZE_GEOMETRIC && opts->prune_expire) {
704 struct child_process prune_cmd = CHILD_PROCESS_INIT;
705
706 strvec_pushl(&prune_cmd.args, "prune", "--expire", NULL);
707 /* run `git prune` even if using cruft packs */
708 strvec_push(&prune_cmd.args, opts->prune_expire);
709 if (!(opts->flags & ODB_OPTIMIZE_VERBOSE))
710 strvec_push(&prune_cmd.args, "--no-progress");
711 if (repo_has_promisor_remote(repo))
712 strvec_push(&prune_cmd.args,
713 "--exclude-promisor-objects");
714 prune_cmd.git_cmd = 1;
715
716 if (run_command(&prune_cmd)) {
717 ret = error("failed to run %s", prune_cmd.args.v[0]);
718 goto out;
719 }
720 }
721
722 if (opts->flags & ODB_OPTIMIZE_AUTO && too_many_loose_objects(files, gc_auto_threshold))
723 warning(_("There are too many unreachable loose objects; "
724 "run 'git prune' to remove them."));
725
726 ret = 0;
727
728 out:
729 return ret;
730 }
731
732 struct odb_source_files *odb_source_files_new(struct object_database *odb,
733 const char *path,
734 bool local)
735 {
736 struct odb_source_files *files;
737
738 CALLOC_ARRAY(files, 1);
739 odb_source_init(&files->base, odb, ODB_SOURCE_FILES, path, local);
740 files->loose = odb_source_loose_new(odb, path, local);
741 files->packed = odb_source_packed_new(odb, path, local);
742
743 files->base.free = odb_source_files_free;
744 files->base.close = odb_source_files_close;
745 files->base.prepare = odb_source_files_prepare;
746 files->base.read_object_info = odb_source_files_read_object_info;
747 files->base.read_object_stream = odb_source_files_read_object_stream;
748 files->base.for_each_object = odb_source_files_for_each_object;
749 files->base.count_objects = odb_source_files_count_objects;
750 files->base.find_abbrev_len = odb_source_files_find_abbrev_len;
751 files->base.freshen_object = odb_source_files_freshen_object;
752 files->base.write_object = odb_source_files_write_object;
753 files->base.write_object_stream = odb_source_files_write_object_stream;
754 files->base.begin_transaction = odb_source_files_begin_transaction;
755 files->base.read_alternates = odb_source_files_read_alternates;
756 files->base.write_alternate = odb_source_files_write_alternate;
757 files->base.optimize = odb_source_files_optimize;
758 files->base.optimize_required = odb_source_files_optimize_required;
759
760 /*
761 * Ideally, we would only ever store absolute paths in the source. This
762 * is not (yet) possible though because we access and assume relative
763 * paths in the primary ODB source in some user-facing functionality.
764 */
765 if (!is_absolute_path(path))
766 chdir_notify_register(NULL, odb_source_files_reparent, files);
767
768 return files;
769 }