Merge branch 'mk/blame-first-parent'
authorJeff King <peff@peff.net>
Tue, 1 Dec 2015 23:54:58 +0000 (18:54 -0500)
committerJeff King <peff@peff.net>
Tue, 1 Dec 2015 23:54:58 +0000 (18:54 -0500)
Regression fix for a topic already in master.

* mk/blame-first-parent:
blame: fix object casting regression

1  2 
builtin/blame.c
diff --combined builtin/blame.c
index 83612f5b646f1db7232cf69cf5a2ea6b30a6e833,eaa2c4260375370cb5fb15bf2ea600b39d4d8cf7..2afe82864b122018fabb832c4363977b58dae309
@@@ -6,7 -6,6 +6,7 @@@
   */
  
  #include "cache.h"
 +#include "refs.h"
  #include "builtin.h"
  #include "blob.h"
  #include "commit.h"
@@@ -51,7 -50,7 +51,7 @@@ static int xdl_opts
  static int abbrev = -1;
  static int no_whole_file_rename;
  
 -static enum date_mode blame_date_mode = DATE_ISO8601;
 +static struct date_mode blame_date_mode = { DATE_ISO8601 };
  static size_t blame_date_width;
  
  static struct string_list mailmap;
@@@ -459,13 -458,12 +459,13 @@@ static void queue_blames(struct scorebo
  static struct origin *make_origin(struct commit *commit, const char *path)
  {
        struct origin *o;
 -      o = xcalloc(1, sizeof(*o) + strlen(path) + 1);
 +      size_t pathlen = strlen(path) + 1;
 +      o = xcalloc(1, sizeof(*o) + pathlen);
        o->commit = commit;
        o->refcnt = 1;
        o->next = commit->util;
        commit->util = o;
 -      strcpy(o->path, path);
 +      memcpy(o->path, path, pathlen); /* includes NUL */
        return o;
  }
  
@@@ -975,10 -973,7 +975,10 @@@ static void pass_blame_to_parent(struc
        fill_origin_blob(&sb->revs->diffopt, target, &file_o);
        num_get_patch++;
  
 -      diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d);
 +      if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
 +              die("unable to generate diff (%s -> %s)",
 +                  sha1_to_hex(parent->commit->object.sha1),
 +                  sha1_to_hex(target->commit->object.sha1));
        /* The rest are the same as the parent */
        blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent);
        *d.dstq = NULL;
@@@ -1124,9 -1119,7 +1124,9 @@@ static void find_copy_in_blob(struct sc
         * file_p partially may match that image.
         */
        memset(split, 0, sizeof(struct blame_entry [3]));
 -      diff_hunks(file_p, &file_o, 1, handle_split_cb, &d);
 +      if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
 +              die("unable to generate diff (%s)",
 +                  sha1_to_hex(parent->commit->object.sha1));
        /* remainder, if any, all match the preimage */
        handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
  }
