git-2.22.0/refs/packed-backend.c
/*
 * Create a newly-allocated `snapshot` of the `packed-refs` file in
 * its current state and return it. The return value will already have
 * its reference count incremented.
 *
 * A comment line of the form "# pack-refs with: " may contain zero or
 * more traits. We interpret the traits as follows:
 *
 *   Neither `peeled` nor `fully-peeled`:
 *
 *      Probably no references are peeled. But if the file contains a
 *      peeled value for a reference, we will use it.
 *
 *   `peeled`:
 *
 *      References under "refs/tags/", if they *can* be peeled, *are*
 *      peeled in this file. References outside of "refs/tags/" are
 *      probably not peeled even if they could have been, but if we find
 *      a peeled value for such a reference we will use it.
 *
 *   `fully-peeled`:
 *
 *      All references in the file that can be peeled are peeled.
 *      Inversely (and this is more important), any references in the
 *      file for which no peeled value is recorded is not peelable. This
 *      trait should typically be written alongside "peeled" for
 *      compatibility with older clients, but we do not require it
 *      (i.e., "peeled" is a no-op if "fully-peeled" is set).
 *
 *   `sorted`:
 *
 *      The references in this file are known to be sorted by refname.
 */
Create a newly-allocated `snapshot` of the `packed-refs` file in
its current state and return it. The return value will already have
its reference count incremented.

A comment line of the form "# pack-refs with: " may contain zero or
more traits. We interpret the traits as follows.

Neither `peeled` nor `fully-peeled`.

Probably no references are peeled. But if the file contains a
peeled value for a reference, we will use it.

`peeled`.

References under "refs/tags/", if they *can* be peeled, *are
peeled in this file. References outside of "refs/tags/" are
probably not peeled even if they could have been, but if we find
a peeled value for such a reference we will use it.

`fully-peeled`.

All references in the file that can be peeled are peeled.
Inversely (and this is more important), any references in the
file for which no peeled value is recorded is not peelable. This
trait should typically be written alongside "peeled" for
compatibility with older clients, but we do not require it
.

`sorted`.

