Merge branch 'mh/blame-worktree' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 8 Aug 2016 21:21:32 +0000 (14:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 8 Aug 2016 21:21:32 +0000 (14:21 -0700)
"git blame file" allowed the lineage of lines in the uncommitted,
unadded contents of "file" to be inspected, but it refused when
"file" did not appear in the current commit. When "file" was
created by renaming an existing file (but the change has not been
committed), this restriction was unnecessarily tight.

* mh/blame-worktree:
t/t8003-blame-corner-cases.sh: Use here documents
blame: allow to blame paths freshly added to the index

1  2 
builtin/blame.c
diff --combined builtin/blame.c
index 9a035000b0c596523fd457073382101f99e89aa4,12c765acfede5727b27b2afaed2eb290fd930fc6..d123e2e6aeba54b234ae3876a6c94e617964a22a
@@@ -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);
@@@ -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 */
@@@ -2229,6 -2230,7 +2229,7 @@@ static int git_blame_config(const char 
  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;
                    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 (!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,7 -2433,8 +2432,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)
@@@ -2459,7 -2469,8 +2467,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)