git-mv: follow -k request even on failing renames
[git] / git-tag.sh
1 #!/bin/sh
2 # Copyright (c) 2005 Linus Torvalds
3
4 . git-sh-setup
5
6 usage () {
7     echo >&2 "Usage: git-tag [-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <tagname> [<head>]"
8     exit 1
9 }
10
11 annotate=
12 signed=
13 force=
14 message=
15 username=
16 while case "$#" in 0) break ;; esac
17 do
18     case "$1" in
19     -a)
20         annotate=1
21         ;;
22     -s)
23         annotate=1
24         signed=1
25         ;;
26     -f)
27         force=1
28         ;;
29     -m)
30         annotate=1
31         shift
32         message="$1"
33         ;;
34     -u)
35         annotate=1
36         signed=1
37         shift
38         username="$1"
39         ;;
40     -d)
41         shift
42         tag_name="$1"
43         rm "$GIT_DIR/refs/tags/$tag_name" && \
44                 echo "Deleted tag $tag_name."
45         exit $?
46         ;;
47     -*)
48         usage
49         ;;
50     *)
51         break
52         ;;
53     esac
54     shift
55 done
56
57 name="$1"
58 [ "$name" ] || usage
59 if [ -e "$GIT_DIR/refs/tags/$name" -a -z "$force" ]; then
60     die "tag '$name' already exists"
61 fi
62 shift
63 git-check-ref-format "tags/$name" ||
64         die "we do not like '$name' as a tag name."
65
66 object=$(git-rev-parse --verify --default HEAD "$@") || exit 1
67 type=$(git-cat-file -t $object) || exit 1
68 tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1
69 : ${username:=$(expr "$tagger" : '\(.*>\)')}
70
71 trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0
72
73 if [ "$annotate" ]; then
74     if [ -z "$message" ]; then
75         ( echo "#"
76           echo "# Write a tag message"
77           echo "#" ) > "$GIT_DIR"/TAG_EDITMSG
78         ${VISUAL:-${EDITOR:-vi}} "$GIT_DIR"/TAG_EDITMSG || exit
79     else
80         echo "$message" >"$GIT_DIR"/TAG_EDITMSG
81     fi
82
83     grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG |
84     git-stripspace >"$GIT_DIR"/TAG_FINALMSG
85
86     [ -s "$GIT_DIR"/TAG_FINALMSG ] || {
87         echo >&2 "No tag message?"
88         exit 1
89     }
90
91     ( echo -e "object $object\ntype $type\ntag $name\ntagger $tagger\n";
92       cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP
93     rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG
94     if [ "$signed" ]; then
95         gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP &&
96         cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP ||
97         die "failed to sign the tag with GPG."
98     fi
99     object=$(git-mktag < "$GIT_DIR"/TAG_TMP)
100 fi
101
102 leading=`expr "refs/tags/$name" : '\(.*\)/'` &&
103 mkdir -p "$GIT_DIR/$leading" &&
104 echo $object > "$GIT_DIR/refs/tags/$name"