| #!/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 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" |