@@@ -1841,7 -1834,7 +1841,7 @@@ static const char *format_time(unsigne
                size_t time_width;
                int tz;
                tz = atoi(tz_str);
 -              time_str = show_date(time, tz, blame_date_mode);
 +              time_str = show_date(time, tz, &blame_date_mode);
                strbuf_addstr(&time_buf, time_str);
                /*
                 * Add space paddings to time_buf to display a fixed width
@@@ -1880,9 -1873,9 +1880,9 @@@ static void emit_porcelain(struct score
        int cnt;
        const char *cp;
        struct origin *suspect = ent->suspect;
 -      char hex[41];
 +      char hex[GIT_SHA1_HEXSZ + 1];
  
 -      strcpy(hex, sha1_to_hex(suspect->commit->object.sha1));
 +      sha1_to_hex_r(hex, suspect->commit->object.sha1);
        printf("%s %d %d %d\n",
               hex,
               ent->s_lno + 1,
@@@ -1918,11 -1911,11 +1918,11 @@@ static void emit_other(struct scoreboar
        const char *cp;
        struct origin *suspect = ent->suspect;
        struct commit_info ci;
 -      char hex[41];
 +      char hex[GIT_SHA1_HEXSZ + 1];
        int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
  
        get_commit_info(suspect->commit, &ci, 1);
 -      strcpy(hex, sha1_to_hex(suspect->commit->object.sha1));
 +      sha1_to_hex_r(hex, suspect->commit->object.sha1);
  
        cp = nth_line(sb, ent->lno);
        for (cnt = 0; cnt < ent->num_lines; cnt++) {
@@@ -2201,7 -2194,7 +2201,7 @@@ static int git_blame_config(const char 
        if (!strcmp(var, "blame.date")) {
                if (!value)
                        return config_error_nonbool(var);
 -              blame_date_mode = parse_date_format(value);
 +              parse_date_format(value, &blame_date_mode);
                return 0;
        }
  
@@@ -2240,19 -2233,20 +2240,19 @@@ static struct commit_list **append_pare
  static void append_merge_parents(struct commit_list **tail)
  {
        int merge_head;
 -      const char *merge_head_file = git_path("MERGE_HEAD");
        struct strbuf line = STRBUF_INIT;
  
 -      merge_head = open(merge_head_file, O_RDONLY);
 +      merge_head = open(git_path_merge_head(), O_RDONLY);
        if (merge_head < 0) {
                if (errno == ENOENT)
                        return;
 -              die("cannot open '%s' for reading", merge_head_file);
 +              die("cannot open '%s' for reading", git_path_merge_head());
        }
  
        while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
                unsigned char sha1[20];
                if (line.len < 40 || get_sha1_hex(line.buf, sha1))
 -                      die("unknown line in '%s': %s", merge_head_file, line.buf);
 +                      die("unknown line in '%s': %s", git_path_merge_head(), line.buf);
                tail = append_parent(tail, sha1);
        }
        close(merge_head);
@@@ -2402,10 -2396,12 +2402,12 @@@ static struct commit *fake_working_tree
        return commit;
  }
  
- static struct object_array_entry *find_single_final(struct rev_info *revs)
+ static struct commit *find_single_final(struct rev_info *revs,
+                                       const char **name_p)
  {
        int i;
-       struct object_array_entry *found = NULL;
+       struct commit *found = NULL;
+       const char *name = NULL;
  
        for (i = 0; i < revs->pending.nr; i++) {
                struct object *obj = revs->pending.objects[i].item;
                        die("Non commit %s?", revs->pending.objects[i].name);
                if (found)
                        die("More than one commit to dig from %s and %s?",
-                           revs->pending.objects[i].name,
-                           found->name);
-               found = &(revs->pending.objects[i]);
+                           revs->pending.objects[i].name, name);
+               found = (struct commit *)obj;
+               name = revs->pending.objects[i].name;
        }
+       if (name_p)
+               *name_p = name;
        return found;
  }
  
  static char *prepare_final(struct scoreboard *sb)
  {
-       struct object_array_entry *found = find_single_final(sb->revs);
-       if (found) {
-               sb->final = (struct commit *) found->item;
-               return xstrdup(found->name);
-       } else {
-               return NULL;
-       }
+       const char *name;
+       sb->final = find_single_final(sb->revs, &name);
+       return xstrdup_or_null(name);
  }
  
  static char *prepare_initial(struct scoreboard *sb)
@@@ -2588,13 -2582,13 +2588,13 @@@ parse_done
  
        if (cmd_is_annotate) {
                output_option |= OUTPUT_ANNOTATE_COMPAT;
 -              blame_date_mode = DATE_ISO8601;
 +              blame_date_mode.type = DATE_ISO8601;
        } else {
                blame_date_mode = revs.date_mode;
        }
  
        /* The maximum width used to show the dates */
 -      switch (blame_date_mode) {
 +      switch (blame_date_mode.type) {
        case DATE_RFC2822:
                blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
                break;
                   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");
                break;
 +      case DATE_STRFTIME:
 +              blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */
 +              break;
        }
        blame_date_width -= 1; /* strip the null */
  
                sb.commits.compare = compare_commits_by_commit_date;
        }
        else if (contents_from)
 -              die("--contents and --children do not blend well.");
 +              die("--contents and --reverse do not blend well.");
        else {
                final_commit_name = prepare_initial(&sb);
                sb.commits.compare = compare_commits_by_reverse_commit_date;
                die("Cannot use --contents with final commit object name");
  
        if (reverse && revs.first_parent_only) {
-               struct object_array_entry *entry = find_single_final(sb.revs);
-               if (!entry)
+               final_commit = find_single_final(sb.revs, NULL);
+               if (!final_commit)
                        die("--reverse and --first-parent together require specified latest commit");
-               else
-                       final_commit = (struct commit*) entry->item;
        }
  
        /*