Merge branch 'js/regexec-buf' into maint
[gitweb.git] / builtin / blame.c
index a3f68747326836fff7b1f99ce3e5b858f77f97ab..a5bbf91e497524215c884f1e145070afcf3f586a 100644 (file)
@@ -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
@@ -598,7 +598,7 @@ static struct origin *find_origin(struct scoreboard *sb,
                            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':
@@ -608,7 +608,7 @@ static struct origin *find_origin(struct scoreboard *sb,
                }
        }
        diff_flush(&diff_opts);
-       free_pathspec(&diff_opts.pathspec);
+       clear_pathspec(&diff_opts.pathspec);
        return porigin;
 }
 
@@ -644,13 +644,13 @@ static struct origin *find_rename(struct scoreboard *sb,
                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;
 }
 
@@ -1308,7 +1308,7 @@ static void find_copy_in_parent(struct scoreboard *sb,
                                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)
@@ -1342,7 +1342,7 @@ static void find_copy_in_parent(struct scoreboard *sb,
        } while (unblamed);
        target->suspects = reverse_blame(leftover, NULL);
        diff_flush(&diff_opts);
-       free_pathspec(&diff_opts.pathspec);
+       clear_pathspec(&diff_opts.pathspec);
 }
 
 /*
@@ -2229,6 +2229,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 static void verify_working_tree_path(struct commit *work_tree, const char *path)
 {
        struct commit_list *parents;
+       int pos;
 
        for (parents = work_tree->parents; parents; parents = parents->next) {
                const unsigned char *commit_sha1 = parents->item->object.oid.hash;
@@ -2239,7 +2240,15 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
                    sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
                        return;
        }
-       die("no such path '%s' in HEAD", path);
+
+       pos = cache_name_pos(path, strlen(path));
+       if (pos >= 0)
+               ; /* path is in the index */
+       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);
 }
 
 static struct commit_list **append_parent(struct commit_list **tail, const unsigned char *sha1)
@@ -2424,8 +2433,7 @@ static struct commit *find_single_final(struct rev_info *revs,
                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)
@@ -2460,8 +2468,7 @@ static char *prepare_initial(struct scoreboard *sb)
                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)
@@ -2521,12 +2528,12 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        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)")),
@@ -2627,6 +2634,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        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;
@@ -2799,7 +2809,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        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);