Reuse previous annotation when overwriting a tag
[gitweb.git] / builtin-tag.c
index fcbf9bbf18155b5e9b699bf12cd980561498992f..566d123a8db1a3da70d261acd8cf3fdcbc2e469f 100644 (file)
@@ -51,7 +51,7 @@ static void launch_editor(const char *path, struct strbuf *buffer)
        if (run_command(&child))
                die("There was a problem with the editor %s.", editor);
 
-       if (strbuf_read_file(buffer, path) < 0)
+       if (strbuf_read_file(buffer, path, 0) < 0)
                die("could not read message file '%s': %s",
                    path, strerror(errno));
 }
@@ -247,9 +247,37 @@ static int git_tag_config(const char *var, const char *value)
        return git_default_config(var, value);
 }
 
+static void write_tag_body(int fd, const unsigned char *sha1)
+{
+       unsigned long size;
+       enum object_type type;
+       char *buf, *sp, *eob;
+       size_t len;
+
+       buf = read_sha1_file(sha1, &type, &size);
+       if (!buf)
+               return;
+       /* skip header */
+       sp = strstr(buf, "\n\n");
+
+       if (!sp || !size || type != OBJ_TAG) {
+               free(buf);
+               return;
+       }
+       sp += 2; /* skip the 2 LFs */
+       eob = strstr(sp, "\n" PGP_SIGNATURE "\n");
+       if (eob)
+               len = eob - sp;
+       else
+               len = buf + size - sp;
+       write_or_die(fd, sp, len);
+
+       free(buf);
+}
+
 static void create_tag(const unsigned char *object, const char *tag,
                       struct strbuf *buf, int message, int sign,
-                          unsigned char *result)
+                          unsigned char *prev, unsigned char *result)
 {
        enum object_type type;
        char header_buf[1024];
@@ -282,7 +310,11 @@ static void create_tag(const unsigned char *object, const char *tag,
                if (fd < 0)
                        die("could not create file '%s': %s",
                                                path, strerror(errno));
-               write_or_die(fd, tag_template, strlen(tag_template));
+
+               if (!is_null_sha1(prev))
+                       write_tag_body(fd, prev);
+               else
+                       write_or_die(fd, tag_template, strlen(tag_template));
                close(fd);
 
                launch_editor(path, buf);
@@ -291,14 +323,11 @@ static void create_tag(const unsigned char *object, const char *tag,
                free(path);
        }
 
-       strbuf_setlen(buf, stripspace(buf->buf, buf->len, 1));
+       stripspace(buf, 1);
 
        if (!message && !buf->len)
                die("no tag message?");
 
-       /* insert the header and add the '\n' if needed: */
-       if (buf->len)
-               strbuf_addch(buf, '\n');
        strbuf_insert(buf, 0, header_buf, header_len);
 
        if (sign && do_sign(buf) < 0)
@@ -359,8 +388,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                        continue;
                }
                if (!strcmp(arg, "-F")) {
-                       int fd;
-
                        annotate = 1;
                        i++;
                        if (i == argc)
@@ -368,17 +395,14 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                        if (message)
                                die("only one -F or -m option is allowed.");
 
-                       if (!strcmp(argv[i], "-"))
-                               fd = 0;
-                       else {
-                               fd = open(argv[i], O_RDONLY);
-                               if (fd < 0)
-                                       die("could not open '%s': %s",
+                       if (!strcmp(argv[i], "-")) {
+                               if (strbuf_read(&buf, 0, 1024) < 0)
+                                       die("cannot read %s", argv[i]);
+                       } else {
+                               if (strbuf_read_file(&buf, argv[i], 1024) < 0)
+                                       die("could not open or read '%s': %s",
                                                argv[i], strerror(errno));
                        }
-                       if (strbuf_read(&buf, fd, 1024) < 0) {
-                               die("cannot read %s", argv[i]);
-                       }
                        message = 1;
                        continue;
                }
@@ -427,7 +451,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                die("tag '%s' already exists", tag);
 
        if (annotate)
-               create_tag(object, tag, &buf, message, sign, object);
+               create_tag(object, tag, &buf, message, sign, prev, object);
 
        lock = lock_any_ref_for_update(ref, prev, 0);
        if (!lock)