The references in this file are known to be sorted by refname.
Create a newly - allocated ` snapshot ` of the ` packed - refs ` file in its current state and return it . The return value will already have its reference count incremented . A comment line of the form " # pack - refs with : " may contain zero or more traits . We interpret the traits as follows . Neither ` peeled ` nor ` fully - peeled ` . Probably no references are peeled . But if the file contains a peeled value for a reference we will use it . ` peeled ` . References under " refs / tags / " if they * can * be peeled * are peeled in this file . References outside of " refs / tags / " are probably not peeled even if they could have been but if we find a peeled value for such a reference we will use it . ` fully - peeled ` . All references in the file that can be peeled are peeled . Inversely ( and this is more important ) any references in the file for which no peeled value is recorded is not peelable . This trait should typically be written alongside " peeled " for compatibility with older clients but we do not require it . ` sorted ` . The references in this file are known to be sorted by refname .
static struct snapshot *create_snapshot(struct packed_ref_store *refs)
{
	struct snapshot *snapshot = xcalloc(1, sizeof(*snapshot));
	int sorted = 0;
	snapshot->refs = refs;
	acquire_snapshot(snapshot);
	snapshot->peeled = PEELED_NONE;
	if (!load_contents(snapshot))
		return snapshot;
	if (snapshot->buf < snapshot->eof && *snapshot->buf == '#') {
		char *tmp, *p, *eol;
		struct string_list traits = STRING_LIST_INIT_NODUP;
		eol = memchr(snapshot->buf, '\n',
			     snapshot->eof - snapshot->buf);
		if (!eol)
			die_unterminated_line(refs->path,
					      snapshot->buf,
					      snapshot->eof - snapshot->buf);
		tmp = xmemdupz(snapshot->buf, eol - snapshot->buf);
		if (!skip_prefix(tmp, "# pack-refs with:", (const char **)&p))
			die_invalid_line(refs->path,
					 snapshot->buf,
					 snapshot->eof - snapshot->buf);
		string_list_split_in_place(&traits, p, ' ', -1);
		if (unsorted_string_list_has_string(&traits, "fully-peeled"))
			snapshot->peeled = PEELED_FULLY;
		else if (unsorted_string_list_has_string(&traits, "peeled"))
			snapshot->peeled = PEELED_TAGS;
		sorted = unsorted_string_list_has_string(&traits, "sorted");
		snapshot->start = eol + 1;
		string_list_clear(&traits, 0);
		free(tmp);
	}
	verify_buffer_safe(snapshot);
	if (!sorted) {
		sort_snapshot(snapshot);
		verify_buffer_safe(snapshot);
	}
	if (mmap_strategy != MMAP_OK && snapshot->mmapped) {
		size_t size = snapshot->eof - snapshot->start;
		char *buf_copy = xmalloc(size);
		memcpy(buf_copy, snapshot->start, size);
		clear_snapshot_buffer(snapshot);
		snapshot->buf = snapshot->start = buf_copy;
		snapshot->eof = buf_copy + size;
	}
	return snapshot;
}
static struct snapshot * create_snapshot ( struct packed_ref_store * refs ) { struct snapshot * snapshot = xcalloc ( 1 , sizeof ( * snapshot ) ) ; int sorted = 0 ; snapshot -> refs = refs ; acquire_snapshot ( snapshot ) ; snapshot -> peeled = PEELED_NONE ; if ( ! load_contents ( snapshot ) ) return snapshot ; if ( snapshot -> buf < snapshot -> eof && * snapshot -> buf == ' ' ) { char * tmp , * p , * eol ; struct string_list traits = STRING_LIST_INIT_NODUP ; eol = memchr ( snapshot -> buf , ' \n ' , snapshot -> eof - snapshot -> buf ) ; if ( ! eol ) die_unterminated_line ( refs -> path , snapshot -> buf , snapshot -> eof - snapshot -> buf ) ; tmp = xmemdupz ( snapshot -> buf , eol - snapshot -> buf ) ; if ( ! skip_prefix ( tmp , " " , ( const char * * ) & p ) ) die_invalid_line ( refs -> path , snapshot -> buf , snapshot -> eof - snapshot -> buf ) ; string_list_split_in_place ( & traits , p , ' ' , -1 ) ; if ( unsorted_string_list_has_string ( & traits , " " ) ) snapshot -> peeled = PEELED_FULLY ; else if ( unsorted_string_list_has_string ( & traits , " " ) ) snapshot -> peeled = PEELED_TAGS ; sorted = unsorted_string_list_has_string ( & traits , " " ) ; snapshot -> start = eol + 1 ; string_list_clear ( & traits , 0 ) ; free ( tmp ) ; } verify_buffer_safe ( snapshot ) ; if ( ! sorted ) { sort_snapshot ( snapshot ) ; verify_buffer_safe ( snapshot ) ; } if ( mmap_strategy != MMAP_OK && snapshot -> mmapped ) { size_t size = snapshot -> eof - snapshot -> start ; char * buf_copy = xmalloc ( size ) ; memcpy ( buf_copy , snapshot -> start , size ) ; clear_snapshot_buffer ( snapshot ) ; snapshot -> buf = snapshot -> start = buf_copy ; snapshot -> eof = buf_copy + size ; } return snapshot ; }
Create a newly-allocated `snapshot` of the `packed-refs` file in
 its current state and return it.
Create a newly - allocated ` snapshot ` of the ` packed - refs ` file in its current state and return it .
/* If the file has a header line, process it: */ /* perhaps other traits later as well */ /* The "+ 1" is for the LF character. */ /*
		 * Reordering the records might have moved a short one
		 * to the end of the buffer, so verify the buffer's
		 * safety again:
		 */ /*
		 * We don't want to leave the file mmapped, so we are
		 * forced to make a copy now:
		 */