"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Josh Rickmar <openbsd+lists@zettaport.com>
Subject:
Re: show just one tag with got tag -l
To:
gameoftrees@openbsd.org
Date:
Wed, 29 Jun 2022 06:32:02 -0400

Download raw body.

Thread
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"
>  }
>  
>