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 9enum mmap_strategy { 10 /* 11 * Don't use mmap() at all for reading `packed-refs`. 12 */ 13 MMAP_NONE, 14 15 /* 16 * Can use mmap() for reading `packed-refs`, but the file must 17 * not remain mmapped. This is the usual option on Windows, 18 * where you cannot rename a new version of a file onto a file 19 * that is currently mmapped. 20 */ 21 MMAP_TEMPORARY, 22 23 /* 24 * It is OK to leave the `packed-refs` file mmapped while 25 * arbitrary other code is running. 26 */ 27 MMAP_OK 28}; 29 30#if defined(NO_MMAP) 31static enum mmap_strategy mmap_strategy = MMAP_NONE; 32#elif defined(MMAP_PREVENTS_DELETE) 33static enum mmap_strategy mmap_strategy = MMAP_TEMPORARY; 34#else 35static enum mmap_strategy mmap_strategy = MMAP_OK; 36#endif 37 38struct packed_ref_store; 39 40/* 41 * A `snapshot` represents one snapshot of a `packed-refs` file. 42 * 43 * Normally, this will be a mmapped view of the contents of the 44 * `packed-refs` file at the time the snapshot was created. However, 45 * if the `packed-refs` file was not sorted, this might point at heap 46 * memory holding the contents of the `packed-refs` file with its 47 * records sorted by refname. 48 * 49 * `snapshot` instances are reference counted (via 50 * `acquire_snapshot()` and `release_snapshot()`). This is to prevent 51 * an instance from disappearing while an iterator is still iterating 52 * over it. Instances are garbage collected when their `referrers` 53 * count goes to zero. 54 * 55 * The most recent `snapshot`, if available, is referenced by the 56 * `packed_ref_store`. Its freshness is checked whenever 57 * `get_snapshot()` is called; if the existing snapshot is obsolete, a 58 * new snapshot is taken. 59 */ 60struct snapshot { 61 /* 62 * A back-pointer to the packed_ref_store with which this 63 * snapshot is associated: 64 */ 65 struct packed_ref_store *refs; 66 67 /* Is the `packed-refs` file currently mmapped? */ 68 int mmapped; 69 70 /* 71 * The contents of the `packed-refs` file: 72 * 73 * - buf -- a pointer to the start of the memory 74 * - start -- a pointer to the first byte of actual references 75 * (i.e., after the header line, if one is present) 76 * - eof -- a pointer just past the end of the reference 77 * contents 78 * 79 * If the `packed-refs` file was already sorted, `buf` points 80 * at the mmapped contents of the file. If not, it points at 81 * heap-allocated memory containing the contents, sorted. If 82 * there were no contents (e.g., because the file didn't 83 * exist), `buf`, `start`, and `eof` are all NULL. 84 */ 85 char *buf, *start, *eof; 86 87 /* 88 * What is the peeled state of the `packed-refs` file that 89 * this snapshot represents? (This is usually determined from 90 * the file's header.) 91 */ 92 enum { PEELED_NONE, PEELED_TAGS, PEELED_FULLY } peeled; 93 94 /* 95 * Count of references to this instance, including the pointer 96 * from `packed_ref_store::snapshot`, if any. The instance 97 * will not be freed as long as the reference count is 98 * nonzero. 99 */ 100 unsigned int referrers; 101 102 /* 103 * The metadata of the `packed-refs` file from which this 104 * snapshot was created, used to tell if the file has been 105 * replaced since we read it. 106 */ 107 struct stat_validity validity; 108}; 109 110/* 111 * A `ref_store` representing references stored in a `packed-refs` 112 * file. It implements the `ref_store` interface, though it has some 113 * limitations: 114 * 115 * - It cannot store symbolic references. 116 * 117 * - It cannot store reflogs. 118 * 119 * - It does not support reference renaming (though it could). 120 * 121 * On the other hand, it can be locked outside of a reference 122 * transaction. In that case, it remains locked even after the 123 * transaction is done and the new `packed-refs` file is activated. 124 */ 125struct packed_ref_store { 126 struct ref_store base; 127 128 unsigned int store_flags; 129 130 /* The path of the "packed-refs" file: */ 131 char *path; 132 133 /* 134 * A snapshot of the values read from the `packed-refs` file, 135 * if it might still be current; otherwise, NULL. 136 */ 137 struct snapshot *snapshot; 138 139 /* 140 * Lock used for the "packed-refs" file. Note that this (and 141 * thus the enclosing `packed_ref_store`) must not be freed. 142 */ 143 struct lock_file lock; 144 145 /* 146 * Temporary file used when rewriting new contents to the 147 * "packed-refs" file. Note that this (and thus the enclosing 148 * `packed_ref_store`) must not be freed. 149 */ 150 struct tempfile *tempfile; 151}; 152 153/* 154 * Increment the reference count of `*snapshot`. 155 */ 156static void acquire_snapshot(struct snapshot *snapshot) 157{ 158 snapshot->referrers++; 159} 160 161/* 162 * If the buffer in `snapshot` is active, then either munmap the 163 * memory and close the file, or free the memory. Then set the buffer 164 * pointers to NULL. 165 */ 166static void clear_snapshot_buffer(struct snapshot *snapshot) 167{ 168 if (snapshot->mmapped) { 169 if (munmap(snapshot->buf, snapshot->eof - snapshot->buf)) 170 die_errno("error ummapping packed-refs file %s", 171 snapshot->refs->path); 172 snapshot->mmapped = 0; 173 } else { 174 free(snapshot->buf); 175 } 176 snapshot->buf = snapshot->start = snapshot->eof = NULL; 177} 178 179/* 180 * Decrease the reference count of `*snapshot`. If it goes to zero, 181 * free `*snapshot` and return true; otherwise return false. 182 */ 183static int release_snapshot(struct snapshot *snapshot) 184{ 185 if (!--snapshot->referrers) { 186 stat_validity_clear(&snapshot->validity); 187 clear_snapshot_buffer(snapshot); 188 free(snapshot); 189 return 1; 190 } else { 191 return 0; 192 } 193} 194 195struct ref_store *packed_ref_store_create(const char *path, 196 unsigned int store_flags) 197{ 198 struct packed_ref_store *refs = xcalloc(1, sizeof(*refs)); 199 struct ref_store *ref_store = (struct ref_store *)refs; 200 201 base_ref_store_init(ref_store, &refs_be_packed); 202 refs->store_flags = store_flags; 203 204 refs->path = xstrdup(path); 205 return ref_store; 206} 207 208/* 209 * Downcast `ref_store` to `packed_ref_store`. Die if `ref_store` is 210 * not a `packed_ref_store`. Also die if `packed_ref_store` doesn't 211 * support at least the flags specified in `required_flags`. `caller` 212 * is used in any necessary error messages. 213 */ 214static struct packed_ref_store *packed_downcast(struct ref_store *ref_store, 215 unsigned int required_flags, 216 const char *caller) 217{ 218 struct packed_ref_store *refs; 219 220 if (ref_store->be != &refs_be_packed) 221 die("BUG: ref_store is type \"%s\" not \"packed\" in %s", 222 ref_store->be->name, caller); 223 224 refs = (struct packed_ref_store *)ref_store; 225 226 if ((refs->store_flags & required_flags) != required_flags) 227 die("BUG: unallowed operation (%s), requires %x, has %x\n", 228 caller, required_flags, refs->store_flags); 229 230 return refs; 231} 232 233static void clear_snapshot(struct packed_ref_store *refs) 234{ 235 if (refs->snapshot) { 236 struct snapshot *snapshot = refs->snapshot; 237 238 refs->snapshot = NULL; 239 release_snapshot(snapshot); 240 } 241} 242 243static NORETURN void die_unterminated_line(const char *path, 244 const char *p, size_t len) 245{ 246 if (len < 80) 247 die("unterminated line in %s: %.*s", path, (int)len, p); 248 else 249 die("unterminated line in %s: %.75s...", path, p); 250} 251 252static NORETURN void die_invalid_line(const char *path, 253 const char *p, size_t len) 254{ 255 const char *eol = memchr(p, '\n', len); 256 257 if (!eol) 258 die_unterminated_line(path, p, len); 259 else if (eol - p < 80) 260 die("unexpected line in %s: %.*s", path, (int)(eol - p), p); 261 else 262 die("unexpected line in %s: %.75s...", path, p); 263 264} 265 266struct snapshot_record { 267 const char *start; 268 size_t len; 269}; 270 271static int cmp_packed_ref_records(const void *v1, const void *v2) 272{ 273 const struct snapshot_record *e1 = v1, *e2 = v2; 274 const char *r1 = e1->start + GIT_SHA1_HEXSZ + 1; 275 const char *r2 = e2->start + GIT_SHA1_HEXSZ + 1; 276 277 while (1) { 278 if (*r1 == '\n') 279 return *r2 == '\n' ? 0 : -1; 280 if (*r1 != *r2) { 281 if (*r2 == '\n') 282 return 1; 283 else 284 return (unsigned char)*r1 < (unsigned char)*r2 ? -1 : +1; 285 } 286 r1++; 287 r2++; 288 } 289} 290 291/* 292 * Compare a snapshot record at `rec` to the specified NUL-terminated 293 * refname. 294 */ 295static int cmp_record_to_refname(const char *rec, const char *refname) 296{ 297 const char *r1 = rec + GIT_SHA1_HEXSZ + 1; 298 const char *r2 = refname; 299 300 while (1) { 301 if (*r1 == '\n') 302 return *r2 ? -1 : 0; 303 if (!*r2) 304 return 1; 305 if (*r1 != *r2) 306 return (unsigned char)*r1 < (unsigned char)*r2 ? -1 : +1; 307 r1++; 308 r2++; 309 } 310} 311 312/* 313 * `snapshot->buf` is not known to be sorted. Check whether it is, and 314 * if not, sort it into new memory and munmap/free the old storage. 315 */ 316static void sort_snapshot(struct snapshot *snapshot) 317{ 318 struct snapshot_record *records = NULL; 319 size_t alloc = 0, nr = 0; 320 int sorted = 1; 321 const char *pos, *eof, *eol; 322 size_t len, i; 323 char *new_buffer, *dst; 324 325 pos = snapshot->start; 326 eof = snapshot->eof; 327 328 if (pos == eof) 329 return; 330 331 len = eof - pos; 332 333 /* 334 * Initialize records based on a crude estimate of the number 335 * of references in the file (we'll grow it below if needed): 336 */ 337 ALLOC_GROW(records, len / 80 + 20, alloc); 338 339 while (pos < eof) { 340 eol = memchr(pos, '\n', eof - pos); 341 if (!eol) 342 /* The safety check should prevent this. */ 343 BUG("unterminated line found in packed-refs"); 344 if (eol - pos < GIT_SHA1_HEXSZ + 2) 345 die_invalid_line(snapshot->refs->path, 346 pos, eof - pos); 347 eol++; 348 if (eol < eof && *eol == '^') { 349 /* 350 * Keep any peeled line together with its 351 * reference: 352 */ 353 const char *peeled_start = eol; 354 355 eol = memchr(peeled_start, '\n', eof - peeled_start); 356 if (!eol) 357 /* The safety check should prevent this. */ 358 BUG("unterminated peeled line found in packed-refs"); 359 eol++; 360 } 361 362 ALLOC_GROW(records, nr + 1, alloc); 363 records[nr].start = pos; 364 records[nr].len = eol - pos; 365 nr++; 366 367 if (sorted && 368 nr > 1 && 369 cmp_packed_ref_records(&records[nr - 2], 370 &records[nr - 1]) >= 0) 371 sorted = 0; 372 373 pos = eol; 374 } 375 376 if (sorted) 377 goto cleanup; 378 379 /* We need to sort the memory. First we sort the records array: */ 380 QSORT(records, nr, cmp_packed_ref_records); 381 382 /* 383 * Allocate a new chunk of memory, and copy the old memory to 384 * the new in the order indicated by `records` (not bothering 385 * with the header line): 386 */ 387 new_buffer = xmalloc(len); 388 for (dst = new_buffer, i = 0; i < nr; i++) { 389 memcpy(dst, records[i].start, records[i].len); 390 dst += records[i].len; 391 } 392 393 /* 394 * Now munmap the old buffer and use the sorted buffer in its 395 * place: 396 */ 397 clear_snapshot_buffer(snapshot); 398 snapshot->buf = snapshot->start = new_buffer; 399 snapshot->eof = new_buffer + len; 400 401cleanup: 402 free(records); 403} 404 405/* 406 * Return a pointer to the start of the record that contains the 407 * character `*p` (which must be within the buffer). If no other 408 * record start is found, return `buf`. 409 */ 410static const char *find_start_of_record(const char *buf, const char *p) 411{ 412 while (p > buf && (p[-1] != '\n' || p[0] == '^')) 413 p--; 414 return p; 415} 416 417/* 418 * Return a pointer to the start of the record following the record 419 * that contains `*p`. If none is found before `end`, return `end`. 420 */ 421static const char *find_end_of_record(const char *p, const char *end) 422{ 423 while (++p < end && (p[-1] != '\n' || p[0] == '^')) 424 ; 425 return p; 426} 427 428/* 429 * We want to be able to compare mmapped reference records quickly, 430 * without totally parsing them. We can do so because the records are 431 * LF-terminated, and the refname should start exactly (GIT_SHA1_HEXSZ 432 * + 1) bytes past the beginning of the record. 433 * 434 * But what if the `packed-refs` file contains garbage? We're willing 435 * to tolerate not detecting the problem, as long as we don't produce 436 * totally garbled output (we can't afford to check the integrity of 437 * the whole file during every Git invocation). But we do want to be 438 * sure that we never read past the end of the buffer in memory and 439 * perform an illegal memory access. 440 * 441 * Guarantee that minimum level of safety by verifying that the last 442 * record in the file is LF-terminated, and that it has at least 443 * (GIT_SHA1_HEXSZ + 1) characters before the LF. Die if either of 444 * these checks fails. 445 */ 446static void verify_buffer_safe(struct snapshot *snapshot) 447{ 448 const char *start = snapshot->start; 449 const char *eof = snapshot->eof; 450 const char *last_line; 451 452 if (start == eof) 453 return; 454 455 last_line = find_start_of_record(start, eof - 1); 456 if (*(eof - 1) != '\n' || eof - last_line < GIT_SHA1_HEXSZ + 2) 457 die_invalid_line(snapshot->refs->path, 458 last_line, eof - last_line); 459} 460 461#define SMALL_FILE_SIZE (32*1024) 462 463/* 464 * Depending on `mmap_strategy`, either mmap or read the contents of 465 * the `packed-refs` file into the snapshot. Return 1 if the file 466 * existed and was read, or 0 if the file was absent or empty. Die on 467 * errors. 468 */ 469static int load_contents(struct snapshot *snapshot) 470{ 471 int fd; 472 struct stat st; 473 size_t size; 474 ssize_t bytes_read; 475 476 fd = open(snapshot->refs->path, O_RDONLY); 477 if (fd < 0) { 478 if (errno == ENOENT) { 479 /* 480 * This is OK; it just means that no 481 * "packed-refs" file has been written yet, 482 * which is equivalent to it being empty, 483 * which is its state when initialized with 484 * zeros. 485 */ 486 return 0; 487 } else { 488 die_errno("couldn't read %s", snapshot->refs->path); 489 } 490 } 491 492 stat_validity_update(&snapshot->validity, fd); 493 494 if (fstat(fd, &st) < 0) 495 die_errno("couldn't stat %s", snapshot->refs->path); 496 size = xsize_t(st.st_size); 497 498 if (!size) { 499 return 0; 500 } else if (mmap_strategy == MMAP_NONE || size <= SMALL_FILE_SIZE) { 501 snapshot->buf = xmalloc(size); 502 bytes_read = read_in_full(fd, snapshot->buf, size); 503 if (bytes_read < 0 || bytes_read != size) 504 die_errno("couldn't read %s", snapshot->refs->path); 505 snapshot->mmapped = 0; 506 } else { 507 snapshot->buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 508 snapshot->mmapped = 1; 509 } 510 close(fd); 511 512 snapshot->start = snapshot->buf; 513 snapshot->eof = snapshot->buf + size; 514 515 return 1; 516} 517 518/* 519 * Find the place in `snapshot->buf` where the start of the record for 520 * `refname` starts. If `mustexist` is true and the reference doesn't 521 * exist, then return NULL. If `mustexist` is false and the reference 522 * doesn't exist, then return the point where that reference would be 523 * inserted, or `snapshot->eof` (which might be NULL) if it would be 524 * inserted at the end of the file. In the latter mode, `refname` 525 * doesn't have to be a proper reference name; for example, one could 526 * search for "refs/replace/" to find the start of any replace 527 * references. 528 * 529 * The record is sought using a binary search, so `snapshot->buf` must 530 * be sorted. 531 */ 532static const char *find_reference_location(struct snapshot *snapshot, 533 const char *refname, int mustexist) 534{ 535 /* 536 * This is not *quite* a garden-variety binary search, because 537 * the data we're searching is made up of records, and we 538 * always need to find the beginning of a record to do a 539 * comparison. A "record" here is one line for the reference 540 * itself and zero or one peel lines that start with '^'. Our 541 * loop invariant is described in the next two comments. 542 */ 543 544 /* 545 * A pointer to the character at the start of a record whose 546 * preceding records all have reference names that come 547 * *before* `refname`. 548 */ 549 const char *lo = snapshot->start; 550 551 /* 552 * A pointer to a the first character of a record whose 553 * reference name comes *after* `refname`. 554 */ 555 const char *hi = snapshot->eof; 556 557 while (lo != hi) { 558 const char *mid, *rec; 559 int cmp; 560 561 mid = lo + (hi - lo) / 2; 562 rec = find_start_of_record(lo, mid); 563 cmp = cmp_record_to_refname(rec, refname); 564 if (cmp < 0) { 565 lo = find_end_of_record(mid, hi); 566 } else if (cmp > 0) { 567 hi = rec; 568 } else { 569 return rec; 570 } 571 } 572 573 if (mustexist) 574 return NULL; 575 else 576 return lo; 577} 578 579/* 580 * Create a newly-allocated `snapshot` of the `packed-refs` file in 581 * its current state and return it. The return value will already have 582 * its reference count incremented. 583 * 584 * A comment line of the form "# pack-refs with: " may contain zero or 585 * more traits. We interpret the traits as follows: 586 * 587 * Neither `peeled` nor `fully-peeled`: 588 * 589 * Probably no references are peeled. But if the file contains a 590 * peeled value for a reference, we will use it. 591 * 592 * `peeled`: 593 * 594 * References under "refs/tags/", if they *can* be peeled, *are* 595 * peeled in this file. References outside of "refs/tags/" are 596 * probably not peeled even if they could have been, but if we find 597 * a peeled value for such a reference we will use it. 598 * 599 * `fully-peeled`: 600 * 601 * All references in the file that can be peeled are peeled. 602 * Inversely (and this is more important), any references in the 603 * file for which no peeled value is recorded is not peelable. This 604 * trait should typically be written alongside "peeled" for 605 * compatibility with older clients, but we do not require it 606 * (i.e., "peeled" is a no-op if "fully-peeled" is set). 607 * 608 * `sorted`: 609 * 610 * The references in this file are known to be sorted by refname. 611 */ 612static struct snapshot *create_snapshot(struct packed_ref_store *refs) 613{ 614 struct snapshot *snapshot = xcalloc(1, sizeof(*snapshot)); 615 int sorted = 0; 616 617 snapshot->refs = refs; 618 acquire_snapshot(snapshot); 619 snapshot->peeled = PEELED_NONE; 620 621 if (!load_contents(snapshot)) 622 return snapshot; 623 624 /* If the file has a header line, process it: */ 625 if (snapshot->buf < snapshot->eof && *snapshot->buf == '#') { 626 char *tmp, *p, *eol; 627 struct string_list traits = STRING_LIST_INIT_NODUP; 628 629 eol = memchr(snapshot->buf, '\n', 630 snapshot->eof - snapshot->buf); 631 if (!eol) 632 die_unterminated_line(refs->path, 633 snapshot->buf, 634 snapshot->eof - snapshot->buf); 635 636 tmp = xmemdupz(snapshot->buf, eol - snapshot->buf); 637 638 if (!skip_prefix(tmp, "# pack-refs with:", (const char **)&p)) 639 die_invalid_line(refs->path, 640 snapshot->buf, 641 snapshot->eof - snapshot->buf); 642 643 string_list_split_in_place(&traits, p, ' ', -1); 644 645 if (unsorted_string_list_has_string(&traits, "fully-peeled")) 646 snapshot->peeled = PEELED_FULLY; 647 else if (unsorted_string_list_has_string(&traits, "peeled")) 648 snapshot->peeled = PEELED_TAGS; 649 650 sorted = unsorted_string_list_has_string(&traits, "sorted"); 651 652 /* perhaps other traits later as well */ 653 654 /* The "+ 1" is for the LF character. */ 655 snapshot->start = eol + 1; 656 657 string_list_clear(&traits, 0); 658 free(tmp); 659 } 660 661 verify_buffer_safe(snapshot); 662 663 if (!sorted) { 664 sort_snapshot(snapshot); 665 666 /* 667 * Reordering the records might have moved a short one 668 * to the end of the buffer, so verify the buffer's 669 * safety again: 670 */ 671 verify_buffer_safe(snapshot); 672 } 673 674 if (mmap_strategy != MMAP_OK && snapshot->mmapped) { 675 /* 676 * We don't want to leave the file mmapped, so we are 677 * forced to make a copy now: 678 */ 679 size_t size = snapshot->eof - snapshot->start; 680 char *buf_copy = xmalloc(size); 681 682 memcpy(buf_copy, snapshot->start, size); 683 clear_snapshot_buffer(snapshot); 684 snapshot->buf = snapshot->start = buf_copy; 685 snapshot->eof = buf_copy + size; 686 } 687 688 return snapshot; 689} 690 691/* 692 * Check that `refs->snapshot` (if present) still reflects the 693 * contents of the `packed-refs` file. If not, clear the snapshot. 694 */ 695static void validate_snapshot(struct packed_ref_store *refs) 696{ 697 if (refs->snapshot && 698 !stat_validity_check(&refs->snapshot->validity, refs->path)) 699 clear_snapshot(refs); 700} 701 702/* 703 * Get the `snapshot` for the specified packed_ref_store, creating and 704 * populating it if it hasn't been read before or if the file has been 705 * changed (according to its `validity` field) since it was last read. 706 * On the other hand, if we hold the lock, then assume that the file 707 * hasn't been changed out from under us, so skip the extra `stat()` 708 * call in `stat_validity_check()`. This function does *not* increase 709 * the snapshot's reference count on behalf of the caller. 710 */ 711static struct snapshot *get_snapshot(struct packed_ref_store *refs) 712{ 713 if (!is_lock_file_locked(&refs->lock)) 714 validate_snapshot(refs); 715 716 if (!refs->snapshot) 717 refs->snapshot = create_snapshot(refs); 718 719 return refs->snapshot; 720} 721 722static int packed_read_raw_ref(struct ref_store *ref_store, 723 const char *refname, struct object_id *oid, 724 struct strbuf *referent, unsigned int *type) 725{ 726 struct packed_ref_store *refs = 727 packed_downcast(ref_store, REF_STORE_READ, "read_raw_ref"); 728 struct snapshot *snapshot = get_snapshot(refs); 729 const char *rec; 730 731 *type = 0; 732 733 rec = find_reference_location(snapshot, refname, 1); 734 735 if (!rec) { 736 /* refname is not a packed reference. */ 737 errno = ENOENT; 738 return -1; 739 } 740 741 if (get_oid_hex(rec, oid)) 742 die_invalid_line(refs->path, rec, snapshot->eof - rec); 743 744 *type = REF_ISPACKED; 745 return 0; 746} 747 748/* 749 * This value is set in `base.flags` if the peeled value of the 750 * current reference is known. In that case, `peeled` contains the 751 * correct peeled value for the reference, which might be `null_oid` 752 * if the reference is not a tag or if it is broken. 753 */ 754#define REF_KNOWS_PEELED 0x40 755 756/* 757 * An iterator over a snapshot of a `packed-refs` file. 758 */ 759struct packed_ref_iterator { 760 struct ref_iterator base; 761 762 struct snapshot *snapshot; 763 764 /* The current position in the snapshot's buffer: */ 765 const char *pos; 766 767 /* The end of the part of the buffer that will be iterated over: */ 768 const char *eof; 769 770 /* Scratch space for current values: */ 771 struct object_id oid, peeled; 772 struct strbuf refname_buf; 773 774 unsigned int flags; 775}; 776 777/* 778 * Move the iterator to the next record in the snapshot, without 779 * respect for whether the record is actually required by the current 780 * iteration. Adjust the fields in `iter` and return `ITER_OK` or 781 * `ITER_DONE`. This function does not free the iterator in the case 782 * of `ITER_DONE`. 783 */ 784static int next_record(struct packed_ref_iterator *iter) 785{ 786 const char *p = iter->pos, *eol; 787 788 strbuf_reset(&iter->refname_buf); 789 790 if (iter->pos == iter->eof) 791 return ITER_DONE; 792 793 iter->base.flags = REF_ISPACKED; 794 795 if (iter->eof - p < GIT_SHA1_HEXSZ + 2 || 796 parse_oid_hex(p, &iter->oid, &p) || 797 !isspace(*p++)) 798 die_invalid_line(iter->snapshot->refs->path, 799 iter->pos, iter->eof - iter->pos); 800 801 eol = memchr(p, '\n', iter->eof - p); 802 if (!eol) 803 die_unterminated_line(iter->snapshot->refs->path, 804 iter->pos, iter->eof - iter->pos); 805 806 strbuf_add(&iter->refname_buf, p, eol - p); 807 iter->base.refname = iter->refname_buf.buf; 808 809 if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) { 810 if (!refname_is_safe(iter->base.refname)) 811 die("packed refname is dangerous: %s", 812 iter->base.refname); 813 oidclr(&iter->oid); 814 iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN; 815 } 816 if (iter->snapshot->peeled == PEELED_FULLY || 817 (iter->snapshot->peeled == PEELED_TAGS && 818 starts_with(iter->base.refname, "refs/tags/"))) 819 iter->base.flags |= REF_KNOWS_PEELED; 820 821 iter->pos = eol + 1; 822 823 if (iter->pos < iter->eof && *iter->pos == '^') { 824 p = iter->pos + 1; 825 if (iter->eof - p < GIT_SHA1_HEXSZ + 1 || 826 parse_oid_hex(p, &iter->peeled, &p) || 827 *p++ != '\n') 828 die_invalid_line(iter->snapshot->refs->path, 829 iter->pos, iter->eof - iter->pos); 830 iter->pos = p; 831 832 /* 833 * Regardless of what the file header said, we 834 * definitely know the value of *this* reference. But 835 * we suppress it if the reference is broken: 836 */ 837 if ((iter->base.flags & REF_ISBROKEN)) { 838 oidclr(&iter->peeled); 839 iter->base.flags &= ~REF_KNOWS_PEELED; 840 } else { 841 iter->base.flags |= REF_KNOWS_PEELED; 842 } 843 } else { 844 oidclr(&iter->peeled); 845 } 846 847 return ITER_OK; 848} 849 850static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator) 851{ 852 struct packed_ref_iterator *iter = 853 (struct packed_ref_iterator *)ref_iterator; 854 int ok; 855 856 while ((ok = next_record(iter)) == ITER_OK) { 857 if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && 858 ref_type(iter->base.refname) != REF_TYPE_PER_WORKTREE) 859 continue; 860 861 if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && 862 !ref_resolves_to_object(iter->base.refname, &iter->oid, 863 iter->flags)) 864 continue; 865 866 return ITER_OK; 867 } 868 869 if (ref_iterator_abort(ref_iterator) != ITER_DONE) 870 ok = ITER_ERROR; 871 872 return ok; 873} 874 875static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator, 876 struct object_id *peeled) 877{ 878 struct packed_ref_iterator *iter = 879 (struct packed_ref_iterator *)ref_iterator; 880 881 if ((iter->base.flags & REF_KNOWS_PEELED)) { 882 oidcpy(peeled, &iter->peeled); 883 return is_null_oid(&iter->peeled) ? -1 : 0; 884 } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) { 885 return -1; 886 } else { 887 return !!peel_object(&iter->oid, peeled); 888 } 889} 890 891static int packed_ref_iterator_abort(struct ref_iterator *ref_iterator) 892{ 893 struct packed_ref_iterator *iter = 894 (struct packed_ref_iterator *)ref_iterator; 895 int ok = ITER_DONE; 896 897 strbuf_release(&iter->refname_buf); 898 release_snapshot(iter->snapshot); 899 base_ref_iterator_free(ref_iterator); 900 return ok; 901} 902 903static struct ref_iterator_vtable packed_ref_iterator_vtable = { 904 packed_ref_iterator_advance, 905 packed_ref_iterator_peel, 906 packed_ref_iterator_abort 907}; 908 909static struct ref_iterator *packed_ref_iterator_begin( 910 struct ref_store *ref_store, 911 const char *prefix, unsigned int flags) 912{ 913 struct packed_ref_store *refs; 914 struct snapshot *snapshot; 915 const char *start; 916 struct packed_ref_iterator *iter; 917 struct ref_iterator *ref_iterator; 918 unsigned int required_flags = REF_STORE_READ; 919 920 if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) 921 required_flags |= REF_STORE_ODB; 922 refs = packed_downcast(ref_store, required_flags, "ref_iterator_begin"); 923 924 /* 925 * Note that `get_snapshot()` internally checks whether the 926 * snapshot is up to date with what is on disk, and re-reads 927 * it if not. 928 */ 929 snapshot = get_snapshot(refs); 930 931 if (prefix && *prefix) 932 start = find_reference_location(snapshot, prefix, 0); 933 else 934 start = snapshot->start; 935 936 if (start == snapshot->eof) 937 return empty_ref_iterator_begin(); 938 939 iter = xcalloc(1, sizeof(*iter)); 940 ref_iterator = &iter->base; 941 base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1); 942 943 iter->snapshot = snapshot; 944 acquire_snapshot(snapshot); 945 946 iter->pos = start; 947 iter->eof = snapshot->eof; 948 strbuf_init(&iter->refname_buf, 0); 949 950 iter->base.oid = &iter->oid; 951 952 iter->flags = flags; 953 954 if (prefix && *prefix) 955 /* Stop iteration after we've gone *past* prefix: */ 956 ref_iterator = prefix_ref_iterator_begin(ref_iterator, prefix, 0); 957 958 return ref_iterator; 959} 960 961/* 962 * Write an entry to the packed-refs file for the specified refname. 963 * If peeled is non-NULL, write it as the entry's peeled value. On 964 * error, return a nonzero value and leave errno set at the value left 965 * by the failing call to `fprintf()`. 966 */ 967static int write_packed_entry(FILE *fh, const char *refname, 968 const struct object_id *oid, 969 const struct object_id *peeled) 970{ 971 if (fprintf(fh, "%s %s\n", oid_to_hex(oid), refname) < 0 || 972 (peeled && fprintf(fh, "^%s\n", oid_to_hex(peeled)) < 0)) 973 return -1; 974 975 return 0; 976} 977 978int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) 979{ 980 struct packed_ref_store *refs = 981 packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN, 982 "packed_refs_lock"); 983 static int timeout_configured = 0; 984 static int timeout_value = 1000; 985 986 if (!timeout_configured) { 987 git_config_get_int("core.packedrefstimeout", &timeout_value); 988 timeout_configured = 1; 989 } 990 991 /* 992 * Note that we close the lockfile immediately because we 993 * don't write new content to it, but rather to a separate 994 * tempfile. 995 */ 996 if (hold_lock_file_for_update_timeout( 997 &refs->lock, 998 refs->path, 999 flags, timeout_value) < 0) {1000 unable_to_lock_message(refs->path, errno, err);1001 return -1;1002 }10031004 if (close_lock_file_gently(&refs->lock)) {1005 strbuf_addf(err, "unable to close %s: %s", refs->path, strerror(errno));1006 rollback_lock_file(&refs->lock);1007 return -1;1008 }10091010 /*1011 * Now that we hold the `packed-refs` lock, make sure that our1012 * snapshot matches the current version of the file. Normally1013 * `get_snapshot()` does that for us, but that function1014 * assumes that when the file is locked, any existing snapshot1015 * is still valid. We've just locked the file, but it might1016 * have changed the moment *before* we locked it.1017 */1018 validate_snapshot(refs);10191020 /*1021 * Now make sure that the packed-refs file as it exists in the1022 * locked state is loaded into the snapshot:1023 */1024 get_snapshot(refs);1025 return 0;1026}10271028void packed_refs_unlock(struct ref_store *ref_store)1029{1030 struct packed_ref_store *refs = packed_downcast(1031 ref_store,1032 REF_STORE_READ | REF_STORE_WRITE,1033 "packed_refs_unlock");10341035 if (!is_lock_file_locked(&refs->lock))1036 die("BUG: packed_refs_unlock() called when not locked");1037 rollback_lock_file(&refs->lock);1038}10391040int packed_refs_is_locked(struct ref_store *ref_store)1041{1042 struct packed_ref_store *refs = packed_downcast(1043 ref_store,1044 REF_STORE_READ | REF_STORE_WRITE,1045 "packed_refs_is_locked");10461047 return is_lock_file_locked(&refs->lock);1048}10491050/*1051 * The packed-refs header line that we write out. Perhaps other traits1052 * will be added later.1053 *1054 * Note that earlier versions of Git used to parse these traits by1055 * looking for " trait " in the line. For this reason, the space after1056 * the colon and the trailing space are required.1057 */1058static const char PACKED_REFS_HEADER[] =1059 "# pack-refs with: peeled fully-peeled sorted \n";10601061static int packed_init_db(struct ref_store *ref_store, struct strbuf *err)1062{1063 /* Nothing to do. */1064 return 0;1065}10661067/*1068 * Write the packed refs from the current snapshot to the packed-refs1069 * tempfile, incorporating any changes from `updates`. `updates` must1070 * be a sorted string list whose keys are the refnames and whose util1071 * values are `struct ref_update *`. On error, rollback the tempfile,1072 * write an error message to `err`, and return a nonzero value.1073 *1074 * The packfile must be locked before calling this function and will1075 * remain locked when it is done.1076 */1077static int write_with_updates(struct packed_ref_store *refs,1078 struct string_list *updates,1079 struct strbuf *err)1080{1081 struct ref_iterator *iter = NULL;1082 size_t i;1083 int ok;1084 FILE *out;1085 struct strbuf sb = STRBUF_INIT;1086 char *packed_refs_path;10871088 if (!is_lock_file_locked(&refs->lock))1089 die("BUG: write_with_updates() called while unlocked");10901091 /*1092 * If packed-refs is a symlink, we want to overwrite the1093 * symlinked-to file, not the symlink itself. Also, put the1094 * staging file next to it:1095 */1096 packed_refs_path = get_locked_file_path(&refs->lock);1097 strbuf_addf(&sb, "%s.new", packed_refs_path);1098 free(packed_refs_path);1099 refs->tempfile = create_tempfile(sb.buf);1100 if (!refs->tempfile) {1101 strbuf_addf(err, "unable to create file %s: %s",1102 sb.buf, strerror(errno));1103 strbuf_release(&sb);1104 return -1;1105 }1106 strbuf_release(&sb);11071108 out = fdopen_tempfile(refs->tempfile, "w");1109 if (!out) {1110 strbuf_addf(err, "unable to fdopen packed-refs tempfile: %s",1111 strerror(errno));1112 goto error;1113 }11141115 if (fprintf(out, "%s", PACKED_REFS_HEADER) < 0)1116 goto write_error;11171118 /*1119 * We iterate in parallel through the current list of refs and1120 * the list of updates, processing an entry from at least one1121 * of the lists each time through the loop. When the current1122 * list of refs is exhausted, set iter to NULL. When the list1123 * of updates is exhausted, leave i set to updates->nr.1124 */1125 iter = packed_ref_iterator_begin(&refs->base, "",1126 DO_FOR_EACH_INCLUDE_BROKEN);1127 if ((ok = ref_iterator_advance(iter)) != ITER_OK)1128 iter = NULL;11291130 i = 0;11311132 while (iter || i < updates->nr) {1133 struct ref_update *update = NULL;1134 int cmp;11351136 if (i >= updates->nr) {1137 cmp = -1;1138 } else {1139 update = updates->items[i].util;11401141 if (!iter)1142 cmp = +1;1143 else1144 cmp = strcmp(iter->refname, update->refname);1145 }11461147 if (!cmp) {1148 /*1149 * There is both an old value and an update1150 * for this reference. Check the old value if1151 * necessary:1152 */1153 if ((update->flags & REF_HAVE_OLD)) {1154 if (is_null_oid(&update->old_oid)) {1155 strbuf_addf(err, "cannot update ref '%s': "1156 "reference already exists",1157 update->refname);1158 goto error;1159 } else if (oidcmp(&update->old_oid, iter->oid)) {1160 strbuf_addf(err, "cannot update ref '%s': "1161 "is at %s but expected %s",1162 update->refname,1163 oid_to_hex(iter->oid),1164 oid_to_hex(&update->old_oid));1165 goto error;1166 }1167 }11681169 /* Now figure out what to use for the new value: */1170 if ((update->flags & REF_HAVE_NEW)) {1171 /*1172 * The update takes precedence. Skip1173 * the iterator over the unneeded1174 * value.1175 */1176 if ((ok = ref_iterator_advance(iter)) != ITER_OK)1177 iter = NULL;1178 cmp = +1;1179 } else {1180 /*1181 * The update doesn't actually want to1182 * change anything. We're done with it.1183 */1184 i++;1185 cmp = -1;1186 }1187 } else if (cmp > 0) {1188 /*1189 * There is no old value but there is an1190 * update for this reference. Make sure that1191 * the update didn't expect an existing value:1192 */1193 if ((update->flags & REF_HAVE_OLD) &&1194 !is_null_oid(&update->old_oid)) {1195 strbuf_addf(err, "cannot update ref '%s': "1196 "reference is missing but expected %s",1197 update->refname,1198 oid_to_hex(&update->old_oid));1199 goto error;1200 }1201 }12021203 if (cmp < 0) {1204 /* Pass the old reference through. */12051206 struct object_id peeled;1207 int peel_error = ref_iterator_peel(iter, &peeled);12081209 if (write_packed_entry(out, iter->refname,1210 iter->oid,1211 peel_error ? NULL : &peeled))1212 goto write_error;12131214 if ((ok = ref_iterator_advance(iter)) != ITER_OK)1215 iter = NULL;1216 } else if (is_null_oid(&update->new_oid)) {1217 /*1218 * The update wants to delete the reference,1219 * and the reference either didn't exist or we1220 * have already skipped it. So we're done with1221 * the update (and don't have to write1222 * anything).1223 */1224 i++;1225 } else {1226 struct object_id peeled;1227 int peel_error = peel_object(&update->new_oid,1228 &peeled);12291230 if (write_packed_entry(out, update->refname,1231 &update->new_oid,1232 peel_error ? NULL : &peeled))1233 goto write_error;12341235 i++;1236 }1237 }12381239 if (ok != ITER_DONE) {1240 strbuf_addstr(err, "unable to write packed-refs file: "1241 "error iterating over old contents");1242 goto error;1243 }12441245 if (close_tempfile_gently(refs->tempfile)) {1246 strbuf_addf(err, "error closing file %s: %s",1247 get_tempfile_path(refs->tempfile),1248 strerror(errno));1249 strbuf_release(&sb);1250 delete_tempfile(&refs->tempfile);1251 return -1;1252 }12531254 return 0;12551256write_error:1257 strbuf_addf(err, "error writing to %s: %s",1258 get_tempfile_path(refs->tempfile), strerror(errno));12591260error:1261 if (iter)1262 ref_iterator_abort(iter);12631264 delete_tempfile(&refs->tempfile);1265 return -1;1266}12671268int is_packed_transaction_needed(struct ref_store *ref_store,1269 struct ref_transaction *transaction)1270{1271 struct packed_ref_store *refs = packed_downcast(1272 ref_store,1273 REF_STORE_READ,1274 "is_packed_transaction_needed");1275 struct strbuf referent = STRBUF_INIT;1276 size_t i;1277 int ret;12781279 if (!is_lock_file_locked(&refs->lock))1280 BUG("is_packed_transaction_needed() called while unlocked");12811282 /*1283 * We're only going to bother returning false for the common,1284 * trivial case that references are only being deleted, their1285 * old values are not being checked, and the old `packed-refs`1286 * file doesn't contain any of those reference(s). This gives1287 * false positives for some other cases that could1288 * theoretically be optimized away:1289 *1290 * 1. It could be that the old value is being verified without1291 * setting a new value. In this case, we could verify the1292 * old value here and skip the update if it agrees. If it1293 * disagrees, we could either let the update go through1294 * (the actual commit would re-detect and report the1295 * problem), or come up with a way of reporting such an1296 * error to *our* caller.1297 *1298 * 2. It could be that a new value is being set, but that it1299 * is identical to the current packed value of the1300 * reference.1301 *1302 * Neither of these cases will come up in the current code,1303 * because the only caller of this function passes to it a1304 * transaction that only includes `delete` updates with no1305 * `old_id`. Even if that ever changes, false positives only1306 * cause an optimization to be missed; they do not affect1307 * correctness.1308 */13091310 /*1311 * Start with the cheap checks that don't require old1312 * reference values to be read:1313 */1314 for (i = 0; i < transaction->nr; i++) {1315 struct ref_update *update = transaction->updates[i];13161317 if (update->flags & REF_HAVE_OLD)1318 /* Have to check the old value -> needed. */1319 return 1;13201321 if ((update->flags & REF_HAVE_NEW) && !is_null_oid(&update->new_oid))1322 /* Have to set a new value -> needed. */1323 return 1;1324 }13251326 /*1327 * The transaction isn't checking any old values nor is it1328 * setting any nonzero new values, so it still might be able1329 * to be skipped. Now do the more expensive check: the update1330 * is needed if any of the updates is a delete, and the old1331 * `packed-refs` file contains a value for that reference.1332 */1333 ret = 0;1334 for (i = 0; i < transaction->nr; i++) {1335 struct ref_update *update = transaction->updates[i];1336 unsigned int type;1337 struct object_id oid;13381339 if (!(update->flags & REF_HAVE_NEW))1340 /*1341 * This reference isn't being deleted -> not1342 * needed.1343 */1344 continue;13451346 if (!refs_read_raw_ref(ref_store, update->refname,1347 &oid, &referent, &type) ||1348 errno != ENOENT) {1349 /*1350 * We have to actually delete that reference1351 * -> this transaction is needed.1352 */1353 ret = 1;1354 break;1355 }1356 }13571358 strbuf_release(&referent);1359 return ret;1360}13611362struct packed_transaction_backend_data {1363 /* True iff the transaction owns the packed-refs lock. */1364 int own_lock;13651366 struct string_list updates;1367};13681369static void packed_transaction_cleanup(struct packed_ref_store *refs,1370 struct ref_transaction *transaction)1371{1372 struct packed_transaction_backend_data *data = transaction->backend_data;13731374 if (data) {1375 string_list_clear(&data->updates, 0);13761377 if (is_tempfile_active(refs->tempfile))1378 delete_tempfile(&refs->tempfile);13791380 if (data->own_lock && is_lock_file_locked(&refs->lock)) {1381 packed_refs_unlock(&refs->base);1382 data->own_lock = 0;1383 }13841385 free(data);1386 transaction->backend_data = NULL;1387 }13881389 transaction->state = REF_TRANSACTION_CLOSED;1390}13911392static int packed_transaction_prepare(struct ref_store *ref_store,1393 struct ref_transaction *transaction,1394 struct strbuf *err)1395{1396 struct packed_ref_store *refs = packed_downcast(1397 ref_store,1398 REF_STORE_READ | REF_STORE_WRITE | REF_STORE_ODB,1399 "ref_transaction_prepare");1400 struct packed_transaction_backend_data *data;1401 size_t i;1402 int ret = TRANSACTION_GENERIC_ERROR;14031404 /*1405 * Note that we *don't* skip transactions with zero updates,1406 * because such a transaction might be executed for the side1407 * effect of ensuring that all of the references are peeled or1408 * ensuring that the `packed-refs` file is sorted. If the1409 * caller wants to optimize away empty transactions, it should1410 * do so itself.1411 */14121413 data = xcalloc(1, sizeof(*data));1414 string_list_init(&data->updates, 0);14151416 transaction->backend_data = data;14171418 /*1419 * Stick the updates in a string list by refname so that we1420 * can sort them:1421 */1422 for (i = 0; i < transaction->nr; i++) {1423 struct ref_update *update = transaction->updates[i];1424 struct string_list_item *item =1425 string_list_append(&data->updates, update->refname);14261427 /* Store a pointer to update in item->util: */1428 item->util = update;1429 }1430 string_list_sort(&data->updates);14311432 if (ref_update_reject_duplicates(&data->updates, err))1433 goto failure;14341435 if (!is_lock_file_locked(&refs->lock)) {1436 if (packed_refs_lock(ref_store, 0, err))1437 goto failure;1438 data->own_lock = 1;1439 }14401441 if (write_with_updates(refs, &data->updates, err))1442 goto failure;14431444 transaction->state = REF_TRANSACTION_PREPARED;1445 return 0;14461447failure:1448 packed_transaction_cleanup(refs, transaction);1449 return ret;1450}14511452static int packed_transaction_abort(struct ref_store *ref_store,1453 struct ref_transaction *transaction,1454 struct strbuf *err)1455{1456 struct packed_ref_store *refs = packed_downcast(1457 ref_store,1458 REF_STORE_READ | REF_STORE_WRITE | REF_STORE_ODB,1459 "ref_transaction_abort");14601461 packed_transaction_cleanup(refs, transaction);1462 return 0;1463}14641465static int packed_transaction_finish(struct ref_store *ref_store,1466 struct ref_transaction *transaction,1467 struct strbuf *err)1468{1469 struct packed_ref_store *refs = packed_downcast(1470 ref_store,1471 REF_STORE_READ | REF_STORE_WRITE | REF_STORE_ODB,1472 "ref_transaction_finish");1473 int ret = TRANSACTION_GENERIC_ERROR;1474 char *packed_refs_path;14751476 clear_snapshot(refs);14771478 packed_refs_path = get_locked_file_path(&refs->lock);1479 if (rename_tempfile(&refs->tempfile, packed_refs_path)) {1480 strbuf_addf(err, "error replacing %s: %s",1481 refs->path, strerror(errno));1482 goto cleanup;1483 }14841485 ret = 0;14861487cleanup:1488 free(packed_refs_path);1489 packed_transaction_cleanup(refs, transaction);1490 return ret;1491}14921493static int packed_initial_transaction_commit(struct ref_store *ref_store,1494 struct ref_transaction *transaction,1495 struct strbuf *err)1496{1497 return ref_transaction_commit(transaction, err);1498}14991500static int packed_delete_refs(struct ref_store *ref_store, const char *msg,1501 struct string_list *refnames, unsigned int flags)1502{1503 struct packed_ref_store *refs =1504 packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs");1505 struct strbuf err = STRBUF_INIT;1506 struct ref_transaction *transaction;1507 struct string_list_item *item;1508 int ret;15091510 (void)refs; /* We need the check above, but don't use the variable */15111512 if (!refnames->nr)1513 return 0;15141515 /*1516 * Since we don't check the references' old_oids, the1517 * individual updates can't fail, so we can pack all of the1518 * updates into a single transaction.1519 */15201521 transaction = ref_store_transaction_begin(ref_store, &err);1522 if (!transaction)1523 return -1;15241525 for_each_string_list_item(item, refnames) {1526 if (ref_transaction_delete(transaction, item->string, NULL,1527 flags, msg, &err)) {1528 warning(_("could not delete reference %s: %s"),1529 item->string, err.buf);1530 strbuf_reset(&err);1531 }1532 }15331534 ret = ref_transaction_commit(transaction, &err);15351536 if (ret) {1537 if (refnames->nr == 1)1538 error(_("could not delete reference %s: %s"),1539 refnames->items[0].string, err.buf);1540 else1541 error(_("could not delete references: %s"), err.buf);1542 }15431544 ref_transaction_free(transaction);1545 strbuf_release(&err);1546 return ret;1547}15481549static int packed_pack_refs(struct ref_store *ref_store, unsigned int flags)1550{1551 /*1552 * Packed refs are already packed. It might be that loose refs1553 * are packed *into* a packed refs store, but that is done by1554 * updating the packed references via a transaction.1555 */1556 return 0;1557}15581559static int packed_create_symref(struct ref_store *ref_store,1560 const char *refname, const char *target,1561 const char *logmsg)1562{1563 die("BUG: packed reference store does not support symrefs");1564}15651566static int packed_rename_ref(struct ref_store *ref_store,1567 const char *oldrefname, const char *newrefname,1568 const char *logmsg)1569{1570 die("BUG: packed reference store does not support renaming references");1571}15721573static int packed_copy_ref(struct ref_store *ref_store,1574 const char *oldrefname, const char *newrefname,1575 const char *logmsg)1576{1577 die("BUG: packed reference store does not support copying references");1578}15791580static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store)1581{1582 return empty_ref_iterator_begin();1583}15841585static int packed_for_each_reflog_ent(struct ref_store *ref_store,1586 const char *refname,1587 each_reflog_ent_fn fn, void *cb_data)1588{1589 return 0;1590}15911592static int packed_for_each_reflog_ent_reverse(struct ref_store *ref_store,1593 const char *refname,1594 each_reflog_ent_fn fn,1595 void *cb_data)1596{1597 return 0;1598}15991600static int packed_reflog_exists(struct ref_store *ref_store,1601 const char *refname)1602{1603 return 0;1604}16051606static int packed_create_reflog(struct ref_store *ref_store,1607 const char *refname, int force_create,1608 struct strbuf *err)1609{1610 die("BUG: packed reference store does not support reflogs");1611}16121613static int packed_delete_reflog(struct ref_store *ref_store,1614 const char *refname)1615{1616 return 0;1617}16181619static int packed_reflog_expire(struct ref_store *ref_store,1620 const char *refname, const struct object_id *oid,1621 unsigned int flags,1622 reflog_expiry_prepare_fn prepare_fn,1623 reflog_expiry_should_prune_fn should_prune_fn,1624 reflog_expiry_cleanup_fn cleanup_fn,1625 void *policy_cb_data)1626{1627 return 0;1628}16291630struct ref_storage_be refs_be_packed = {1631 NULL,1632 "packed",1633 packed_ref_store_create,1634 packed_init_db,1635 packed_transaction_prepare,1636 packed_transaction_finish,1637 packed_transaction_abort,1638 packed_initial_transaction_commit,16391640 packed_pack_refs,1641 packed_create_symref,1642 packed_delete_refs,1643 packed_rename_ref,1644 packed_copy_ref,16451646 packed_ref_iterator_begin,1647 packed_read_raw_ref,16481649 packed_reflog_iterator_begin,1650 packed_for_each_reflog_ent,1651 packed_for_each_reflog_ent_reverse,1652 packed_reflog_exists,1653 packed_create_reflog,1654 packed_delete_reflog,1655 packed_reflog_expire1656};