Anonymous committed 3927bbe

tag: delete TAG_EDITMSG only on successful tag

The user may put some effort into writing an annotated tag
message. When the tagging process later fails (which can
happen fairly easily, since it may be dependent on gpg being
correctly configured and used), there is no record left on
disk of the tag message.

Instead, let's keep the TAG_EDITMSG file around until we are
sure the tag has been created successfully. If we die
because of an error, the user can recover their text from
that file. Leaving the file in place causes no conflicts;
it will be silently overwritten by the next annotated tag

This matches the behavior of COMMIT_EDITMSG, which stays
around in case of error.

Signed-off-by: Jeff King <>
Signed-off-by: Junio C Hamano <>

  • Participants
  • Parent commits bcc6a83

Comments (0)

Files changed (1)

File builtin-tag.c

+static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)
+	if (sign && do_sign(buf) < 0)
+		return error("unable to sign the tag");
+	if (write_sha1_file(buf->buf, buf->len, tag_type, result) < 0)
+		return error("unable to write tag file");
+	return 0;
 static void create_tag(const unsigned char *object, const char *tag,
 		       struct strbuf *buf, int message, int sign,
 		       unsigned char *prev, unsigned char *result)
 	enum object_type type;
 	char header_buf[1024];
 	int header_len;
+	char *path = NULL;
 	type = sha1_object_info(object, NULL);
 	if (type <= OBJ_NONE)
 		die("tag header too big.");
 	if (!message) {
-		char *path;
 		int fd;
 		/* write the template message before editing: */
 			"Please supply the message using either -m or -F option.\n");
-		unlink(path);
-		free(path);
 	stripspace(buf, 1);
 	strbuf_insert(buf, 0, header_buf, header_len);
-	if (sign && do_sign(buf) < 0)
-		die("unable to sign the tag");
-	if (write_sha1_file(buf->buf, buf->len, tag_type, result) < 0)
-		die("unable to write tag file");
+	if (build_tag_object(buf, sign, result) < 0) {
+		if (path)
+			fprintf(stderr, "The tag message has been left in %s\n",
+				path);
+		exit(128);
+	}
+	if (path) {
+		unlink(path);
+		free(path);
+	}
 struct msg_arg {