From: Michael Haggerty <mhagger@alum.mit.edu>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH v2 4/4] pack-refs: add fully-peeled trait
Date: Mon, 18 Mar 2013 04:12:21 +0100 [thread overview]
Message-ID: <51468615.70503@alum.mit.edu> (raw)
In-Reply-To: <20130317082829.GD29550@sigill.intra.peff.net>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
and ACK for the whole series, once Junio's points are addressed.
Regarding Junio's readability suggestion: I agree that his versions are
a bit more readable, albeit at the expense of having to evaluate a bit
more logic for each reference rather than just once when the header line
is handled. So I don't have a preference either way.
Michael
On 03/17/2013 09:28 AM, Jeff King wrote:
> From: Michael Haggerty <mhagger@alum.mit.edu>
>
> Older versions of pack-refs did not write peel lines for
> refs outside of refs/tags. This meant that on reading the
> pack-refs file, we might set the REF_KNOWS_PEELED flag for
> such a ref, even though we do not know anything about its
> peeled value.
>
> The previous commit updated the writer to always peel, no
> matter what the ref is. That means that packed-refs files
> written by newer versions of git are fine to be read by both
> old and new versions of git. However, we still have the
> problem of reading packed-refs files written by older
> versions of git, or by other implementations which have not
> yet learned the same trick.
>
> The simplest fix would be to always unset the
> REF_KNOWS_PEELED flag for refs outside of refs/tags that do
> not have a peel line (if it has a peel line, we know it is
> valid, but we cannot assume a missing peel line means
> anything). But that loses an important optimization, as
> upload-pack should not need to load the object pointed to by
> refs/heads/foo to determine that it is not a tag.
>
> Instead, we add a "fully-peeled" trait to the packed-refs
> file. If it is set, we know that we can trust a missing peel
> line to mean that a ref cannot be peeled. Otherwise, we fall
> back to assuming nothing.
>
> [commit message and tests by Jeff King <peff@peff.net>]
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> This uses Michael's approach for managing the flags within
> read_packed_refs, which is more readable. As I picked up his
> code and comments, I realized that there was basically
> nothing of mine left, so I switched the authorship. But do
> note:
>
> 1. It should have Michael's signoff, which was not present
> in the commit I lifted the code from.
>
> 2. I tweaked the big comment above read_packed_refs to
> reduce some ambiguities. Please double-check that I am
> not putting inaccurate words in your mouth. :)
>
> pack-refs.c | 2 +-
> refs.c | 43 +++++++++++++++++++++++++++++++++++++++++--
> t/t3211-peel-ref.sh | 22 ++++++++++++++++++++++
> 3 files changed, 64 insertions(+), 3 deletions(-)
>
> diff --git a/pack-refs.c b/pack-refs.c
> index ebde785..4461f71 100644
> --- a/pack-refs.c
> +++ b/pack-refs.c
> @@ -128,7 +128,7 @@ int pack_refs(unsigned int flags)
> die_errno("unable to create ref-pack file structure");
>
> /* perhaps other traits later as well */
> - fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
> + fprintf(cbdata.refs_file, "# pack-refs with: peeled fully-peeled \n");
>
> for_each_ref(handle_one_ref, &cbdata);
> if (ferror(cbdata.refs_file))
> diff --git a/refs.c b/refs.c
> index 175b9fc..bdeac28 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -803,11 +803,39 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
> return line;
> }
>
> +/*
> + * Read f, which is a packed-refs file, into dir.
> + *
> + * A comment line of the form "# pack-refs with: " may contain zero or
> + * more traits. We interpret the traits as follows:
> + *
> + * No traits:
> + *
> + * 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 "fully-peeled" for
> + * compatibility with older clients, but we do not require it
> + * (i.e., "peeled" is a no-op if "fully-peeled" is set).
> + */
> static void read_packed_refs(FILE *f, struct ref_dir *dir)
> {
> struct ref_entry *last = NULL;
> char refline[PATH_MAX];
> int flag = REF_ISPACKED;
> + int refs_tags_peeled = 0;
>
> while (fgets(refline, sizeof(refline), f)) {
> unsigned char sha1[20];
> @@ -816,8 +844,10 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
>
> if (!strncmp(refline, header, sizeof(header)-1)) {
> const char *traits = refline + sizeof(header) - 1;
> - if (strstr(traits, " peeled "))
> + if (strstr(traits, " fully-peeled "))
> flag |= REF_KNOWS_PEELED;
> + else if (strstr(traits, " peeled "))
> + refs_tags_peeled = 1;
> /* perhaps other traits later as well */
> continue;
> }
> @@ -825,6 +855,8 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
> refname = parse_ref_line(refline, sha1);
> if (refname) {
> last = create_ref_entry(refname, sha1, flag, 1);
> + if (refs_tags_peeled && !prefixcmp(refname, "refs/tags/"))
> + last->flag |= REF_KNOWS_PEELED;
> add_ref(dir, last);
> continue;
> }
> @@ -832,8 +864,15 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
> refline[0] == '^' &&
> strlen(refline) == 42 &&
> refline[41] == '\n' &&
> - !get_sha1_hex(refline + 1, sha1))
> + !get_sha1_hex(refline + 1, sha1)) {
> hashcpy(last->u.value.peeled, sha1);
> + /*
> + * Regardless of what the file header said,
> + * we definitely know the value of *this*
> + * reference:
> + */
> + last->flag |= REF_KNOWS_PEELED;
> + }
> }
> }
>
> diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh
> index 85f09be..d4d7792 100755
> --- a/t/t3211-peel-ref.sh
> +++ b/t/t3211-peel-ref.sh
> @@ -39,4 +39,26 @@ test_expect_success 'refs are peeled outside of refs/tags (packed)' '
> test_cmp expect actual
> '
>
> +test_expect_success 'create old-style pack-refs without fully-peeled' '
> + # Git no longer writes without fully-peeled, so we just write our own
> + # from scratch; we could also munge the existing file to remove the
> + # fully-peeled bits, but that seems even more prone to failure,
> + # especially if the format ever changes again. At least this way we
> + # know we are emulating exactly what an older git would have written.
> + {
> + echo "# pack-refs with: peeled " &&
> + print_ref "refs/heads/master" &&
> + print_ref "refs/outside/foo" &&
> + print_ref "refs/tags/base" &&
> + print_ref "refs/tags/foo" &&
> + echo "^$(git rev-parse "refs/tags/foo^{}")"
> + } >tmp &&
> + mv tmp .git/packed-refs
> +'
> +
> +test_expect_success 'refs are peeled outside of refs/tags (old packed)' '
> + git show-ref -d >actual &&
> + test_cmp expect actual
> +'
> +
> test_done
>
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
next prev parent reply other threads:[~2013-03-18 3:12 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-16 9:00 [PATCH 0/2] peel-ref optimization fixes Jeff King
2013-03-16 9:01 ` [PATCH 1/2] pack-refs: write peeled entry for non-tags Jeff King
2013-03-16 13:50 ` Michael Haggerty
2013-03-17 6:02 ` Jeff King
2013-03-16 9:01 ` [PATCH 2/2] pack-refs: add fully-peeled trait Jeff King
2013-03-16 14:06 ` Michael Haggerty
2013-03-17 6:04 ` Jeff King
2013-03-17 5:50 ` Junio C Hamano
2013-03-17 5:55 ` Jeff King
2013-03-17 8:21 ` [PATCH v2 0/4] peel-ref optimization fixes Jeff King
2013-03-17 8:22 ` [PATCH v2 1/4] avoid segfaults on parse_object failure Jeff King
2013-03-17 8:23 ` [PATCH v2 2/4] use parse_object_or_die instead of die("bad object") Jeff King
2013-03-17 8:23 ` [PATCH v2 3/4] pack-refs: write peeled entry for non-tags Jeff King
2013-03-17 8:28 ` [PATCH v2 4/4] pack-refs: add fully-peeled trait Jeff King
2013-03-17 20:01 ` Junio C Hamano
2013-03-18 11:37 ` [PATCH v3 " Jeff King
2013-03-18 16:26 ` Junio C Hamano
2013-03-18 3:12 ` Michael Haggerty [this message]
2013-03-18 15:12 ` [PATCH v2 " Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51468615.70503@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.