Re: What's cooking in git.git (topics)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



"Shawn O. Pearce" <spearce@xxxxxxxxxxx> writes:

> There is almost no additional penalty for a simple strand of pearls
> with the tag placed along that strand; only one possible tag will be
> found.  But my code does an unnecessary revision list in this case.
>
> Where we really get hit is the large number of possible tags.  The
> master branch is turning up 14 tags, some dating back to v1.4.1-rc1.
> I do try to abort the revision list as soon as one of those tags
> cannot give me a better selection than the one I have currently,
> but I still had to generate a revision list to reach that point.

I looked at the algorithm, and after scratching my head for a
while, I finally found it sane (modulo leaks, which I think I
fixed with the attached patch).

One minor problem that you inherited from the original algorithm
is the name priority.  If you have an annotated tag A and a
lightweight tag b, and ask "git describe --tags" in this graph:

    ---o---o---o---o---x
           A   b

you would still want to describe 'x' with A, not b.
Unfortunately you don't (and the original doesn't either).

I think this is probably easy to solve in the loop that finds
"all_matches"; once you hit an annotated tag, your traversal
should stop in any case.  But if you were asked for --tags, and
if your "initialized" piece did find both lightweight and
annotated tags, you do not stop when you saw a lightweight one,
but keep looking for an annotated one, ignoring any further
lightweight ones.

Another thought.  I often do "git describe maint master next
pu", and I see an opportunity for optimizing for such a
multi-ref query.  Once you traversed the commits in
"all_matches" loop, you know which strands of pearls are
reachable to what tags, so you could hang that information
somewhere (perhaps ->utils) in each commit.  But I think
optimizing for a multi-ref query is probably not worth it.


-- >8 --
[PATCH] plug a few leaks in revision walking used in describe.

Signed-off-by: Junio C Hamano <junkio@xxxxxxx>
---
 builtin-describe.c |    1 +
 revision.c         |    8 +++++---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/builtin-describe.c b/builtin-describe.c
index d65c7d2..a8c98ce 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -183,6 +183,7 @@ static void describe(const char *arg, int last_one)
 			cur_match->depth++;
 		if (!min_match || cur_match->depth < min_match->depth)
 			min_match = cur_match;
+		free_commit_list(revs.commits);
 	}
 	printf("%s-g%s\n", min_match->name->path,
 		   find_unique_abbrev(cmit->object.sha1, abbrev));
diff --git a/revision.c b/revision.c
index 1e3b29a..f2ddd95 100644
--- a/revision.c
+++ b/revision.c
@@ -1121,21 +1121,23 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 void prepare_revision_walk(struct rev_info *revs)
 {
 	int nr = revs->pending.nr;
-	struct object_array_entry *list = revs->pending.objects;
+	struct object_array_entry *e, *list;
 
+	e = list = revs->pending.objects;
 	revs->pending.nr = 0;
 	revs->pending.alloc = 0;
 	revs->pending.objects = NULL;
 	while (--nr >= 0) {
-		struct commit *commit = handle_commit(revs, list->item, list->name);
+		struct commit *commit = handle_commit(revs, e->item, e->name);
 		if (commit) {
 			if (!(commit->object.flags & SEEN)) {
 				commit->object.flags |= SEEN;
 				insert_by_date(commit, &revs->commits);
 			}
 		}
-		list++;
+		e++;
 	}
+	free(list);
 
 	if (revs->no_walk)
 		return;

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]