Merge branch 'mh/blame-worktree'
authorJunio C Hamano <gitster@pobox.com>
Wed, 31 Aug 2016 17:03:50 +0000 (10:03 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 31 Aug 2016 17:03:50 +0000 (10:03 -0700)
* mh/blame-worktree:
blame: fix segfault on untracked files

1  2 
builtin/blame.c
diff --combined builtin/blame.c
index 7ec782343002d27b1b7fdd7e61fada12e81eeaf1,4d52f9602eae138a9c365b8f99795a7cd6951c6b..a5bbf91e497524215c884f1e145070afcf3f586a
@@@ -56,7 -56,7 +56,7 @@@ static int show_progress
  static struct date_mode blame_date_mode = { DATE_ISO8601 };
  static size_t blame_date_width;
  
 -static struct string_list mailmap;
 +static struct string_list mailmap = STRING_LIST_INIT_NODUP;
  
  #ifndef DEBUG
  #define DEBUG 0
@@@ -134,7 -134,7 +134,7 @@@ struct progress_info 
        int blamed_lines;
  };
  
 -static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen,
 +static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
                      xdl_emit_hunk_consume_func_t hunk_func, void *cb_data)
  {
        xpparam_t xpp = {0};
        xdemitcb_t ecb = {NULL};
  
        xpp.flags = xdl_opts;
 -      xecfg.ctxlen = ctxlen;
        xecfg.hunk_func = hunk_func;
        ecb.priv = cb_data;
        return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
@@@ -598,7 -599,7 +598,7 @@@ static struct origin *find_origin(struc
                            p->status);
                case 'M':
                        porigin = get_origin(sb, parent, origin->path);
 -                      hashcpy(porigin->blob_sha1, p->one->sha1);
 +                      hashcpy(porigin->blob_sha1, p->one->oid.hash);
                        porigin->mode = p->one->mode;
                        break;
                case 'A':
                }
        }
        diff_flush(&diff_opts);
 -      free_pathspec(&diff_opts.pathspec);
 +      clear_pathspec(&diff_opts.pathspec);
        return porigin;
  }
  
@@@ -644,13 -645,13 +644,13 @@@ static struct origin *find_rename(struc
                if ((p->status == 'R' || p->status == 'C') &&
                    !strcmp(p->two->path, origin->path)) {
                        porigin = get_origin(sb, parent, p->one->path);
 -                      hashcpy(porigin->blob_sha1, p->one->sha1);
 +                      hashcpy(porigin->blob_sha1, p->one->oid.hash);
                        porigin->mode = p->one->mode;
                        break;
                }
        }
        diff_flush(&diff_opts);
 -      free_pathspec(&diff_opts.pathspec);
 +      clear_pathspec(&diff_opts.pathspec);
        return porigin;
  }
  
@@@ -979,7 -980,7 +979,7 @@@ static void pass_blame_to_parent(struc
        fill_origin_blob(&sb->revs->diffopt, target, &file_o);
        num_get_patch++;
  
 -      if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
 +      if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d))
                die("unable to generate diff (%s -> %s)",
                    oid_to_hex(&parent->commit->object.oid),
                    oid_to_hex(&target->commit->object.oid));
@@@ -1128,7 -1129,7 +1128,7 @@@ static void find_copy_in_blob(struct sc
         * file_p partially may match that image.
         */
        memset(split, 0, sizeof(struct blame_entry [3]));
 -      if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
 +      if (diff_hunks(file_p, &file_o, handle_split_cb, &d))
                die("unable to generate diff (%s)",
                    oid_to_hex(&parent->commit->object.oid));
        /* remainder, if any, all match the preimage */
@@@ -1308,7 -1309,7 +1308,7 @@@ static void find_copy_in_parent(struct 
                                continue;
  
                        norigin = get_origin(sb, parent, p->one->path);
 -                      hashcpy(norigin->blob_sha1, p->one->sha1);
 +                      hashcpy(norigin->blob_sha1, p->one->oid.hash);
                        norigin->mode = p->one->mode;
                        fill_origin_blob(&sb->revs->diffopt, norigin, &file_p);
                        if (!file_p.ptr)
        } while (unblamed);
        target->suspects = reverse_blame(leftover, NULL);
        diff_flush(&diff_opts);
 -      free_pathspec(&diff_opts.pathspec);
 +      clear_pathspec(&diff_opts.pathspec);
  }
  
  /*
@@@ -2244,7 -2245,8 +2244,8 @@@ static void verify_working_tree_path(st
        pos = cache_name_pos(path, strlen(path));
        if (pos >= 0)
                ; /* path is in the index */
-       else if (!strcmp(active_cache[-1 - pos]->name, path))
+       else if (-1 - pos < active_nr &&
+                !strcmp(active_cache[-1 - pos]->name, path))
                ; /* path is in the index, unmerged */
        else
                die("no such path '%s' in HEAD", path);
@@@ -2432,7 -2434,8 +2433,7 @@@ static struct commit *find_single_final
                struct object *obj = revs->pending.objects[i].item;
                if (obj->flags & UNINTERESTING)
                        continue;
 -              while (obj->type == OBJ_TAG)
 -                      obj = deref_tag(obj, NULL, 0);
 +              obj = deref_tag(obj, NULL, 0);
                if (obj->type != OBJ_COMMIT)
                        die("Non commit %s?", revs->pending.objects[i].name);
                if (found)
@@@ -2467,7 -2470,8 +2468,7 @@@ static char *prepare_initial(struct sco
                struct object *obj = revs->pending.objects[i].item;
                if (!(obj->flags & UNINTERESTING))
                        continue;
 -              while (obj->type == OBJ_TAG)
 -                      obj = deref_tag(obj, NULL, 0);
 +              obj = deref_tag(obj, NULL, 0);
                if (obj->type != OBJ_COMMIT)
                        die("Non commit %s?", revs->pending.objects[i].name);
                if (sb->final)
@@@ -2527,12 -2531,12 +2528,12 @@@ int cmd_blame(int argc, const char **ar
        enum object_type type;
        struct commit *final_commit = NULL;
  
 -      static struct string_list range_list;
 -      static int output_option = 0, opt = 0;
 -      static int show_stats = 0;
 -      static const char *revs_file = NULL;
 -      static const char *contents_from = NULL;
 -      static const struct option options[] = {
 +      struct string_list range_list = STRING_LIST_INIT_NODUP;
 +      int output_option = 0, opt = 0;
 +      int show_stats = 0;
 +      const char *revs_file = NULL;
 +      const char *contents_from = NULL;
 +      const struct option options[] = {
                OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
                OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
                OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
@@@ -2633,9 -2637,6 +2634,9 @@@ parse_done
        case DATE_RAW:
                blame_date_width = sizeof("1161298804 -0700");
                break;
 +      case DATE_UNIX:
 +              blame_date_width = sizeof("1161298804");
 +              break;
        case DATE_SHORT:
                blame_date_width = sizeof("2006-10-19");
                break;
        lno = prepare_lines(&sb);
  
        if (lno && !range_list.nr)
 -              string_list_append(&range_list, xstrdup("1"));
 +              string_list_append(&range_list, "1");
  
        anchor = 1;
        range_set_init(&ranges, range_list.nr);