3 # Mark certain commit with a tag
4 # Copyright (c) Petr Baudis, 2005
6 # Creates a tag referencing the given commit (or 'HEAD'). You can then
7 # use the tag anywhere you specify a commit or tree ID.
9 # cg-tag will try to sign the tag if you give it the -s option.
10 # You can override the default key choice by passing it the -k argument.
12 # Takes the tag name and optionally the associated ID as arguments.
13 # When the standard input is not a terminal, it will accept the tag
14 # description on stdin.
18 # -e:: Run tag description message editor
19 # Open editor for the tag description message.
21 # -f:: Overwrite existing tag if exists
22 # This will make cg-tag silently overwrite the tag if it already
25 # -m MESSAGE:: Specify tag description message
26 # Message associated with the tag, describing it. Multiple -m
27 # parameters will cause several description paragraphs to appear.
29 # -M FILE:: Read tag description message from a file
30 # Include tag description message from a file (this has the same
31 # effect as if you would cat it to stdin).
33 # -k KEYNAME:: Use the given KEYNAME to sign the tag
34 # Use the given key to sign the tag, instead of the default one.
35 # You can use any key identifier GPG recognizes - the argument
36 # is passed verbatim as the '--default-key' argument to GPG.
38 # -s:: Sign the tag by your private key using GPG.
39 # Sign the tag by your private key using GPG.
42 # This is most usually the ID of the commit to tag. Tagging
43 # other objects than commits is possible, but rather "unusual".
45 # Testsuite: Marginal (part of t9206-merge-multi-base)
47 USAGE
="cg-tag [-m MESSAGE]... [-e] [-s] [OTHER_OPTIONS] TAG_NAME [OBJECT_ID]"
50 .
"${COGITO_LIB}"cg-Xlib ||
exit 1
61 elif optparse
-k=; then
63 elif optparse
-m=; then
64 msgs
[${#msgs[@]}]="$OPTARG"
65 elif optparse
-d=; then
66 # 20060407 cogito-0.17.1-g382c125
67 warn
-b "cg-tag -d is obsolete, please use cg-tag -m instead"
68 msgs
[${#msgs[@]}]="$OPTARG"
69 elif optparse
-M=; then
71 elif optparse
-e; then
73 elif optparse
-f; then
83 [ -n "$name" ] || usage
85 id
="$(cg-object-id -n "$id")" ||
exit 1
86 type="$(git-cat-file -t "$id")"
89 git-check-ref-format
"refs/tags/$name" || \
90 die
"name contains invalid characters"
92 [ "$force" ] ||
! exists_ref
"refs/tags/$name" || \
93 die
"tag already exists ($name)"
95 [ "$id" ] || id
="$(get_ref "$
(git-symbolic-ref HEAD
)")"
98 tagdir
="$(mktemp -d -t gittag.XXXXXX)"
101 LOGMSG2
="$tagdir/log2"
105 for msg
in "${msgs[@]}"; do
106 [ "$written" ] && echo >>"$LOGMSG"
107 echo "$msg" |
fmt -s >>"$LOGMSG"
111 if [ "$msgfile" ]; then
112 [ "$written" ] && echo >>"$LOGMSG"
113 cat "$msgfile" >>"$LOGMSG" ||
exit 1
117 # Always have at least one blank line, to ease the editing for
118 # the poor people whose text editor has no 'O' command.
119 [ "$written" ] ||
{ editor_shalluse
"$editor" && echo >>"$LOGMSG"; }
121 editor_comment_start tag
122 echo "CG: You can edit the following fields to adjust cg-tag's behaviour." >>"$LOGMSG"
123 echo "CG:" >>"$LOGMSG"
124 signyn
=No
; [ "$sign" ] && signyn
=Yes
125 echo "CG: Sign the tag: $signyn" >>"$LOGMSG"
126 [ -n "$keyname" ] || keyname
="(default)"
127 echo "CG: GPG key name: $keyname" >>"$LOGMSG"
128 echo "CG:" >>"$LOGMSG"
129 editor_comment_end tag
132 cp "$LOGMSG" "$LOGMSG2"
133 if editor_shalluse
"$editor"; then
134 if [ "$editor" ] && ! editor
$commitalways tag t
; then
136 echo "Tag message not modified, tagging aborted" >&2
139 editor_parse_setif signyn
"Sign the tag"
141 y|Y|Yes|
yes|
1|true
) sign
=1;;
144 editor_parse_setif keyname
"GPG key name"
145 [ x
"$keyname" = x
"(default)" ] && keyname
=
154 cat <<SIGEND >"$tagdir/tag"
158 tagger $(git-var GIT_COMMITTER_IDENT)
160 if [ -s "$LOGMSG" ]; then
162 cat "$LOGMSG" >>"$tagdir/tag"
166 if ! gpg
${keyname:+--default-key "$keyname"} -bsa "$tagdir/tag"; then
168 die
"error signing the tag"
170 cat "$tagdir/tag.asc" >>"$tagdir/tag"
172 if ! git-update-ref
"refs/tags/$name" "$(git-mktag <"$tagdir/tag
")"; then
174 die
"error creating tag"
176 echo "Tagged $id as $name"