Download raw body.
got {diff,log,update} -c KEYWORD (cf. svn revision keywords)
got {diff,log,update} -c KEYWORD (cf. svn revision keywords)
got {diff,log,update} -c KEYWORD (cf. svn revision keywords)
On 2023/07/14 23:44:08 +1000, Mark Jamsek <mark@jamsek.com> wrote: > I've made a few changes that I think make it a lot nicer, and have > added some non-trivial and somewhat contrived tests too. > > I nixed the hand-rolled overflow code so we use strtonum(3), and made > the keyword parsing strict. That lax keyword comparison was by design > initially but I forgot to remove it; I was using -cBASED in testing :) > > Something I just noticed that I like about the ':' delimiters is ^W > removes back to the ':', which is handy. And the +/-N works great with > tog's count modifier. You can open tog, see which commit it is you > want with Nj, and use the same N count (or the headline index-1) in the > 'got * -c:head:-N' command! This is going to save a lot of copypasting > and misremembering commit ids. It's pretty neat :) sorry for the delay. I've been using this today quite a few times. Honestly I woludn't have imaged that things like got di -cmain -c main:-3 were *so* useful in practice :D Thanks! ok for me; minor nits below: > --- got/got.c > +++ got/got.c > @@ -32,6 +32,7 @@ > #include <sha2.h> > #include <signal.h> > #include <stdio.h> > +#include <stddef.h> stddef.h is not needed anymore. > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > --- /dev/null > +++ lib/keyword.c > @@ -0,0 +1,263 @@ > +/* > + * Copyright (c) 2023 Mark Jamsek <mark@jamsek.dev> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/queue.h> > + > +#include <ctype.h> > +#include <limits.h> > +#include <stddef.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <sha1.h> it's not needed right now but I'd add an #include <sha2.h> too. Some of our headers require it being included, and as soon as the sha256 work is resumed got_object.h will require it too. > +#include "got_reference.h" > +#include "got_error.h" > +#include "got_object.h" > +#include "got_repository.h" > +#include "got_cancel.h" > +#include "got_worktree.h" > +#include "got_commit_graph.h" > +#include "got_keyword.h" > +const struct got_error * > +got_keyword_to_idstr(char **ret, const char *keyword, > + struct got_repository *repo, struct got_worktree *wt) > +{ > [...] > + while (n <= kwm.n) { > + err = got_commit_graph_iter_next(&iter_id, graph, repo, > + NULL, NULL); > + if (err) { > + if (err->code == GOT_ERR_ITER_COMPLETED) > + err = NULL; Here (in a follow-up maybe) I'd set error to something non-NULL. I think it'd be better to return an error if we couldn't go as far back as required. (imagine the case with `main' being a reference to a commit without parent and the user doing got log -c main:-1) > + break; > + } > + > + if (kwm.sym == GOT_KEYWORD_DESCENDANT) { > + /* > + * We want the Nth generation descendant of KEYWORD, > + * so queue all commits from HEAD to KEYWORD then we > + * can walk from KEYWORD to its Nth gen descendent. > + */ > + err = got_object_qid_alloc(&qid, &iter_id); > + if (err) > + goto done; > + STAILQ_INSERT_HEAD(&commits, qid, entry); > + > + if (got_object_id_cmp(&iter_id, kwid) == 0) > + break; > + continue; > + } > + ++n; > + } > + > + if (kwm.sym == GOT_KEYWORD_DESCENDANT) { > + n = 0; > + > + STAILQ_FOREACH(qid, &commits, entry) { > + if (qid == STAILQ_LAST(&commits, got_object_qid, entry) > + || n == kwm.n) > + break; > + ++n; > + } > + > + memcpy(&iter_id, &qid->id, sizeof(iter_id)); > + nit: extra empty line > + }
got {diff,log,update} -c KEYWORD (cf. svn revision keywords)
got {diff,log,update} -c KEYWORD (cf. svn revision keywords)
got {diff,log,update} -c KEYWORD (cf. svn revision keywords)