Test commit
[cogito/jonas.git] / cg-tag
blobd4498fb068482876ce36688f320ef7e3d8aae95b
1 #!/usr/bin/env bash
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.
16 # OPTIONS
17 # -------
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
23 # exists.
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.
41 # OBJECT_ID::
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]"
48 _git_wc_unneeded=1
50 . "${COGITO_LIB}"cg-Xlib || exit 1
52 sign=
53 keyname=
54 msgs=()
55 msgfile=
56 editor=
57 force=
58 while optparse; do
59 if optparse -s; then
60 sign=1
61 elif optparse -k=; then
62 keyname="$OPTARG"
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
70 msgfile="$OPTARG"
71 elif optparse -e; then
72 editor=1
73 elif optparse -f; then
74 force=1
75 else
76 optfail
78 done
80 name="${ARGS[0]}"
81 id="${ARGS[1]}"
83 [ -n "$name" ] || usage
85 id="$(cg-object-id -n "$id")" || exit 1
86 type="$(git-cat-file -t "$id")"
87 id="${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)"
100 LOGMSG="$tagdir/log"
101 LOGMSG2="$tagdir/log2"
103 written=
105 for msg in "${msgs[@]}"; do
106 [ "$written" ] && echo >>"$LOGMSG"
107 echo "$msg" | fmt -s >>"$LOGMSG"
108 written=1
109 done
111 if [ "$msgfile" ]; then
112 [ "$written" ] && echo >>"$LOGMSG"
113 cat "$msgfile" >>"$LOGMSG" || exit 1
114 written=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
130 editor_msg_end
132 cp "$LOGMSG" "$LOGMSG2"
133 if editor_shalluse "$editor"; then
134 if [ "$editor" ] && ! editor $commitalways tag t; then
135 rm -rf "$tagdir"
136 echo "Tag message not modified, tagging aborted" >&2
137 exit 1
139 editor_parse_setif signyn "Sign the tag"
140 case "$signyn" in
141 y|Y|Yes|yes|1|true) sign=1;;
142 *) sign=;;
143 esac
144 editor_parse_setif keyname "GPG key name"
145 [ x"$keyname" = x"(default)" ] && keyname=
146 else
147 cat >>"$LOGMSG2"
150 editor_parse_clean
151 rm "$LOGMSG2"
154 cat <<SIGEND >"$tagdir/tag"
155 object $id
156 type $type
157 tag $name
158 tagger $(git-var GIT_COMMITTER_IDENT)
159 SIGEND
160 if [ -s "$LOGMSG" ]; then
161 echo >>"$tagdir/tag"
162 cat "$LOGMSG" >>"$tagdir/tag"
164 if [ "$sign" ]; then
165 echo >>"$tagdir/tag"
166 if ! gpg ${keyname:+--default-key "$keyname"} -bsa "$tagdir/tag"; then
167 rm -rf "$tagdir"
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
173 rm -rf "$tagdir"
174 die "error creating tag"
176 echo "Tagged $id as $name"
178 rm -rf "$tagdir"