Avoid using non-portable `echo -n` in tests.
[gitweb.git] / log-tree.c
index 1474d1f5d96c9b04b0d5c190f88b2fdefd2ef679..cec3c061360e9d33068fdb6c2555b69cc11f6771 100644 (file)
@@ -1,12 +1,48 @@
 #include "cache.h"
 #include "diff.h"
 #include "commit.h"
+#include "tag.h"
 #include "graph.h"
 #include "log-tree.h"
 #include "reflog-walk.h"
+#include "refs.h"
 
 struct decoration name_decoration = { "object names" };
 
+static void add_name_decoration(const char *prefix, const char *name, struct object *obj)
+{
+       int plen = strlen(prefix);
+       int nlen = strlen(name);
+       struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen);
+       memcpy(res->name, prefix, plen);
+       memcpy(res->name + plen, name, nlen + 1);
+       res->next = add_decoration(&name_decoration, obj, res);
+}
+
+static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+       struct object *obj = parse_object(sha1);
+       if (!obj)
+               return 0;
+       add_name_decoration("", refname, obj);
+       while (obj->type == OBJ_TAG) {
+               obj = ((struct tag *)obj)->tagged;
+               if (!obj)
+                       break;
+               add_name_decoration("tag: ", refname, obj);
+       }
+       return 0;
+}
+
+void load_ref_decorations(void)
+{
+       static int loaded;
+       if (!loaded) {
+               loaded = 1;
+               for_each_ref(add_ref_decoration, NULL);
+       }
+}
+
 static void show_parents(struct commit *commit, int abbrev)
 {
        struct commit_list *p;
@@ -198,7 +234,7 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
                extra_headers = subject_buffer;
 
                snprintf(buffer, sizeof(buffer) - 1,
-                        "--%s%s\n"
+                        "\n--%s%s\n"
                         "Content-Type: text/x-patch;"
                         " name=\"%s.diff\"\n"
                         "Content-Transfer-Encoding: 8bit\n"
@@ -216,7 +252,7 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
 
 void show_log(struct rev_info *opt)
 {
-       struct strbuf msgbuf;
+       struct strbuf msgbuf = STRBUF_INIT;
        struct log_info *log = opt->loginfo;
        struct commit *commit = log->commit, *parent = log->parent;
        int abbrev = opt->diffopt.abbrev;
@@ -228,15 +264,17 @@ void show_log(struct rev_info *opt)
        if (!opt->verbose_header) {
                graph_show_commit(opt->graph);
 
-               if (commit->object.flags & BOUNDARY)
-                       putchar('-');
-               else if (commit->object.flags & UNINTERESTING)
-                       putchar('^');
-               else if (opt->left_right) {
-                       if (commit->object.flags & SYMMETRIC_LEFT)
-                               putchar('<');
-                       else
-                               putchar('>');
+               if (!opt->graph) {
+                       if (commit->object.flags & BOUNDARY)
+                               putchar('-');
+                       else if (commit->object.flags & UNINTERESTING)
+                               putchar('^');
+                       else if (opt->left_right) {
+                               if (commit->object.flags & SYMMETRIC_LEFT)
+                                       putchar('<');
+                               else
+                                       putchar('>');
+                       }
                }
                fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
                if (opt->print_parents)
@@ -293,15 +331,18 @@ void show_log(struct rev_info *opt)
                fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
                if (opt->commit_format != CMIT_FMT_ONELINE)
                        fputs("commit ", stdout);
-               if (commit->object.flags & BOUNDARY)
-                       putchar('-');
-               else if (commit->object.flags & UNINTERESTING)
-                       putchar('^');
-               else if (opt->left_right) {
-                       if (commit->object.flags & SYMMETRIC_LEFT)
-                               putchar('<');
-                       else
-                               putchar('>');
+
+               if (!opt->graph) {
+                       if (commit->object.flags & BOUNDARY)
+                               putchar('-');
+                       else if (commit->object.flags & UNINTERESTING)
+                               putchar('^');
+                       else if (opt->left_right) {
+                               if (commit->object.flags & SYMMETRIC_LEFT)
+                                       putchar('<');
+                               else
+                                       putchar('>');
+                       }
                }
                fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit),
                      stdout);
@@ -340,7 +381,6 @@ void show_log(struct rev_info *opt)
        /*
         * And then the pretty-printed message itself
         */
-       strbuf_init(&msgbuf, 0);
        if (need_8bit_cte >= 0)
                need_8bit_cte = has_non_ascii(opt->add_signoff);
        pretty_print_commit(opt->commit_format, commit, &msgbuf,
@@ -427,7 +467,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
        struct commit_list *parents;
        unsigned const char *sha1 = commit->object.sha1;
 
-       if (!opt->diff)
+       if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS))
                return 0;
 
        /* Root commit? */