commit 68e8cedbff75686437a3d71b0c265fb66cbbbd75 from: Stefan Sperling via: Thomas Adam date: Fri Jul 01 21:13:24 2022 UTC make it possible to show just one tag with 'got tag -l' suggested by jrick ok jrick jamsek commit - 19a6a6b5eea7ed2df9eaaba2364d18ee05678ddd commit + 68e8cedbff75686437a3d71b0c265fb66cbbbd75 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 - 78f96eab35bb4c23dfc7fc1b0736b108ecfcc036 blob + 7b44ace527a04030b552586446d99d5a123db1e9 --- got/got.c +++ got/got.c @@ -6868,17 +6868,48 @@ 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); err = got_ref_list(&refs, repo, "refs/tags", got_ref_cmp_tags, 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; @@ -6891,7 +6922,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); @@ -6984,9 +7016,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 * @@ -7080,17 +7113,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; - } - tag_name += 10; - } else if (asprintf(&refname, "refs/tags/%s", tag_name) == -1) { - err = got_error_from_errno("asprintf"); + err = get_tag_refname(&refname, tag_name); + if (err) goto done; - } + if (strncmp("refs/tags/", tag_name, 10) == 0) + tag_name += 10; err = got_ref_open(&ref, repo, refname, 0); if (err == NULL) { @@ -7165,7 +7192,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; @@ -7202,12 +7229,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 " @@ -7265,7 +7293,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 - ccaa267e7e49fc1b70b2fe8aa99a88a10cd5e96c blob + 85eeb97a2ce3a3d1ae9c6e6be4aabef220a38b41 --- regress/cmdline/tag.sh +++ regress/cmdline/tag.sh @@ -166,6 +166,25 @@ test_tag_list() { echo " " >> $testroot/stdout.expected 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 $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 @@ -177,7 +196,26 @@ 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 $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" }