{"thread":{"id":"39664","subject":"git difftool --dir-diff error in the presence of symlinks to directories","startedAt":"2015-06-17T22:39:27Z","lastAt":"2015-06-22T05:20:25Z","messageCount":2,"participants":["Ismail Badawi","David Aguilar"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"264100","messageId":"CAFB4ZjUnhEMfjg9+sHrPp271e=V=yU_5QFHBbmPpWMkb72+ENw@mail.gmail.com","threadId":"39664","inReplyTo":null,"subject":"git difftool --dir-diff error in the presence of symlinks to directories","fromName":"Ismail Badawi","fromEmail":"ismail@badawi.io","sentAt":"2015-06-17T22:39:27Z","receivedAt":"2015-06-17T22:39:27Z","isPatch":false,"sender":{"key":"ismail@badawi.io","avatar":null},"body":"Reproduce like this (using git 2.4.3):\n\ngit init\nmkdir foo\ntouch foo/bar\ngit add .\ngit commit -m \"Initial commit.\"\nln -s foo link\ngit add .\ngit commit -m \"Add link to foo.\"\ngit difftool -d HEAD^ HEAD\n\nThat last command outputs:\n\nfatal: Unable to hash /Users/isbadawi/test/link\nhash-object /Users/isbadawi/test/link: command returned error: 128\n\nBriefly looking at the 'git difftool' source it looks like it uses the\noutput of 'git diff --raw' and calls 'hash-object' on any object whose\nmode is nonzero, including symlinks.\n\nI'm not sure what the right thing to do here is -- just thought I'd\nreport this failure.\n\nThanks,\nIsmail\n"},{"id":"264488","messageId":"20150622052024.GA2188@gmail.com","threadId":"39664","inReplyTo":"CAFB4ZjUnhEMfjg9+sHrPp271e=V=yU_5QFHBbmPpWMkb72+ENw@mail.gmail.com","subject":"Re: git difftool --dir-diff error in the presence of symlinks to directories","fromName":"David Aguilar","fromEmail":"davvid@gmail.com","sentAt":"2015-06-22T05:20:25Z","receivedAt":"2015-06-22T05:20:25Z","isPatch":false,"sender":{"key":"davvid@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13196?v=4"},"body":"On Wed, Jun 17, 2015 at 06:39:27PM -0400, Ismail Badawi wrote:\n> Reproduce like this (using git 2.4.3):\n> \n> git init\n> mkdir foo\n> touch foo/bar\n> git add .\n> git commit -m \"Initial commit.\"\n> ln -s foo link\n> git add .\n> git commit -m \"Add link to foo.\"\n> git difftool -d HEAD^ HEAD\n> \n> That last command outputs:\n> \n> fatal: Unable to hash /Users/isbadawi/test/link\n> hash-object /Users/isbadawi/test/link: command returned error: 128\n> \n> Briefly looking at the 'git difftool' source it looks like it uses the\n> output of 'git diff --raw' and calls 'hash-object' on any object whose\n> mode is nonzero, including symlinks.\n> \n> I'm not sure what the right thing to do here is -- just thought I'd\n> report this failure.\n> \n> Thanks,\n> Ismail\n\nThanks for the bug report, Ismail.\n\nThis looks like an unhandled edge case that difftool's dir-diff\nmode doesn't take into account.  I've cc'd Tim and John since\nthey're both familiar with this part of the code.\n\nWe should take your bug recipe above and add it to difftool's\ntest suite when fixing the bug.  I've included a diff below that\nadds the above snippet to t7800-difftool.sh.\n\nAs far as how to handle this edge case -- one option is that we\ncould detect that the link points at a directory and ignore it.\n\nI think what's happening is that we're hashing the file so that\nwe can later detect whether it's changed.  The fix might be as\nsimple as skipping links to directories in that code path, but I\nhaven't looked too closely yet.  I can take a look in a couple\nof weeks if no one beats me to it by then.\n\n--- >8 --- >8 ---\ndiff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh\nindex ea35a02..f67fc65 100755\n--- a/t/t7800-difftool.sh\n+++ b/t/t7800-difftool.sh\n@@ -504,4 +504,24 @@ test_expect_success PERL 'difftool properly honors gitlink and core.worktree' '\n \t)\n '\n \n+test_expect_success PERL,SYMLINKS 'difftool --dir-diff symlinked directories' '\n+\ttest_config diff.tool checktrees &&\n+\ttest_config difftool.checktrees.cmd \"echo good\" &&\n+\tgit init dirlinks &&\n+\t(\n+\t\tcd dirlinks &&\n+\t\tmkdir foo &&\n+\t\t: >foo/bar &&\n+\t\tgit add foo/bar &&\n+\t\ttest_commit one &&\n+\t\tln -s foo link\n+\t\tgit add link\n+\t\ttest_commit two &&\n+\t\techo good >expect &&\n+\t\tgit difftool --dir-diff HEAD~ >actual &&\n+\t\ttest_commit expect actual\n+\n+\t)\n+'\n+\n test_done\n-- \nDavid\n"}]}