1#include "../cache.h" 2#include "../config.h" 3#include "../refs.h" 4#include "refs-internal.h" 5#include "packed-backend.h" 6#include "../iterator.h" 7#include "../lockfile.h" 8#include "../chdir-notify.h" 9 10enum mmap_strategy { 11 /* 12 * Don't use mmap() at all for reading `packed-refs`. 13 */ 14 MMAP_NONE, 15 16 /* 17 * Can use mmap() for reading `packed-refs`, but the file must 18 * not remain mmapped. This is the usual option on Windows, 19 * where you cannot rename a new version of a file onto a file 20 * that is currently mmapped. 21 */ 22 MMAP_TEMPORARY, 23 24 /* 25 * It is OK to leave the `packed-refs` file mmapped while 26 * arbitrary other code is running. 27 */ 28 MMAP_OK 29}; 30 31#if defined(NO_MMAP) 32static enum mmap_strategy mmap_strategy = MMAP_NONE; 33#elif defined(MMAP_PREVENTS_DELETE) 34static enum mmap_strategy mmap_strategy = MMAP_TEMPORARY; 35#else 36static enum mmap_strategy mmap_strategy = MMAP_OK; 37#endif 38 39struct packed_ref_store; 40 41/* 42 * A `snapshot` represents one snapshot of a `packed-refs` file. 43 * 44 * Normally, this will be a mmapped view of the contents of the 45 * `packed-refs` file at the time the snapshot was created. However, 46 * if the `packed-refs` file was not sorted, this might point at heap 47 * memory holding the contents of the `packed-refs` file with its 48 * records sorted by refname. 49 * 50 * `snapshot` instances are reference counted (via 51 * `acquire_snapshot()` and `release_snapshot()`). This is to prevent 52 * an instance from disappearing while an iterator is still iterating 53 * over it. Instances are garbage collected when their `referrers` 54 * count goes to zero. 55 * 56 * The most recent `snapshot`, if available, is referenced by the 57 * `packed_ref_store`. Its freshness is checked whenever 58 * `get_snapshot()` is called; if the existing snapshot is obsolete, a 59 * new snapshot is taken. 60 */ 61struct snapshot { 62 /* 63 * A back-pointer to the packed_ref_store with which this 64 * snapshot is associated: 65 */ 66 struct packed_ref_store *refs; 67 68 /* Is the `packed-refs` file currently mmapped? */ 69 int mmapped; 70 71 /* 72 * The contents of the `packed-refs` file: 73 * 74 * - buf -- a pointer to the start of the memory 75 * - start -- a pointer to the first byte of actual references 76 * (i.e., after the header line, if one is present) 77 * - eof -- a pointer just past the end of the reference 78 * contents 79 * 80 * If the `packed-refs` file was already sorted, `buf` points 81 * at the mmapped contents of the file. If not, it points at 82 * heap-allocated memory containing the contents, sorted. If 83 * there were no contents (e.g., because the file didn't 84 * exist), `buf`, `start`, and `eof` are all NULL. 85 */ 86 char *buf, *start, *eof; 87 88 /* 89 * What is the peeled state of the `packed-refs` file that 90 * this snapshot represents? (This is usually determined from 91 * the file's header.) 92 */ 93 enum { PEELED_NONE, PEELED_TAGS, PEELED_FULLY } peeled; 94 95 /* 96 * Count of references to this instance, including the pointer 97 * from `packed_ref_store::snapshot`, if any. The instance 98 * will not be freed as long as the reference count is 99 * nonzero. 100 */ 101 unsigned int referrers; 102 103 /* 104 * The metadata of the `packed-refs` file from which this 105 * snapshot was created, used to tell if the file has been 106 * replaced since we read it. 107 */ 108 struct stat_validity validity; 109}; 110 111/* 112 * A `ref_store` representing references stored in a `packed-refs` 113 * file. It implements the `ref_store` interface, though it has some 114 * limitations: 115 * 116 * - It cannot store symbolic references. 117 * 118 * - It cannot store reflogs. 119 * 120 * - It does not support reference renaming (though it could). 121 * 122 * On the other hand, it can be locked outside of a reference 123 * transaction. In that case, it remains locked even after the 124 * transaction is done and the new `packed-refs` file is activated. 125 */ 126struct packed_ref_store { 127 struct ref_store base; 128 129 unsigned int store_flags; 130 131 /* The path of the "packed-refs" file: */ 132 char *path; 133 134 /* 135 * A snapshot of the values read from the `packed-refs` file, 136 * if it might still be current; otherwise, NULL. 137 */ 138 struct snapshot *snapshot; 139 140 /* 141 * Lock used for the "packed-refs" file. Note that this (and 142 * thus the enclosing `packed_ref_store`) must not be freed. 143 */ 144 struct lock_file lock; 145 146 /* 147 * Temporary file used when rewriting new contents to the 148 * "packed-refs" file. Note that this (and thus the enclosing 149 * `packed_ref_store`) must not be freed. 150 */ 151 struct tempfile *tempfile; 152}; 153 154/* 155 * Increment the reference count of `*snapshot`. 156 */ 157static void acquire_snapshot(struct snapshot *snapshot) 158{ 159 snapshot->referrers++; 160} 161 162/* 163 * If the buffer in `snapshot` is active, then either munmap the 164 * memory and close the file, or free the memory. Then set the buffer 165 * pointers to NULL. 166 */ 167static void clear_snapshot_buffer(struct snapshot *snapshot) 168{ 169 if (snapshot->mmapped) { 170 if (munmap(snapshot->buf, snapshot->eof - snapshot->buf)) 171 die_errno("error ummapping packed-refs file %s", 172 snapshot->refs->path); 173 snapshot->mmapped = 0; 174 } else { 175 free(snapshot->buf); 176 } 177 snapshot->buf = snapshot->start = snapshot->eof = NULL; 178} 179 180/* 181 * Decrease the reference count of `*snapshot`. If it goes to zero, 182 * free `*snapshot` and return true; otherwise return false. 183 */ 184static int release_snapshot(struct snapshot *snapshot) 185{ 186 if (!--snapshot->referrers) { 187 stat_validity_clear(&snapshot->validity); 188 clear_snapshot_buffer(snapshot); 189 free(snapshot); 190 return 1; 191 } else { 192 return 0; 193 } 194} 195 196struct ref_store *packed_ref_store_create(const char *path, 197 unsigned int store_flags) 198{ 199 struct packed_ref_store *refs = xcalloc(1, sizeof(*refs)); 200 struct ref_store *ref_store = (struct ref_store *)refs; 201 202 base_ref_store_init(ref_store, &refs_be_packed); 203 refs->store_flags = store_flags; 204 205 refs->path = xstrdup(path); 206 chdir_notify_reparent("packed-refs", &refs->path); 207 208 return ref_store; 209} 210 211/* 212 * Downcast `ref_store` to `packed_ref_store`. Die if `ref_store` is 213 * not a `packed_ref_store`. Also die if `packed_ref_store` doesn't 214 * support at least the flags specified in `required_flags`. `caller` 215 * is used in any necessary error messages. 216 */ 217static struct packed_ref_store *packed_downcast(struct ref_store *ref_store, 218 unsigned int required_flags, 219 const char *caller) 220{ 221 struct packed_ref_store *refs; 222 223 if (ref_store->be != &refs_be_packed) 224 BUG("ref_store is type \"%s\" not \"packed\" in %s", 225 ref_store->be->name, caller); 226 227 refs = (struct packed_ref_store *)ref_store; 228 229 if ((refs->store_flags & required_flags) != required_flags) 230 BUG("unallowed operation (%s), requires %x, has %x\n", 231 caller, required_flags, refs->store_flags); 232 233 return refs; 234} 235 236static void clear_snapshot(struct packed_ref_store *refs) 237{ 238 if (refs->snapshot) { 239 struct snapshot *snapshot = refs->snapshot; 240 241 refs->snapshot = NULL; 242 release_snapshot(snapshot); 243 } 244} 245 246static NORETURN void die_unterminated_line(const char *path, 247 const char *p, size_t len) 248{ 249 if (len < 80) 250 die("unterminated line in %s: %.*s", path, (int)len, p); 251 else 252 die("unterminated line in %s: %.75s...", path, p); 253} 254 255static NORETURN void die_invalid_line(const char *path, 256 const char *p, size_t len) 257{ 258 const char *eol = memchr(p, '\n', len); 259 260 if (!eol) 261 die_unterminated_line(path, p, len); 262 else if (eol - p < 80) 263 die("unexpected line in %s: %.*s", path, (int)(eol - p), p); 264 else 265 die("unexpected line in %s: %.75s...", path, p); 266 267} 268 269struct snapshot_record { 270 const char *start; 271 size_t len; 272}; 273 274static int cmp_packed_ref_records(const void *v1, const void *v2) 275{ 276 const struct snapshot_record *e1 = v1, *e2 = v2; 277 const char *r1 = e1->start + GIT_SHA1_HEXSZ + 1; 278 const char *r2 = e2->start + GIT_SHA1_HEXSZ + 1; 279 280 while (1) { 281 if (*r1 == '\n') 282 return *r2 == '\n' ? 0 : -1; 283 if (*r1 != *r2) { 284 if (*r2 == '\n') 285 return 1; 286 else 287 return (unsigned char)*r1 < (unsigned char)*r2 ? -1 : +1; 288 } 289 r1++; 290 r2++; 291 } 292} 293 294/* 295 * Compare a snapshot record at `rec` to the specified NUL-terminated 296 * refname. 297 */ 298static int cmp_record_to_refname(const char *rec, const char *refname) 299{ 300 const char *r1 = rec + GIT_SHA1_HEXSZ + 1; 301 const char *r2 = refname; 302 303 while (1) { 304 if (*r1 == '\n') 305 return *r2 ? -1 : 0; 306 if (!*r2) 307 return 1; 308 if (*r1 != *r2) 309 return (unsigned char)*r1 < (unsigned char)*r2 ? -1 : +1; 310 r1++; 311 r2++; 312 } 313} 314 315/* 316 * `snapshot->buf` is not known to be sorted. Check whether it is, and 317 * if not, sort it into new memory and munmap/free the old storage. 318 */ 319static void sort_snapshot(struct snapshot *snapshot) 320{ 321 struct snapshot_record *records = NULL; 322 size_t alloc = 0, nr = 0; 323 int sorted = 1; 324 const char *pos, *eof, *eol; 325 size_t len, i; 326 char *new_buffer, *dst; 327 328 pos = snapshot->start; 329 eof = snapshot->eof; 330 331 if (pos == eof) 332 return; 333 334 len = eof - pos; 335 336 /* 337 * Initialize records based on a crude estimate of the number 338 * of references in the file (we'll grow it below if needed): 339 */ 340 ALLOC_GROW(records, len / 80 + 20, alloc); 341 342 while (pos < eof) { 343 eol = memchr(pos, '\n', eof - pos); 344 if (!eol) 345 /* The safety check should prevent this. */ 346 BUG("unterminated line found in packed-refs"); 347 if (eol - pos < GIT_SHA1_HEXSZ + 2) 348 die_invalid_line(snapshot->refs->path, 349 pos, eof - pos); 350 eol++; 351 if (eol < eof && *eol == '^') { 352 /* 353 * Keep any peeled line together with its 354 * reference: 355 */ 356 const char *peeled_start = eol; 357 358 eol = memchr(peeled_start, '\n', eof - peeled_start); 359 if (!eol) 360 /* The safety check should prevent this. */ 361 BUG("unterminated peeled line found in packed-refs"); 362 eol++; 363 } 364 365 ALLOC_GROW(records, nr + 1, alloc); 366 records[nr].start = pos; 367 records[nr].len = eol - pos; 368 nr++; 369 370 if (sorted && 371 nr > 1 && 372 cmp_packed_ref_records(&records[nr - 2], 373 &records[nr - 1]) >= 0) 374 sorted = 0; 375 376 pos = eol; 377 } 378 379 if (sorted) 380 goto cleanup; 381 382 /* We need to sort the memory. First we sort the records array: */ 383 QSORT(records, nr, cmp_packed_ref_records); 384 385 /* 386 * Allocate a new chunk of memory, and copy the old memory to 387 * the new in the order indicated by `records` (not bothering 388 * with the header line): 389 */ 390 new_buffer = xmalloc(len); 391 for (dst = new_buffer, i = 0; i < nr; i++) { 392 memcpy(dst, records[i].start, records[i].len); 393 dst += records[i].len; 394 } 395 396 /* 397 * Now munmap the old buffer and use the sorted buffer in its 398 * place: 399 */ 400 clear_snapshot_buffer(snapshot); 401 snapshot->buf = snapshot->start = new_buffer; 402 snapshot->eof = new_buffer + len; 403 404cleanup: 405 free(records); 406} 407 408/* 409 * Return a pointer to the start of the record that contains the 410 * character `*p` (which must be within the buffer). If no other 411 * record start is found, return `buf`. 412 */ 413static const char *find_start_of_record(const char *buf, const char *p) 414{ 415 while (p > buf && (p[-1] != '\n' || p[0] == '^')) 416 p--; 417 return p; 418} 419 420/* 421 * Return a pointer to the start of the record following the record 422 * that contains `*p`. If none is found before `end`, return `end`. 423 */ 424static const char *find_end_of_record(const char *p, const char *end) 425{ 426 while (++p < end && (p[-1] != '\n' || p[0] == '^')) 427 ; 428 return p; 429} 430 431/* 432 * We want to be able to compare mmapped reference records quickly, 433 * without totally parsing them. We can do so because the records are 434 * LF-terminated, and the refname should start exactly (GIT_SHA1_HEXSZ 435 * + 1) bytes past the beginning of the record. 436 * 437 * But what if the `packed-refs` file contains garbage? We're willing 438 * to tolerate not detecting the problem, as long as we don't produce 439 * totally garbled output (we can't afford to check the integrity of 440 * the whole file during every Git invocation). But we do want to be 441 * sure that we never read past the end of the buffer in memory and 442 * perform an illegal memory access. 443 * 444 * Guarantee that minimum level of safety by verifying that the last 445 * record in the file is LF-terminated, and that it has at least 446 * (GIT_SHA1_HEXSZ + 1) characters before the LF. Die if either of 447 * these checks fails. 448 */ 449static void verify_buffer_safe(struct snapshot *snapshot) 450{ 451 const char *start = snapshot->start; 452 const char *eof = snapshot->eof; 453 const char *last_line; 454 455 if (start == eof) 456 return; 457 458 last_line = find_start_of_record(start, eof - 1); 459 if (*(eof - 1) != '\n' || eof - last_line < GIT_SHA1_HEXSZ + 2) 460 die_invalid_line(snapshot->refs->path, 461 last_line, eof - last_line); 462} 463 464#define SMALL_FILE_SIZE (32*1024) 465 466/* 467 * Depending on `mmap_strategy`, either mmap or read the contents of 468 * the `packed-refs` file into the snapshot. Return 1 if the file 469 * existed and was read, or 0 if the file was absent or empty. Die on 470 * errors. 471 */ 472static int load_contents(struct snapshot *snapshot) 473{ 474 int fd; 475 struct stat st; 476 size_t size; 477 ssize_t bytes_read; 478 479 fd = open(snapshot->refs->path, O_RDONLY); 480 if (fd < 0) { 481 if (errno == ENOENT) { 482 /* 483 * This is OK; it just means that no 484 * "packed-refs" file has been written yet, 485 * which is equivalent to it being empty, 486 * which is its state when initialized with 487 * zeros. 488 */ 489 return 0; 490 } else { 491 die_errno("couldn't read %s", snapshot->refs->path); 492 } 493 } 494 495 stat_validity_update(&snapshot->validity, fd); 496 497 if (fstat(fd, &st) < 0) 498 die_errno("couldn't stat %s", snapshot->refs->path); 499 size = xsize_t(st.st_size); 500 501 if (!size) { 502 return 0; 503 } else if (mmap_strategy == MMAP_NONE || size <= SMALL_FILE_SIZE) { 504 snapshot->buf = xmalloc(size); 505 bytes_read = read_in_full(fd, snapshot->buf, size); 506 if (bytes_read < 0 || bytes_read != size) 507 die_errno("couldn't read %s", snapshot->refs->path); 508 snapshot->mmapped = 0; 509 } else { 510 snapshot->buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 511 snapshot->mmapped = 1; 512 } 513 close(fd); 514 515 snapshot->start = snapshot->buf; 516 snapshot->eof = snapshot->buf + size; 517 518 return 1; 519} 520 521/* 522 * Find the place in `snapshot->buf` where the start of the record for 523 * `refname` starts. If `mustexist` is true and the reference doesn't 524 * exist, then return NULL. If `mustexist` is false and the reference 525 * doesn't exist, then return the point where that reference would be 526 * inserted, or `snapshot->eof` (which might be NULL) if it would be 527 * inserted at the end of the file. In the latter mode, `refname` 528 * doesn't have to be a proper reference name; for example, one could 529 * search for "refs/replace/" to find the start of any replace 530 * references. 531 * 532 * The record is sought using a binary search, so `snapshot->buf` must 533 * be sorted. 534 */ 535static const char *find_reference_location(struct snapshot *snapshot, 536 const char *refname, int mustexist) 537{ 538 /* 539 * This is not *quite* a garden-variety binary search, because 540 * the data we're searching is made up of records, and we 541 * always need to find the beginning of a record to do a 542 * comparison. A "record" here is one line for the reference 543 * itself and zero or one peel lines that start with '^'. Our 544 * loop invariant is described in the next two comments. 545 */ 546 547 /* 548 * A pointer to the character at the start of a record whose 549 * preceding records all have reference names that come 550 * *before* `refname`. 551 */ 552 const char *lo = snapshot->start; 553 554 /* 555 * A pointer to a the first character of a record whose 556 * reference name comes *after* `refname`. 557 */ 558 const char *hi = snapshot->eof; 559 560 while (lo != hi) { 561 const char *mid, *rec; 562 int cmp; 563 564 mid = lo + (hi - lo) / 2; 565 rec = find_start_of_record(lo, mid); 566 cmp = cmp_record_to_refname(rec, refname); 567 if (cmp < 0) { 568 lo = find_end_of_record(mid, hi); 569 } else if (cmp > 0) { 570 hi = rec; 571 } else { 572 return rec; 573 } 574 } 575 576 if (mustexist) 577 return NULL; 578 else 579 return lo; 580} 581 582/* 583 * Create a newly-allocated `snapshot` of the `packed-refs` file in 584 * its current state and return it. The return value will already have 585 * its reference count incremented. 586 * 587 * A comment line of the form "# pack-refs with: " may contain zero or 588 * more traits. We interpret the traits as follows: 589 * 590 * Neither `peeled` nor `fully-peeled`: 591 * 592 * Probably no references are peeled. But if the file contains a 593 * peeled value for a reference, we will use it. 594 * 595 * `peeled`: 596 * 597 * References under "refs/tags/", if they *can* be peeled, *are* 598 * peeled in this file. References outside of "refs/tags/" are 599 * probably not peeled even if they could have been, but if we find 600 * a peeled value for such a reference we will use it. 601 * 602 * `fully-peeled`: 603 * 604 * All references in the file that can be peeled are peeled. 605 * Inversely (and this is more important), any references in the 606 * file for which no peeled value is recorded is not peelable. This 607 * trait should typically be written alongside "peeled" for 608 * compatibility with older clients, but we do not require it 609 * (i.e., "peeled" is a no-op if "fully-peeled" is set). 610 * 611 * `sorted`: 612 * 613 * The references in this file are known to be sorted by refname. 614 */ 615static struct snapshot *create_snapshot(struct packed_ref_store *refs) 616{ 617 struct snapshot *snapshot = xcalloc(1, sizeof(*snapshot)); 618 int sorted = 0; 619 620 snapshot->refs = refs; 621 acquire_snapshot(snapshot); 622 snapshot->peeled = PEELED_NONE; 623 624 if (!load_contents(snapshot)) 625 return snapshot; 626 627 /* If the file has a header line, process it: */ 628 if (snapshot->buf < snapshot->eof && *snapshot->buf == '#') { 629 char *tmp, *p, *eol; 630 struct string_list traits = STRING_LIST_INIT_NODUP; 631 632 eol = memchr(snapshot->buf, '\n', 633 snapshot->eof - snapshot->buf); 634 if (!eol) 635 die_unterminated_line(refs->path, 636 snapshot->buf, 637 snapshot->eof - snapshot->buf); 638 639 tmp = xmemdupz(snapshot->buf, eol - snapshot->buf); 640 641 if (!skip_prefix(tmp, "# pack-refs with:", (const char **)&p)) 642 die_invalid_line(refs->path, 643 snapshot->buf, 644 snapshot->eof - snapshot->buf); 645 646 string_list_split_in_place(&traits, p, ' ', -1); 647 648 if (unsorted_string_list_has_string(&traits, "fully-peeled")) 649 snapshot->peeled = PEELED_FULLY; 650 else if (unsorted_string_list_has_string(&traits, "peeled")) 651 snapshot->peeled = PEELED_TAGS; 652 653 sorted = unsorted_string_list_has_string(&traits, "sorted"); 654 655 /* perhaps other traits later as well */ 656 657 /* The "+ 1" is for the LF character. */ 658 snapshot->start = eol + 1; 659 660 string_list_clear(&traits, 0); 661 free(tmp); 662 } 663 664 verify_buffer_safe(snapshot); 665 666 if (!sorted) { 667 sort_snapshot(snapshot); 668 669 /* 670 * Reordering the records might have moved a short one 671 * to the end of the buffer, so verify the buffer's 672 * safety again: 673 */ 674 verify_buffer_safe(snapshot); 675 } 676 677 if (mmap_strategy != MMAP_OK && snapshot->mmapped) { 678 /* 679 * We don't want to leave the file mmapped, so we are 680 * forced to make a copy now: 681 */ 682 size_t size = snapshot->eof - snapshot->start; 683 char *buf_copy = xmalloc(size); 684 685 memcpy(buf_copy, snapshot->start, size); 686 clear_snapshot_buffer(snapshot); 687 snapshot->buf = snapshot->start = buf_copy; 688 snapshot->eof = buf_copy + size; 689 } 690 691 return snapshot; 692} 693 694/* 695 * Check that `refs->snapshot` (if present) still reflects the 696 * contents of the `packed-refs` file. If not, clear the snapshot. 697 */ 698static void validate_snapshot(struct packed_ref_store *refs) 699{ 700 if (refs->snapshot && 701 !stat_validity_check(&refs->snapshot->validity, refs->path)) 702 clear_snapshot(refs); 703} 704 705/* 706 * Get the `snapshot` for the specified packed_ref_store, creating and 707 * populating it if it hasn't been read before or if the file has been 708 * changed (according to its `validity` field) since it was last read. 709 * On the other hand, if we hold the lock, then assume that the file 710 * hasn't been changed out from under us, so skip the extra `stat()` 711 * call in `stat_validity_check()`. This function does *not* increase 712 * the snapshot's reference count on behalf of the caller. 713 */ 714static struct snapshot *get_snapshot(struct packed_ref_store *refs) 715{ 716 if (!is_lock_file_locked(&refs->lock)) 717 validate_snapshot(refs); 718 719 if (!refs->snapshot) 720 refs->snapshot = create_snapshot(refs); 721 722 return refs->snapshot; 723} 724 725static int packed_read_raw_ref(struct ref_store *ref_store, 726 const char *refname, struct object_id *oid, 727 struct strbuf *referent, unsigned int *type) 728{ 729 struct packed_ref_store *refs = 730 packed_downcast(ref_store, REF_STORE_READ, "read_raw_ref"); 731 struct snapshot *snapshot = get_snapshot(refs); 732 const char *rec; 733 734 *type = 0; 735 736 rec = find_reference_location(snapshot, refname, 1); 737 738 if (!rec) { 739 /* refname is not a packed reference. */ 740 errno = ENOENT; 741 return -1; 742 } 743 744 if (get_oid_hex(rec, oid)) 745 die_invalid_line(refs->path, rec, snapshot->eof - rec); 746 747 *type = REF_ISPACKED; 748 return 0; 749} 750 751/* 752 * This value is set in `base.flags` if the peeled value of the 753 * current reference is known. In that case, `peeled` contains the 754 * correct peeled value for the reference, which might be `null_oid` 755 * if the reference is not a tag or if it is broken. 756 */ 757#define REF_KNOWS_PEELED 0x40 758 759/* 760 * An iterator over a snapshot of a `packed-refs` file. 761 */ 762struct packed_ref_iterator { 763 struct ref_iterator base; 764 765 struct snapshot *snapshot; 766 767 /* The current position in the snapshot's buffer: */ 768 const char *pos; 769 770 /* The end of the part of the buffer that will be iterated over: */ 771 const char *eof; 772 773 /* Scratch space for current values: */ 774 struct object_id oid, peeled; 775 struct strbuf refname_buf; 776 777 unsigned int flags; 778}; 779 780/* 781 * Move the iterator to the next record in the snapshot, without 782 * respect for whether the record is actually required by the current 783 * iteration. Adjust the fields in `iter` and return `ITER_OK` or 784 * `ITER_DONE`. This function does not free the iterator in the case 785 * of `ITER_DONE`. 786 */ 787static int next_record(struct packed_ref_iterator *iter) 788{ 789 const char *p = iter->pos, *eol; 790 791 strbuf_reset(&iter->refname_buf); 792 793 if (iter->pos == iter->eof) 794 return ITER_DONE; 795 796 iter->base.flags = REF_ISPACKED; 797 798 if (iter->eof - p < GIT_SHA1_HEXSZ + 2 || 799 parse_oid_hex(p, &iter->oid, &p) || 800 !isspace(*p++)) 801 die_invalid_line(iter->snapshot->refs->path, 802 iter->pos, iter->eof - iter->pos); 803 804 eol = memchr(p, '\n', iter->eof - p); 805 if (!eol) 806 die_unterminated_line(iter->snapshot->refs->path, 807 iter->pos, iter->eof - iter->pos); 808 809 strbuf_add(&iter->refname_buf, p, eol - p); 810 iter->base.refname = iter->refname_buf.buf; 811 812 if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) { 813 if (!refname_is_safe(iter->base.refname)) 814 die("packed refname is dangerous: %s", 815 iter->base.refname); 816 oidclr(&iter->oid); 817 iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN; 818 } 819 if (iter->snapshot->peeled == PEELED_FULLY || 820 (iter->snapshot->peeled == PEELED_TAGS && 821 starts_with(iter->base.refname, "refs/tags/"))) 822 iter->base.flags |= REF_KNOWS_PEELED; 823 824 iter->pos = eol + 1; 825 826 if (iter->pos < iter->eof && *iter->pos == '^') { 827 p = iter->pos + 1; 828 if (iter->eof - p < GIT_SHA1_HEXSZ + 1 || 829 parse_oid_hex(p, &iter->peeled, &p) || 830 *p++ != '\n') 831 die_invalid_line(iter->snapshot->refs->path, 832 iter->pos, iter->eof - iter->pos); 833 iter->pos = p; 834 835 /* 836 * Regardless of what the file header said, we 837 * definitely know the value of *this* reference. But 838 * we suppress it if the reference is broken: 839 */ 840 if ((iter->base.flags & REF_ISBROKEN)) { 841 oidclr(&iter->peeled); 842 iter->base.flags &= ~REF_KNOWS_PEELED; 843 } else { 844 iter->base.flags |= REF_KNOWS_PEELED; 845 } 846 } else { 847 oidclr(&iter->peeled); 848 } 849 850 return ITER_OK; 851} 852 853static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator) 854{ 855 struct packed_ref_iterator *iter = 856 (struct packed_ref_iterator *)ref_iterator; 857 int ok; 858 859 while ((ok = next_record(iter)) == ITER_OK) { 860 if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && 861 ref_type(iter->base.refname) != REF_TYPE_PER_WORKTREE) 862 continue; 863 864 if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && 865 !ref_resolves_to_object(iter->base.refname, &iter->oid, 866 iter->flags)) 867 continue; 868 869 return ITER_OK; 870 } 871 872 if (ref_iterator_abort(ref_iterator) != ITER_DONE) 873 ok = ITER_ERROR; 874 875 return ok; 876} 877 878static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator, 879 struct object_id *peeled) 880{ 881 struct packed_ref_iterator *iter = 882 (struct packed_ref_iterator *)ref_iterator; 883 884 if ((iter->base.flags & REF_KNOWS_PEELED)) { 885 oidcpy(peeled, &iter->peeled); 886 return is_null_oid(&iter->peeled) ? -1 : 0; 887 } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) { 888 return -1; 889 } else { 890 return !!peel_object(&iter->oid, peeled); 891 } 892} 893 894static int packed_ref_iterator_abort(struct ref_iterator *ref_iterator) 895{ 896 struct packed_ref_iterator *iter = 897 (struct packed_ref_iterator *)ref_iterator; 898 int ok = ITER_DONE; 899 900 strbuf_release(&iter->refname_buf); 901 release_snapshot(iter->snapshot); 902 base_ref_iterator_free(ref_iterator); 903 return ok; 904} 905 906static struct ref_iterator_vtable packed_ref_iterator_vtable = { 907 packed_ref_iterator_advance, 908 packed_ref_iterator_peel, 909 packed_ref_iterator_abort 910}; 911 912static struct ref_iterator *packed_ref_iterator_begin( 913 struct ref_store *ref_store, 914 const char *prefix, unsigned int flags) 915{ 916 struct packed_ref_store *refs; 917 struct snapshot *snapshot; 918 const char *start; 919 struct packed_ref_iterator *iter; 920 struct ref_iterator *ref_iterator; 921 unsigned int required_flags = REF_STORE_READ; 922 923 if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) 924 required_flags |= REF_STORE_ODB; 925 refs = packed_downcast(ref_store, required_flags, "ref_iterator_begin"); 926 927 /* 928 * Note that `get_snapshot()` internally checks whether the 929 * snapshot is up to date with what is on disk, and re-reads 930 * it if not. 931 */ 932 snapshot = get_snapshot(refs); 933 934 if (prefix && *prefix) 935 start = find_reference_location(snapshot, prefix, 0); 936 else 937 start = snapshot->start; 938 939 if (start == snapshot->eof) 940 return empty_ref_iterator_begin(); 941 942 iter = xcalloc(1, sizeof(*iter)); 943 ref_iterator = &iter->base; 944 base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1); 945 946 iter->snapshot = snapshot; 947 acquire_snapshot(snapshot); 948 949 iter->pos = start; 950 iter->eof = snapshot->eof; 951 strbuf_init(&iter->refname_buf, 0); 952 953 iter->base.oid = &iter->oid; 954 955 iter->flags = flags; 956 957 if (prefix && *prefix) 958 /* Stop iteration after we've gone *past* prefix: */ 959 ref_iterator = prefix_ref_iterator_begin(ref_iterator, prefix, 0); 960 961 return ref_iterator; 962} 963 964/* 965 * Write an entry to the packed-refs file for the specified refname. 966 * If peeled is non-NULL, write it as the entry's peeled value. On 967 * error, return a nonzero value and leave errno set at the value left 968 * by the failing call to `fprintf()`. 969 */ 970static int write_packed_entry(FILE *fh, const char *refname, 971 const struct object_id *oid, 972 const struct object_id *peeled) 973{ 974 if (fprintf(fh, "%s %s\n", oid_to_hex(oid), refname) < 0 || 975 (peeled && fprintf(fh, "^%s\n", oid_to_hex(peeled)) < 0)) 976 return -1; 977 978 return 0; 979} 980 981int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) 982{ 983 struct packed_ref_store *refs = 984 packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN, 985 "packed_refs_lock"); 986 static int timeout_configured = 0; 987 static int timeout_value = 1000; 988 989 if (!timeout_configured) { 990 git_config_get_int("core.packedrefstimeout", &timeout_value); 991 timeout_configured = 1; 992 } 993 994 /* 995 * Note that we close the lockfile immediately because we 996 * don't write new content to it, but rather to a separate 997 * tempfile. 998 */ 999 if (hold_lock_file_for_update_timeout(1000 &refs->lock,1001 refs->path,1002 flags, timeout_value) < 0) {1003 unable_to_lock_message(refs->path, errno, err);1004 return -1;1005 }10061007 if (close_lock_file_gently(&refs->lock)) {1008 strbuf_addf(err, "unable to close %s: %s", refs->path, strerror(errno));1009 rollback_lock_file(&refs->lock);1010 return -1;1011 }10121013 /*1014 * Now that we hold the `packed-refs` lock, make sure that our1015 * snapshot matches the current version of the file. Normally1016 * `get_snapshot()` does that for us, but that function1017 * assumes that when the file is locked, any existing snapshot1018 * is still valid. We've just locked the file, but it might1019 * have changed the moment *before* we locked it.1020 */1021 validate_snapshot(refs);10221023 /*1024 * Now make sure that the packed-refs file as it exists in the1025 * locked state is loaded into the snapshot:1026 */1027 get_snapshot(refs);1028 return 0;1029}10301031void packed_refs_unlock(struct ref_store *ref_store)1032{1033 struct packed_ref_store *refs = packed_downcast(1034 ref_store,1035 REF_STORE_READ | REF_STORE_WRITE,1036 "packed_refs_unlock");10371038 if (!is_lock_file_locked(&refs->lock))1039 BUG("packed_refs_unlock() called when not locked");1040 rollback_lock_file(&refs->lock);1041}10421043int packed_refs_is_locked(struct ref_store *ref_store)1044{1045 struct packed_ref_store *refs = packed_downcast(1046 ref_store,1047 REF_STORE_READ | REF_STORE_WRITE,1048 "packed_refs_is_locked");10491050 return is_lock_file_locked(&refs->lock);1051}10521053/*1054 * The packed-refs header line that we write out. Perhaps other traits1055 * will be added later.1056 *1057 * Note that earlier versions of Git used to parse these traits by1058 * looking for " trait " in the line. For this reason, the space after1059 * the colon and the trailing space are required.1060 */1061static const char PACKED_REFS_HEADER[] =1062 "# pack-refs with: peeled fully-peeled sorted \n";10631064static int packed_init_db(struct ref_store *ref_store, struct strbuf *err)1065{1066 /* Nothing to do. */1067 return 0;1068}10691070/*1071 * Write the packed refs from the current snapshot to the packed-refs1072 * tempfile, incorporating any changes from `updates`. `updates` must1073 * be a sorted string list whose keys are the refnames and whose util1074 * values are `struct ref_update *`. On error, rollback the tempfile,1075 * write an error message to `err`, and return a nonzero value.1076 *1077 * The packfile must be locked before calling this function and will1078 * remain locked when it is done.1079 */1080static int write_with_updates(struct packed_ref_store *refs,1081 struct string_list *updates,1082 struct strbuf *err)1083{1084 struct ref_iterator *iter = NULL;1085 size_t i;1086 int ok;1087 FILE *out;1088 struct strbuf sb = STRBUF_INIT;1089 char *packed_refs_path;10901091 if (!is_lock_file_locked(&refs->lock))1092 BUG("write_with_updates() called while unlocked");10931094 /*1095 * If packed-refs is a symlink, we want to overwrite the1096 * symlinked-to file, not the symlink itself. Also, put the1097 * staging file next to it:1098 */1099 packed_refs_path = get_locked_file_path(&refs->lock);1100 strbuf_addf(&sb, "%s.new", packed_refs_path);1101 free(packed_refs_path);1102 refs->tempfile = create_tempfile(sb.buf);1103 if (!refs->tempfile) {1104 strbuf_addf(err, "unable to create file %s: %s",1105 sb.buf, strerror(errno));1106 strbuf_release(&sb);1107 return -1;1108 }1109 strbuf_release(&sb);11101111 out = fdopen_tempfile(refs->tempfile, "w");1112 if (!out) {1113 strbuf_addf(err, "unable to fdopen packed-refs tempfile: %s",1114 strerror(errno));1115 goto error;1116 }11171118 if (fprintf(out, "%s", PACKED_REFS_HEADER) < 0)1119 goto write_error;11201121 /*1122 * We iterate in parallel through the current list of refs and1123 * the list of updates, processing an entry from at least one1124 * of the lists each time through the loop. When the current1125 * list of refs is exhausted, set iter to NULL. When the list1126 * of updates is exhausted, leave i set to updates->nr.1127 */1128 iter = packed_ref_iterator_begin(&refs->base, "",1129 DO_FOR_EACH_INCLUDE_BROKEN);1130 if ((ok = ref_iterator_advance(iter)) != ITER_OK)1131 iter = NULL;11321133 i = 0;11341135 while (iter || i < updates->nr) {1136 struct ref_update *update = NULL;1137 int cmp;11381139 if (i >= updates->nr) {1140 cmp = -1;1141 } else {1142 update = updates->items[i].util;11431144 if (!iter)1145 cmp = +1;1146 else1147 cmp = strcmp(iter->refname, update->refname);1148 }11491150 if (!cmp) {1151 /*1152 * There is both an old value and an update1153 * for this reference. Check the old value if1154 * necessary:1155 */1156 if ((update->flags & REF_HAVE_OLD)) {1157 if (is_null_oid(&update->old_oid)) {1158 strbuf_addf(err, "cannot update ref '%s': "1159 "reference already exists",1160 update->refname);1161 goto error;1162 } else if (oidcmp(&update->old_oid, iter->oid)) {1163 strbuf_addf(err, "cannot update ref '%s': "1164 "is at %s but expected %s",1165 update->refname,1166 oid_to_hex(iter->oid),1167 oid_to_hex(&update->old_oid));1168 goto error;1169 }1170 }11711172 /* Now figure out what to use for the new value: */1173 if ((update->flags & REF_HAVE_NEW)) {1174 /*1175 * The update takes precedence. Skip1176 * the iterator over the unneeded1177 * value.1178 */1179 if ((ok = ref_iterator_advance(iter)) != ITER_OK)1180 iter = NULL;1181 cmp = +1;1182 } else {1183 /*1184 * The update doesn't actually want to1185 * change anything. We're done with it.1186 */1187 i++;1188 cmp = -1;1189 }1190 } else if (cmp > 0) {1191 /*1192 * There is no old value but there is an1193 * update for this reference. Make sure that1194 * the update didn't expect an existing value:1195 */1196 if ((update->flags & REF_HAVE_OLD) &&1197 !is_null_oid(&update->old_oid)) {1198 strbuf_addf(err, "cannot update ref '%s': "1199 "reference is missing but expected %s",1200 update->refname,1201 oid_to_hex(&update->old_oid));1202 goto error;1203 }1204 }12051206 if (cmp < 0) {1207 /* Pass the old reference through. */12081209 struct object_id peeled;1210 int peel_error = ref_iterator_peel(iter, &peeled);12111212 if (write_packed_entry(out, iter->refname,1213 iter->oid,1214 peel_error ? NULL : &peeled))1215 goto write_error;12161217 if ((ok = ref_iterator_advance(iter)) != ITER_OK)1218 iter = NULL;1219 } else if (is_null_oid(&update->new_oid)) {1220 /*1221 * The update wants to delete the reference,1222 * and the reference either didn't exist or we1223 * have already skipped it. So we're done with1224 * the update (and don't have to write1225 * anything).1226 */1227 i++;1228 } else {1229 struct object_id peeled;1230 int peel_error = peel_object(&update->new_oid,1231 &peeled);12321233 if (write_packed_entry(out, update->refname,1234 &update->new_oid,1235 peel_error ? NULL : &peeled))1236 goto write_error;12371238 i++;1239 }1240 }12411242 if (ok != ITER_DONE) {1243 strbuf_addstr(err, "unable to write packed-refs file: "1244 "error iterating over old contents");1245 goto error;1246 }12471248 if (close_tempfile_gently(refs->tempfile)) {1249 strbuf_addf(err, "error closing file %s: %s",1250 get_tempfile_path(refs->tempfile),1251 strerror(errno));1252 strbuf_release(&sb);1253 delete_tempfile(&refs->tempfile);1254 return -1;1255 }12561257 return 0;12581259write_error:1260 strbuf_addf(err, "error writing to %s: %s",1261 get_tempfile_path(refs->tempfile), strerror(errno));12621263error:1264 if (iter)1265 ref_iterator_abort(iter);12661267 delete_tempfile(&refs->tempfile);1268 return -1;1269}12701271int is_packed_transaction_needed(struct ref_store *ref_store,1272 struct ref_transaction *transaction)1273{1274 struct packed_ref_store *refs = packed_downcast(1275 ref_store,1276 REF_STORE_READ,1277 "is_packed_transaction_needed");1278 struct strbuf referent = STRBUF_INIT;1279 size_t i;1280 int ret;12811282 if (!is_lock_file_locked(&refs->lock))1283 BUG("is_packed_transaction_needed() called while unlocked");12841285 /*1286 * We're only going to bother returning false for the common,1287 * trivial case that references are only being deleted, their1288 * old values are not being checked, and the old `packed-refs`1289 * file doesn't contain any of those reference(s). This gives1290 * false positives for some other cases that could1291 * theoretically be optimized away:1292 *1293 * 1. It could be that the old value is being verified without1294 * setting a new value. In this case, we could verify the1295 * old value here and skip the update if it agrees. If it1296 * disagrees, we could either let the update go through1297 * (the actual commit would re-detect and report the1298 * problem), or come up with a way of reporting such an1299 * error to *our* caller.1300 *1301 * 2. It could be that a new value is being set, but that it1302 * is identical to the current packed value of the1303 * reference.1304 *1305 * Neither of these cases will come up in the current code,1306 * because the only caller of this function passes to it a1307 * transaction that only includes `delete` updates with no1308 * `old_id`. Even if that ever changes, false positives only1309 * cause an optimization to be missed; they do not affect1310 * correctness.1311 */13121313 /*1314 * Start with the cheap checks that don't require old1315 * reference values to be read:1316 */1317 for (i = 0; i < transaction->nr; i++) {1318 struct ref_update *update = transaction->updates[i];13191320 if (update->flags & REF_HAVE_OLD)1321 /* Have to check the old value -> needed. */1322 return 1;13231324 if ((update->flags & REF_HAVE_NEW) && !is_null_oid(&update->new_oid))1325 /* Have to set a new value -> needed. */1326 return 1;1327 }13281329 /*1330 * The transaction isn't checking any old values nor is it1331 * setting any nonzero new values, so it still might be able1332 * to be skipped. Now do the more expensive check: the update1333 * is needed if any of the updates is a delete, and the old1334 * `packed-refs` file contains a value for that reference.1335 */1336 ret = 0;1337 for (i = 0; i < transaction->nr; i++) {1338 struct ref_update *update = transaction->updates[i];1339 unsigned int type;1340 struct object_id oid;13411342 if (!(update->flags & REF_HAVE_NEW))1343 /*1344 * This reference isn't being deleted -> not1345 * needed.1346 */1347 continue;13481349 if (!refs_read_raw_ref(ref_store, update->refname,1350 &oid, &referent, &type) ||1351 errno != ENOENT) {1352 /*1353 * We have to actually delete that reference1354 * -> this transaction is needed.1355 */1356 ret = 1;1357 break;1358 }1359 }13601361 strbuf_release(&referent);1362 return ret;1363}13641365struct packed_transaction_backend_data {1366 /* True iff the transaction owns the packed-refs lock. */1367 int own_lock;13681369 struct string_list updates;1370};13711372static void packed_transaction_cleanup(struct packed_ref_store *refs,1373 struct ref_transaction *transaction)1374{1375 struct packed_transaction_backend_data *data = transaction->backend_data;13761377 if (data) {1378 string_list_clear(&data->updates, 0);13791380 if (is_tempfile_active(refs->tempfile))1381 delete_tempfile(&refs->tempfile);13821383 if (data->own_lock && is_lock_file_locked(&refs->lock)) {1384 packed_refs_unlock(&refs->base);1385 data->own_lock = 0;1386 }13871388 free(data);1389 transaction->backend_data = NULL;1390 }13911392 transaction->state = REF_TRANSACTION_CLOSED;1393}13941395static int packed_transaction_prepare(struct ref_store *ref_store,1396 struct ref_transaction *transaction,1397 struct strbuf *err)1398{1399 struct packed_ref_store *refs = packed_downcast(1400 ref_store,1401 REF_STORE_READ | REF_STORE_WRITE | REF_STORE_ODB,1402 "ref_transaction_prepare");1403 struct packed_transaction_backend_data *data;1404 size_t i;1405 int ret = TRANSACTION_GENERIC_ERROR;14061407 /*1408 * Note that we *don't* skip transactions with zero updates,1409 * because such a transaction might be executed for the side1410 * effect of ensuring that all of the references are peeled or1411 * ensuring that the `packed-refs` file is sorted. If the1412 * caller wants to optimize away empty transactions, it should1413 * do so itself.1414 */14151416 data = xcalloc(1, sizeof(*data));1417 string_list_init(&data->updates, 0);14181419 transaction->backend_data = data;14201421 /*1422 * Stick the updates in a string list by refname so that we1423 * can sort them:1424 */1425 for (i = 0; i < transaction->nr; i++) {1426 struct ref_update *update = transaction->updates[i];1427 struct string_list_item *item =1428 string_list_append(&data->updates, update->refname);14291430 /* Store a pointer to update in item->util: */1431 item->util = update;1432 }1433 string_list_sort(&data->updates);14341435 if (ref_update_reject_duplicates(&data->updates, err))1436 goto failure;14371438 if (!is_lock_file_locked(&refs->lock)) {1439 if (packed_refs_lock(ref_store, 0, err))1440 goto failure;1441 data->own_lock = 1;1442 }14431444 if (write_with_updates(refs, &data->updates, err))1445 goto failure;14461447 transaction->state = REF_TRANSACTION_PREPARED;1448 return 0;14491450failure:1451 packed_transaction_cleanup(refs, transaction);1452 return ret;1453}14541455static int packed_transaction_abort(struct ref_store *ref_store,1456 struct ref_transaction *transaction,1457 struct strbuf *err)1458{1459 struct packed_ref_store *refs = packed_downcast(1460 ref_store,1461 REF_STORE_READ | REF_STORE_WRITE | REF_STORE_ODB,1462 "ref_transaction_abort");14631464 packed_transaction_cleanup(refs, transaction);1465 return 0;1466}14671468static int packed_transaction_finish(struct ref_store *ref_store,1469 struct ref_transaction *transaction,1470 struct strbuf *err)1471{1472 struct packed_ref_store *refs = packed_downcast(1473 ref_store,1474 REF_STORE_READ | REF_STORE_WRITE | REF_STORE_ODB,1475 "ref_transaction_finish");1476 int ret = TRANSACTION_GENERIC_ERROR;1477 char *packed_refs_path;14781479 clear_snapshot(refs);14801481 packed_refs_path = get_locked_file_path(&refs->lock);1482 if (rename_tempfile(&refs->tempfile, packed_refs_path)) {1483 strbuf_addf(err, "error replacing %s: %s",1484 refs->path, strerror(errno));1485 goto cleanup;1486 }14871488 ret = 0;14891490cleanup:1491 free(packed_refs_path);1492 packed_transaction_cleanup(refs, transaction);1493 return ret;1494}14951496static int packed_initial_transaction_commit(struct ref_store *ref_store,1497 struct ref_transaction *transaction,1498 struct strbuf *err)1499{1500 return ref_transaction_commit(transaction, err);1501}15021503static int packed_delete_refs(struct ref_store *ref_store, const char *msg,1504 struct string_list *refnames, unsigned int flags)1505{1506 struct packed_ref_store *refs =1507 packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");1508 struct strbuf err = STRBUF_INIT;1509 struct ref_transaction *transaction;1510 struct string_list_item *item;1511 int ret;15121513 (void)refs; /* We need the check above, but don't use the variable */15141515 if (!refnames->nr)1516 return 0;15171518 /*1519 * Since we don't check the references' old_oids, the1520 * individual updates can't fail, so we can pack all of the1521 * updates into a single transaction.1522 */15231524 transaction = ref_store_transaction_begin(ref_store, &err);1525 if (!transaction)1526 return -1;15271528 for_each_string_list_item(item, refnames) {1529 if (ref_transaction_delete(transaction, item->string, NULL,1530 flags, msg, &err)) {1531 warning(_("could not delete reference %s: %s"),1532 item->string, err.buf);1533 strbuf_reset(&err);1534 }1535 }15361537 ret = ref_transaction_commit(transaction, &err);15381539 if (ret) {1540 if (refnames->nr == 1)1541 error(_("could not delete reference %s: %s"),1542 refnames->items[0].string, err.buf);1543 else1544 error(_("could not delete references: %s"), err.buf);1545 }15461547 ref_transaction_free(transaction);1548 strbuf_release(&err);1549 return ret;1550}15511552static int packed_pack_refs(struct ref_store *ref_store, unsigned int flags)1553{1554 /*1555 * Packed refs are already packed. It might be that loose refs1556 * are packed *into* a packed refs store, but that is done by1557 * updating the packed references via a transaction.1558 */1559 return 0;1560}15611562static int packed_create_symref(struct ref_store *ref_store,1563 const char *refname, const char *target,1564 const char *logmsg)1565{1566 BUG("packed reference store does not support symrefs");1567}15681569static int packed_rename_ref(struct ref_store *ref_store,1570 const char *oldrefname, const char *newrefname,1571 const char *logmsg)1572{1573 BUG("packed reference store does not support renaming references");1574}15751576static int packed_copy_ref(struct ref_store *ref_store,1577 const char *oldrefname, const char *newrefname,1578 const char *logmsg)1579{1580 BUG("packed reference store does not support copying references");1581}15821583static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store)1584{1585 return empty_ref_iterator_begin();1586}15871588static int packed_for_each_reflog_ent(struct ref_store *ref_store,1589 const char *refname,1590 each_reflog_ent_fn fn, void *cb_data)1591{1592 return 0;1593}15941595static int packed_for_each_reflog_ent_reverse(struct ref_store *ref_store,1596 const char *refname,1597 each_reflog_ent_fn fn,1598 void *cb_data)1599{1600 return 0;1601}16021603static int packed_reflog_exists(struct ref_store *ref_store,1604 const char *refname)1605{1606 return 0;1607}16081609static int packed_create_reflog(struct ref_store *ref_store,1610 const char *refname, int force_create,1611 struct strbuf *err)1612{1613 BUG("packed reference store does not support reflogs");1614}16151616static int packed_delete_reflog(struct ref_store *ref_store,1617 const char *refname)1618{1619 return 0;1620}16211622static int packed_reflog_expire(struct ref_store *ref_store,1623 const char *refname, const struct object_id *oid,1624 unsigned int flags,1625 reflog_expiry_prepare_fn prepare_fn,1626 reflog_expiry_should_prune_fn should_prune_fn,1627 reflog_expiry_cleanup_fn cleanup_fn,1628 void *policy_cb_data)1629{1630 return 0;1631}16321633struct ref_storage_be refs_be_packed = {1634 NULL,1635 "packed",1636 packed_ref_store_create,1637 packed_init_db,1638 packed_transaction_prepare,1639 packed_transaction_finish,1640 packed_transaction_abort,1641 packed_initial_transaction_commit,16421643 packed_pack_refs,1644 packed_create_symref,1645 packed_delete_refs,1646 packed_rename_ref,1647 packed_copy_ref,16481649 packed_ref_iterator_begin,1650 packed_read_raw_ref,16511652 packed_reflog_iterator_begin,1653 packed_for_each_reflog_ent,1654 packed_for_each_reflog_ent_reverse,1655 packed_reflog_exists,1656 packed_create_reflog,1657 packed_delete_reflog,1658 packed_reflog_expire1659};