Merge branch 'ye/doc-http-proto' into maint
[gitweb.git] / builtin / blame.c
index 88cb7997274de6f9ab6f8a5944748334ce605f60..6a284ce46b4f3b46a47d033fca607cae710806bc 100644 (file)
@@ -1405,7 +1405,7 @@ static void get_commit_info(struct commit *commit,
 {
        int len;
        const char *subject, *encoding;
-       char *message;
+       const char *message;
 
        commit_info_init(ret);
 
@@ -1416,7 +1416,7 @@ static void get_commit_info(struct commit *commit,
                    &ret->author_time, &ret->author_tz);
 
        if (!detailed) {
-               logmsg_free(message, commit);
+               unuse_commit_buffer(commit, message);
                return;
        }
 
@@ -1430,7 +1430,7 @@ static void get_commit_info(struct commit *commit,
        else
                strbuf_addf(&ret->summary, "(%s)", sha1_to_hex(commit->object.sha1));
 
-       logmsg_free(message, commit);
+       unuse_commit_buffer(commit, message);
 }
 
 /*
@@ -1556,22 +1556,29 @@ static void assign_blame(struct scoreboard *sb, int opt)
 static const char *format_time(unsigned long time, const char *tz_str,
                               int show_raw_time)
 {
-       static char time_buf[128];
+       static struct strbuf time_buf = STRBUF_INIT;
 
+       strbuf_reset(&time_buf);
        if (show_raw_time) {
-               snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str);
+               strbuf_addf(&time_buf, "%lu %s", time, tz_str);
        }
        else {
                const char *time_str;
-               int time_len;
+               size_t time_width;
                int tz;
                tz = atoi(tz_str);
                time_str = show_date(time, tz, blame_date_mode);
-               time_len = strlen(time_str);
-               memcpy(time_buf, time_str, time_len);
-               memset(time_buf + time_len, ' ', blame_date_width - time_len);
+               strbuf_addstr(&time_buf, time_str);
+               /*
+                * Add space paddings to time_buf to display a fixed width
+                * string, and use time_width for display width calibration.
+                */
+               for (time_width = utf8_strwidth(time_str);
+                    time_width < blame_date_width;
+                    time_width++)
+                       strbuf_addch(&time_buf, ' ');
        }
-       return time_buf;
+       return time_buf.buf;
 }
 
 #define OUTPUT_ANNOTATE_COMPAT 001
@@ -1998,6 +2005,18 @@ static void append_merge_parents(struct commit_list **tail)
        strbuf_release(&line);
 }
 
+/*
+ * This isn't as simple as passing sb->buf and sb->len, because we
+ * want to transfer ownership of the buffer to the commit (so we
+ * must use detach).
+ */
+static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
+{
+       size_t len;
+       void *buf = strbuf_detach(sb, &len);
+       set_commit_buffer(c, buf, len);
+}
+
 /*
  * Prepare a dummy commit that represents the work tree (or staged) item.
  * Note that annotating work tree item never works in the reverse.
@@ -2019,7 +2038,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
        struct strbuf msg = STRBUF_INIT;
 
        time(&now);
-       commit = xcalloc(1, sizeof(*commit));
+       commit = alloc_commit_node();
        commit->object.parsed = 1;
        commit->date = now;
        commit->object.type = OBJ_COMMIT;
@@ -2046,7 +2065,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
                    ident, ident, path,
                    (!contents_from ? path :
                     (!strcmp(contents_from, "-") ? "standard input" : contents_from)));
-       commit->buffer = strbuf_detach(&msg, NULL);
+       set_commit_buffer_from_strbuf(commit, &msg);
 
        if (!contents_from || strcmp("-", contents_from)) {
                struct stat st;
@@ -2088,7 +2107,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
                if (strbuf_read(&buf, 0, 0) < 0)
                        die_errno("failed to read from stdin");
        }
-       convert_to_git(path, buf.buf, buf.len, &buf, 0);
        origin->file.ptr = buf.buf;
        origin->file.size = buf.len;
        pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_sha1);
@@ -2331,7 +2349,14 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                blame_date_width = sizeof("2006-10-19");
                break;
        case DATE_RELATIVE:
-               /* "normal" is used as the fallback for "relative" */
+               /* TRANSLATORS: This string is used to tell us the maximum
+                  display width for a relative timestamp in "git blame"
+                  output.  For C locale, "4 years, 11 months ago", which
+                  takes 22 places, is the longest among various forms of
+                  relative timestamps, but your language may need more or
+                  fewer display columns. */
+               blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
+               break;
        case DATE_LOCAL:
        case DATE_NORMAL:
                blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
@@ -2433,11 +2458,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                die("revision walk setup failed");
 
        if (is_null_sha1(sb.final->object.sha1)) {
-               char *buf;
                o = sb.final->util;
-               buf = xmalloc(o->file.size + 1);
-               memcpy(buf, o->file.ptr, o->file.size + 1);
-               sb.final_buf = buf;
+               sb.final_buf = xmemdupz(o->file.ptr, o->file.size);
                sb.final_buf_size = o->file.size;
        }
        else {