Re: [PATCH 1/2] pack-refs: write peeled entry for non-tags
- From
Michael Haggerty <mhagger@alum.mit.edu>
- Date
- Mar 16, 2013, 13:50 UTC
- Message-ID
- <514478C0.6060008@alum.mit.edu>
- In-Reply-To
- <20130316090103.GA26855@sigill.intra.peff.net>
Looks good aside from a couple of minor points mentioned below.
On 03/16/2013 10:01 AM, Jeff King wrote:
Show 25 quoted lines
> When we pack an annotated tag ref, we write not only the > sha1 of the tag object along with the ref, but also the sha1 > obtained by peeling the tag. This lets readers of the > pack-refs file know the peeled value without having to > actually load the object, speeding up upload-pack's ref > advertisement. > > The writer marks a packed-refs file with peeled refs using > the "peeled" trait at the top of the file. When the reader > sees this trait, it knows that each ref is either followed > by its peeled value, or it is not an annotated tag. > > However, there is a mismatch between the assumptions of the > reader and writer. The writer will only peel refs under > refs/tags, but the reader does not know this; it will assume > a ref without a peeled value must not be a tag object. Thus > an annotated tag object placed outside of the refs/tags > hierarchy will not have its peeled value printed by > upload-pack. > > The simplest way to fix this is to start writing peel values > for all refs. This matches what the reader expects for both > new and old versions of git. > > Signed-off-by: Jeff King <peff@peff.net>
I like your explanation of the problem.
Show 33 quoted lines
> ---
> pack-refs.c | 16 ++++++++--------
> t/t3211-peel-ref.sh | 42 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 50 insertions(+), 8 deletions(-)
> create mode 100755 t/t3211-peel-ref.sh
>
> diff --git a/pack-refs.c b/pack-refs.c
> index f09a054..10832d7 100644
> --- a/pack-refs.c
> +++ b/pack-refs.c
> @@ -27,6 +27,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
> int flags, void *cb_data)
> {
> struct pack_refs_cb_data *cb = cb_data;
> + struct object *o;
> int is_tag_ref;
>
> /* Do not pack the symbolic refs */
> @@ -39,14 +40,13 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
> return 0;
>
> fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
> - if (is_tag_ref) {
> - struct object *o = parse_object(sha1);
> - if (o->type == OBJ_TAG) {
> - o = deref_tag(o, path, 0);
> - if (o)
> - fprintf(cb->refs_file, "^%s\n",
> - sha1_to_hex(o->sha1));
> - }
> +
> + o = parse_object(sha1);
> + if (o->type == OBJ_TAG) {You suggested that I add a test (o != NULL) at the equivalent place in my code (which was derived from this code). Granted, my code was explicitly intending to pass invalid SHA1 values to parse_object(). But wouldn't it be a good defensive step to add the same check here?
Show 32 quoted lines
> + o = deref_tag(o, path, 0);
> + if (o)
> + fprintf(cb->refs_file, "^%s\n",
> + sha1_to_hex(o->sha1));
> }
>
> if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) {
> diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh
> new file mode 100755
> index 0000000..dd5b48b
> --- /dev/null
> +++ b/t/t3211-peel-ref.sh
> @@ -0,0 +1,42 @@
> +#!/bin/sh
> +
> +test_description='tests for the peel_ref optimization of packed-refs'
> +. ./test-lib.sh
> +
> +test_expect_success 'create annotated tag in refs/tags' '
> + test_commit base &&
> + git tag -m annotated foo
> +'
> +
> +test_expect_success 'create annotated tag outside of refs/tags' '
> + git update-ref refs/outside/foo refs/tags/foo
> +'
> +
> +# This matches show-ref's output
> +print_ref() {
> + echo "`git rev-parse "$1"` $1"
> +}
> +CodingGuidelines prefers $() over ``.
Show 24 quoted lines
> +test_expect_success 'set up expected show-ref output' '
> + {
> + print_ref "refs/heads/master" &&
> + print_ref "refs/outside/foo" &&
> + print_ref "refs/outside/foo^{}" &&
> + print_ref "refs/tags/base" &&
> + print_ref "refs/tags/foo" &&
> + print_ref "refs/tags/foo^{}"
> + } >expect
> +'
> +
> +test_expect_success 'refs are peeled outside of refs/tags (loose)' '
> + git show-ref -d >actual &&
> + test_cmp expect actual
> +'
> +
> +test_expect_success 'refs are peeled outside of refs/tags (packed)' '
> + git pack-refs --all &&
> + git show-ref -d >actual &&
> + test_cmp expect actual
> +'
> +
> +test_done
> -- Michael Haggerty mhagger@alum.mit.edu http://softwareswirl.blogspot.com/