From: Josh Rickmar Subject: Re: show just one tag with got tag -l To: gameoftrees@openbsd.org Date: Wed, 29 Jun 2022 06:32:02 -0400 On Wed, Jun 29, 2022 at 12:26:08PM +0200, Stefan Sperling wrote: > Make it possible to show just one tag with 'got tag -l'. > > This can be useful in situations where the desired tag name > is already known, so users do not have to wade through the > entire list of all tag messages. > > Suggested by jrick on IRC. > > ok? ok > > diff f9d376997dd2e84bf84c3c9a4da842d1b5565e9d 10f634d85314c0a8cb06cd3dbd60c3a17dd43371 > commit - f9d376997dd2e84bf84c3c9a4da842d1b5565e9d > commit + 10f634d85314c0a8cb06cd3dbd60c3a17dd43371 > blob - 6e54669dd487e962e60aabbc77043a09b250bd99 > blob + d2db3f11b55b0dcd7008e9f4662210887aa2742b > --- got/got.1 > +++ got/got.1 > @@ -1232,7 +1232,10 @@ If this directory is a > work tree, use the repository path associated with this work tree. > .It Fl l > List all existing tags in the repository instead of creating a new tag. > -If this option is used, no other command-line arguments are allowed. > +If a > +.Ar name > +argument is passed, show only the tag with the given > +.Ar name . > .El > .Pp > By design, the > blob - 6332563c1a68c343f8f860c77299ff6dbe5f18f3 > blob + 2dceeed3a7a54bee61a491f92527df8295059f95 > --- got/got.c > +++ got/got.c > @@ -6869,11 +6869,30 @@ done: > #endif > > static const struct got_error * > -list_tags(struct got_repository *repo) > +get_tag_refname(char **refname, const char *tag_name) > { > + const struct got_error *err; > + > + if (strncmp("refs/tags/", tag_name, 10) == 0) { > + *refname = strdup(tag_name); > + if (*refname == NULL) > + return got_error_from_errno("strdup"); > + } else if (asprintf(refname, "refs/tags/%s", tag_name) == -1) { > + err = got_error_from_errno("asprintf"); > + *refname = NULL; > + return err; > + } > + > + return NULL; > +} > + > +static const struct got_error * > +list_tags(struct got_repository *repo, const char *tag_name) > +{ > static const struct got_error *err = NULL; > struct got_reflist_head refs; > struct got_reflist_entry *re; > + char *wanted_refname = NULL; > > TAILQ_INIT(&refs); > > @@ -6881,6 +6900,18 @@ list_tags(struct got_repository *repo) > if (err) > return err; > > + if (tag_name) { > + struct got_reference *ref; > + err = get_tag_refname(&wanted_refname, tag_name); > + if (err) > + goto done; > + /* Wanted tag reference should exist. */ > + err = got_ref_open(&ref, repo, wanted_refname, 0); > + if (err) > + goto done; > + got_ref_close(ref); > + } > + > TAILQ_FOREACH(re, &refs, entry) { > const char *refname; > char *refstr, *tagmsg0, *tagmsg, *line, *id_str, *datestr; > @@ -6892,7 +6923,8 @@ list_tags(struct got_repository *repo) > struct got_commit_object *commit = NULL; > > refname = got_ref_get_name(re->ref); > - if (strncmp(refname, "refs/tags/", 10) != 0) > + if (strncmp(refname, "refs/tags/", 10) != 0 || > + (wanted_refname && strcmp(refname, wanted_refname) != 0)) > continue; > refname += 10; > refstr = got_ref_to_str(re->ref); > @@ -6985,9 +7017,10 @@ list_tags(struct got_repository *repo) > } while (line); > free(tagmsg0); > } > - > +done: > got_ref_list_free(&refs); > - return NULL; > + free(wanted_refname); > + return err; > } > > static const struct got_error * > @@ -7081,17 +7114,11 @@ add_tag(struct got_repository *repo, const char *tagge > if (err) > goto done; > > - if (strncmp("refs/tags/", tag_name, 10) == 0) { > - refname = strdup(tag_name); > - if (refname == NULL) { > - err = got_error_from_errno("strdup"); > - goto done; > - } > + err = get_tag_refname(&refname, tag_name); > + if (err) > + goto done; > + if (strncmp("refs/tags/", tag_name, 10) == 0) > tag_name += 10; > - } else if (asprintf(&refname, "refs/tags/%s", tag_name) == -1) { > - err = got_error_from_errno("asprintf"); > - goto done; > - } > > err = got_ref_open(&ref, repo, refname, 0); > if (err == NULL) { > @@ -7166,7 +7193,7 @@ cmd_tag(int argc, char *argv[]) > struct got_worktree *worktree = NULL; > char *cwd = NULL, *repo_path = NULL, *commit_id_str = NULL; > char *gitconfig_path = NULL, *tagger = NULL; > - const char *tag_name, *commit_id_arg = NULL, *tagmsg = NULL; > + const char *tag_name = NULL, *commit_id_arg = NULL, *tagmsg = NULL; > int ch, do_list = 0; > int *pack_fds = NULL; > > @@ -7203,12 +7230,13 @@ cmd_tag(int argc, char *argv[]) > "-c option can only be used when creating a tag"); > if (tagmsg) > option_conflict('l', 'm'); > - if (argc > 0) > + if (argc > 1) > usage_tag(); > } else if (argc != 1) > usage_tag(); > > - tag_name = argv[0]; > + if (argc == 1) > + tag_name = argv[0]; > > #ifndef PROFILE > if (pledge("stdio rpath wpath cpath fattr flock proc exec " > @@ -7266,7 +7294,7 @@ cmd_tag(int argc, char *argv[]) > error = apply_unveil(got_repo_get_path(repo), 1, NULL); > if (error) > goto done; > - error = list_tags(repo); > + error = list_tags(repo, tag_name); > } else { > error = get_gitconfig_path(&gitconfig_path); > if (error) > blob - ab908a49f4d848281c7d725df6742a474700a0e1 > blob + 53325e40ea937187e8814d7b18dd3a6a2f5c40f5 > --- regress/cmdline/tag.sh > +++ regress/cmdline/tag.sh > @@ -168,7 +168,45 @@ test_tag_list() { > ret=$? > if [ $ret -ne 0 ]; then > diff -u $testroot/stdout.expected $testroot/stdout > + test_done "$testroot" "$ret" > + return 1 > fi > + > + got tag -r $testroot/repo -l $tag > $testroot/stdout > + > + echo "-----------------------------------------------" \ > + > $testroot/stdout.expected > + echo "tag $tag $tag_id" >> $testroot/stdout.expected > + echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected > + echo "date: $d1" >> $testroot/stdout.expected > + echo "object: commit $commit_id" >> $testroot/stdout.expected > + echo " " >> $testroot/stdout.expected > + echo " test" >> $testroot/stdout.expected > + echo " " >> $testroot/stdout.expected > + cmp -s $testroot/stdout $testroot/stdout.expected > + ret=$? > + if [ $ret -ne 0 ]; then > + diff -u $testroot/stdout.expected $testroot/stdout > + test_done "$testroot" "$ret" > + return 1 > + fi > + > + got tag -r $testroot/repo -l $tag2 > $testroot/stdout > + > + echo "-----------------------------------------------" \ > + > $testroot/stdout.expected > + echo "tag $tag2 $tag_id2" >> $testroot/stdout.expected > + echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected > + echo "date: $d2" >> $testroot/stdout.expected > + echo "object: commit $commit_id" >> $testroot/stdout.expected > + echo " " >> $testroot/stdout.expected > + echo " test" >> $testroot/stdout.expected > + echo " " >> $testroot/stdout.expected > + cmp -s $testroot/stdout $testroot/stdout.expected > + ret=$? > + if [ $ret -ne 0 ]; then > + diff -u $testroot/stdout.expected $testroot/stdout > + fi > test_done "$testroot" "$ret" > } > >