Staging
v0.8.1
Revision be15f50538afa4bfb912a86fa9d9f141010ad691 authored by Linus Torvalds on 11 December 2007, 04:08:06 UTC, committed by Junio C Hamano on 11 December 2007, 08:38:46 UTC
Commit 396865859918e9c7bf8ce74aae137c57da134610 broke signed tags using
the "-u" flag when it made builtin-tag.c use parse_options() to parse its
arguments (but it quite possibly was broken even before that, by the
builtin rewrite).

It used to be that passing the signing ID with the -u parameter also
(obviously!) implied that you wanted to sign and annotate the tag, but
that logic got dropped. It also totally ignored the actual key ID that was
passed in.

This reinstates it all.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ace9c2a
Raw File
object-refs.c
#include "cache.h"
#include "object.h"
#include "decorate.h"

int track_object_refs = 0;

static struct decoration ref_decorate;

struct object_refs *lookup_object_refs(struct object *base)
{
	return lookup_decoration(&ref_decorate, base);
}

static void add_object_refs(struct object *obj, struct object_refs *refs)
{
	if (add_decoration(&ref_decorate, obj, refs))
		die("object %s tried to add refs twice!", sha1_to_hex(obj->sha1));
}

struct object_refs *alloc_object_refs(unsigned count)
{
	struct object_refs *refs;
	size_t size = sizeof(*refs) + count*sizeof(struct object *);

	refs = xcalloc(1, size);
	refs->count = count;
	return refs;
}

static int compare_object_pointers(const void *a, const void *b)
{
	const struct object * const *pa = a;
	const struct object * const *pb = b;
	if (*pa == *pb)
		return 0;
	else if (*pa < *pb)
		return -1;
	else
		return 1;
}

void set_object_refs(struct object *obj, struct object_refs *refs)
{
	unsigned int i, j;

	/* Do not install empty list of references */
	if (refs->count < 1) {
		free(refs);
		return;
	}

	/* Sort the list and filter out duplicates */
	qsort(refs->ref, refs->count, sizeof(refs->ref[0]),
	      compare_object_pointers);
	for (i = j = 1; i < refs->count; i++) {
		if (refs->ref[i] != refs->ref[i - 1])
			refs->ref[j++] = refs->ref[i];
	}
	if (j < refs->count) {
		/* Duplicates were found - reallocate list */
		size_t size = sizeof(*refs) + j*sizeof(struct object *);
		refs->count = j;
		refs = xrealloc(refs, size);
	}

	for (i = 0; i < refs->count; i++)
		refs->ref[i]->used = 1;
	add_object_refs(obj, refs);
}

void mark_reachable(struct object *obj, unsigned int mask)
{
	const struct object_refs *refs;

	if (!track_object_refs)
		die("cannot do reachability with object refs turned off");
	/* If we've been here already, don't bother */
	if (obj->flags & mask)
		return;
	obj->flags |= mask;
	refs = lookup_object_refs(obj);
	if (refs) {
		unsigned i;
		for (i = 0; i < refs->count; i++)
			mark_reachable(refs->ref[i], mask);
	}
}
back to top