git-commit-vandalism/contrib/examples/git-tag.sh
David Kastrup 822f7c7349 Supplant the "while case ... break ;; esac" idiom
A lot of shell scripts contained stuff starting with

	while case "$#" in 0) break ;; esac

and similar.  I consider breaking out of the condition instead of the
body od the loop ugly, and the implied "true" value of the
non-matching case is not really obvious to humans at first glance.  It
happens not to be obvious to some BSD shells, either, but that's
because they are not POSIX-compliant.  In most cases, this has been
replaced by a straight condition using "test".  "case" has the
advantage of being faster than "test" on vintage shells where "test"
is not a builtin.  Since none of them is likely to run the git
scripts, anyway, the added readability should be worth the change.

A few loops have had their termination condition expressed
differently.

Signed-off-by: David Kastrup <dak@gnu.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-09-23 16:12:00 -07:00

206 lines
3.9 KiB
Bash
Executable File

#!/bin/sh
# Copyright (c) 2005 Linus Torvalds
USAGE='[-n [<num>]] -l [<pattern>] | [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg>] <tagname> [<head>]'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
message_given=
annotate=
signed=
force=
message=
username=
list=
verify=
LINES=0
while test $# != 0
do
case "$1" in
-a)
annotate=1
shift
;;
-s)
annotate=1
signed=1
shift
;;
-f)
force=1
shift
;;
-n)
case "$#,$2" in
1,* | *,-*)
LINES=1 # no argument
;;
*) shift
LINES=$(expr "$1" : '\([0-9]*\)')
[ -z "$LINES" ] && LINES=1 # 1 line is default when -n is used
;;
esac
shift
;;
-l)
list=1
shift
case $# in
0) PATTERN=
;;
*)
PATTERN="$1" # select tags by shell pattern, not re
shift
;;
esac
git rev-parse --symbolic --tags | sort |
while read TAG
do
case "$TAG" in
*$PATTERN*) ;;
*) continue ;;
esac
[ "$LINES" -le 0 ] && { echo "$TAG"; continue ;}
OBJTYPE=$(git cat-file -t "$TAG")
case $OBJTYPE in
tag)
ANNOTATION=$(git cat-file tag "$TAG" |
sed -e '1,/^$/d' |
sed -n -e "
/^-----BEGIN PGP SIGNATURE-----\$/q
2,\$s/^/ /
p
${LINES}q
")
printf "%-15s %s\n" "$TAG" "$ANNOTATION"
;;
*) echo "$TAG"
;;
esac
done
;;
-m)
annotate=1
shift
message="$1"
if test "$#" = "0"; then
die "error: option -m needs an argument"
else
message="$1"
message_given=1
shift
fi
;;
-F)
annotate=1
shift
if test "$#" = "0"; then
die "error: option -F needs an argument"
else
message="$(cat "$1")"
message_given=1
shift
fi
;;
-u)
annotate=1
signed=1
shift
if test "$#" = "0"; then
die "error: option -u needs an argument"
else
username="$1"
shift
fi
;;
-d)
shift
had_error=0
for tag
do
cur=$(git show-ref --verify --hash -- "refs/tags/$tag") || {
echo >&2 "Seriously, what tag are you talking about?"
had_error=1
continue
}
git update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || {
had_error=1
continue
}
echo "Deleted tag $tag."
done
exit $had_error
;;
-v)
shift
tag_name="$1"
tag=$(git show-ref --verify --hash -- "refs/tags/$tag_name") ||
die "Seriously, what tag are you talking about?"
git-verify-tag -v "$tag"
exit $?
;;
-*)
usage
;;
*)
break
;;
esac
done
[ -n "$list" ] && exit 0
name="$1"
[ "$name" ] || usage
prev=0000000000000000000000000000000000000000
if git show-ref --verify --quiet -- "refs/tags/$name"
then
test -n "$force" || die "tag '$name' already exists"
prev=`git rev-parse "refs/tags/$name"`
fi
shift
git check-ref-format "tags/$name" ||
die "we do not like '$name' as a tag name."
object=$(git rev-parse --verify --default HEAD "$@") || exit 1
type=$(git cat-file -t $object) || exit 1
tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1
test -n "$username" ||
username=$(git repo-config user.signingkey) ||
username=$(expr "z$tagger" : 'z\(.*>\)')
trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0
if [ "$annotate" ]; then
if [ -z "$message_given" ]; then
( echo "#"
echo "# Write a tag message"
echo "#" ) > "$GIT_DIR"/TAG_EDITMSG
git_editor "$GIT_DIR"/TAG_EDITMSG || exit
else
printf '%s\n' "$message" >"$GIT_DIR"/TAG_EDITMSG
fi
grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG |
git stripspace >"$GIT_DIR"/TAG_FINALMSG
[ -s "$GIT_DIR"/TAG_FINALMSG -o -n "$message_given" ] || {
echo >&2 "No tag message?"
exit 1
}
( printf 'object %s\ntype %s\ntag %s\ntagger %s\n\n' \
"$object" "$type" "$name" "$tagger";
cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP
rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG
if [ "$signed" ]; then
gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP &&
cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP ||
die "failed to sign the tag with GPG."
fi
object=$(git-mktag < "$GIT_DIR"/TAG_TMP)
fi
git update-ref "refs/tags/$name" "$object" "$prev"