Merge branch 'mh/blame-worktree'
authorJunio C Hamano <gitster@pobox.com>
Mon, 25 Jul 2016 21:13:45 +0000 (14:13 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 25 Jul 2016 21:13:45 +0000 (14:13 -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

builtin/blame.c
t/t8003-blame-corner-cases.sh
index 8fec0e1fb31f2a71f523a4a9fd21b4b6c5fa3362..ab66cde2c2cf0f535678469cdf6eb6e37cd3113b 100644 (file)
@@ -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,14 @@ 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 (!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)
index a9b266f0d3d029229a346fb21c703acb84e4c37d..e48370dfa06b33448bbcf63a3db59bce4c1de6e8 100755 (executable)
@@ -41,12 +41,12 @@ test_expect_success setup '
        test_tick &&
        GIT_AUTHOR_NAME=Fourth git commit -m Fourth &&
 
-       {
-               echo ABC
-               echo DEF
-               echo XXXX
-               echo GHIJK
-       } >cow &&
+       cat >cow <<-\EOF &&
+       ABC
+       DEF
+       XXXX
+       GHIJK
+       EOF
        git add cow &&
        test_tick &&
        GIT_AUTHOR_NAME=Fifth git commit -m Fifth
@@ -115,11 +115,11 @@ test_expect_success 'append with -C -C -C' '
 test_expect_success 'blame wholesale copy' '
 
        git blame -f -C -C1 HEAD^ -- cow | sed -e "$pick_fc" >current &&
-       {
-               echo mouse-Initial
-               echo mouse-Second
-               echo mouse-Third
-       } >expected &&
+       cat >expected <<-\EOF &&
+       mouse-Initial
+       mouse-Second
+       mouse-Third
+       EOF
        test_cmp expected current
 
 '
@@ -127,16 +127,61 @@ test_expect_success 'blame wholesale copy' '
 test_expect_success 'blame wholesale copy and more' '
 
        git blame -f -C -C1 HEAD -- cow | sed -e "$pick_fc" >current &&
-       {
-               echo mouse-Initial
-               echo mouse-Second
-               echo cow-Fifth
-               echo mouse-Third
-       } >expected &&
+       cat >expected <<-\EOF &&
+       mouse-Initial
+       mouse-Second
+       cow-Fifth
+       mouse-Third
+       EOF
        test_cmp expected current
 
 '
 
+test_expect_success 'blame wholesale copy and more in the index' '
+
+       cat >horse <<-\EOF &&
+       ABC
+       DEF
+       XXXX
+       YYYY
+       GHIJK
+       EOF
+       git add horse &&
+       test_when_finished "git rm -f horse" &&
+       git blame -f -C -C1 -- horse | sed -e "$pick_fc" >current &&
+       cat >expected <<-\EOF &&
+       mouse-Initial
+       mouse-Second
+       cow-Fifth
+       horse-Not
+       mouse-Third
+       EOF
+       test_cmp expected current
+
+'
+
+test_expect_success 'blame during cherry-pick with file rename conflict' '
+
+       test_when_finished "git reset --hard && git checkout master" &&
+       git checkout HEAD~3 &&
+       echo MOUSE >> mouse &&
+       git mv mouse rodent &&
+       git add rodent &&
+       GIT_AUTHOR_NAME=Rodent git commit -m "rodent" &&
+       git checkout --detach master &&
+       (git cherry-pick HEAD@{1} || test $? -eq 1) &&
+       git show HEAD@{1}:rodent > rodent &&
+       git add rodent &&
+       git blame -f -C -C1 rodent | sed -e "$pick_fc" >current &&
+       cat current &&
+       cat >expected <<-\EOF &&
+       mouse-Initial
+       mouse-Second
+       rodent-Not
+       EOF
+       test_cmp expected current
+'
+
 test_expect_success 'blame path that used to be a directory' '
        mkdir path &&
        echo A A A A A >path/file &&