Re: [PATCH] revision: add --except option
- From
Felipe Contreras <felipe.contreras@gmail.com>
- Date
- Aug 31, 2013, 19:27 UTC
- Message-ID
- <CAMP44s0D98tggTjQsMn+-03KgSsbrh3nxYfLofpC1gfnJpEPyw@mail.gmail.com>
- In-Reply-To
- <5220503F.2080608@viscovery.net>
On Fri, Aug 30, 2013 at 2:56 AM, Johannes Sixt <j.sixt@viscovery.net> wrote:
Show 16 quoted lines
> Am 8/30/2013 8:32, schrieb Junio C Hamano: >> If you have a history where >> >> - branches "master" and "maint" point at commit A; >> - branch "next" points at commit B that is a descendant of A; and >> - there are tags X and Y pointing at commits that are ahead of B >> or behind A >> >> i.e. >> >> ----X----A----B----Y >> >> what are the desired semantics for these? > > I think the simplest were that --except trumps everything and means > "whatever else I say, do as if I did not mention the following".
Actually, my patch is almost there, I attach the necessary changed below to make everything work. I've added debug prints to show what it's actually doing:
>> (1) --branches --except maint > > => master next
=> master next
>> (2) --all --not --branches --except maint > > => X Y --not master next
=> ^master ^next X Y HEAD
>> (3) ^master next --except maint > > => ^master next
=> ^master next
> (4) Y next --except master next --not --branches > > this => Y --not maint > or this => Y --not maint master next
=> Y
Remember that maint (or rather ^maint) is after --except.
Show 5 quoted lines
> (5) --branches --except ^master
>
> this => maint next
> or this => maint master next ^master
> or error("--except does not allow negated revisions")=> maint next
Here's the diff:
--- a/revision.c +++ b/revision.c @@ -2578,7 +2578,11 @@ void reset_revision_walk(void) static int refcmp(const char *a, const char *b) { a = prettify_refname(a); + if (*a == '^') + a++; b = prettify_refname(b); + if (*b == '^') + b++; return strcmp(a, b); } @@ -2594,13 +2598,14 @@ int prepare_revision_walk(struct rev_info *revs) revs->pending.alloc = 0; revs->pending.objects = NULL; while (--nr >= 0) { - struct commit *commit = handle_commit(revs, e->item, e->name); + struct commit *commit; for (i = 0; i < revs->cmdline.nr; i++) { struct rev_cmdline_entry *ce; ce = &revs->cmdline.rev[i]; if ((ce->flags & SKIP) && !refcmp(ce->name, e->name)) goto next; } + commit = handle_commit(revs, e->item, e->name); if (commit) { if (!(commit->object.flags & SEEN)) { commit->object.flags |= SEEN;
-- Felipe Contreras