{"thread":{"id":"41884","subject":"BUG in git diff-index","startedAt":"2016-03-31T12:39:23Z","lastAt":"2018-05-25T03:55:32Z","messageCount":13,"participants":["Andy Lowry","Carlos Martín Nieto","Jeff King","Junio C Hamano","Marc Herbert","Eric Wong","Mike Mason"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"282302","messageId":"loom.20160331T143733-916@post.gmane.org","threadId":"41884","inReplyTo":null,"subject":"BUG in git diff-index","fromName":"Andy Lowry","fromEmail":"andy.work@nglowry.com","sentAt":"2016-03-31T12:39:23Z","receivedAt":"2016-03-31T12:39:23Z","isPatch":false,"sender":{"key":"andy.work@nglowry.com","avatar":null},"body":"Following transcript illustrates what I believe to be a bug in git diff-\nindex. The session used a git built from latest source, located in \n/tmp/git/git.\n\n1. New repo, create empty file A, commit changes.\n2. touch A\n3. git diff-index reports A has changed, and reports bogus destination \nSHA\n4. This is stable behavior until next step\n5. git diff correctly reports no changes\n6. git diff-index now also reports nothing\n\nMy understanding is that git diff-index should care only about content \nand file mode, not modification time.\n\n===========================================================\nandy@wiki:/tmp$ git/git init xxx\nwarning: templates not found /home/andy/share/git-core/templates\nInitialized empty Git repository in /tmp/xxx/.git/\nandy@wiki:/tmp$ cd xxx\nandy@wiki:/tmp/xxx$ touch A\nandy@wiki:/tmp/xxx$ ../git/git add A\nandy@wiki:/tmp/xxx$ ../git/git commit -m initial\n[master (root-commit) 370c3ac] initial\n 1 file changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 A\nandy@wiki:/tmp/xxx$ touch A\nandy@wiki:/tmp/xxx$ ../git/git diff-index HEAD\n:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 \n0000000000000000000000000000000000000000 M    A\nandy@wiki:/tmp/xxx$ ../git/git diff-index HEAD\n:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 \n0000000000000000000000000000000000000000 M    A\nandy@wiki:/tmp/xxx$ ../git/git diff\nandy@wiki:/tmp/xxx$ ../git/git diff-index HEAD\nandy@wiki:/tmp/xxx$ \n"},{"id":"282306","messageId":"1459432667.2124.2.camel@dwim.me","threadId":"41884","inReplyTo":"loom.20160331T143733-916@post.gmane.org","subject":"Re: BUG in git diff-index","fromName":"Carlos Martín Nieto","fromEmail":"cmn@dwim.me","sentAt":"2016-03-31T13:57:47Z","receivedAt":"2016-03-31T13:57:47Z","isPatch":false,"sender":{"key":"cmn@dwim.me","avatar":"https://avatars.githubusercontent.com/u/335443?v=4"},"body":"On Thu, 2016-03-31 at 12:39 +0000, Andy Lowry wrote:\n> Following transcript illustrates what I believe to be a bug in git\n> diff-\n> index. The session used a git built from latest source, located in \n> /tmp/git/git.\n> \n> 1. New repo, create empty file A, commit changes.\n> 2. touch A\n> 3. git diff-index reports A has changed, and reports bogus\n> destination \n> SHA\n> 4. This is stable behavior until next step\n\nThis is expected and matches the documentation. See the bit starting\nwith\n\n    OPERATING MODES\n           You can choose whether you want to trust the index file entirely (using the --cached flag) or ask the diff\n           logic to show any files that don’t match the stat state as being \"tentatively changed\". Both of these\n           operations are very useful indeed.\n\nThe next two sections describe what you are seeing. The default is non-\ncached mode which also shows files which don't match the stat data in\nthe index (which you've changed by touching the file).\n\nCheers,\n   cmn\n"},{"id":"282307","messageId":"20160331140515.GA31116@sigill.intra.peff.net","threadId":"41884","inReplyTo":"loom.20160331T143733-916@post.gmane.org","subject":"Re: BUG in git diff-index","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-03-31T14:05:15Z","receivedAt":"2016-03-31T14:05:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Mar 31, 2016 at 12:39:23PM +0000, Andy Lowry wrote:\n\n> Following transcript illustrates what I believe to be a bug in git diff-\n> index. The session used a git built from latest source, located in \n> /tmp/git/git.\n> \n> 1. New repo, create empty file A, commit changes.\n> 2. touch A\n> 3. git diff-index reports A has changed, and reports bogus destination \n> SHA\n> 4. This is stable behavior until next step\n> 5. git diff correctly reports no changes\n> 6. git diff-index now also reports nothing\n> \n> My understanding is that git diff-index should care only about content \n> and file mode, not modification time.\n\nThis is working as designed (though I agree it is a little confusing).\nFrom \"git help diff-index\":\n\n       These commands all compare two sets of things; what is compared differs:\n\n       git-diff-index <tree-ish>\n           compares the <tree-ish> and the files on the filesystem.\n\n       git-diff-index --cached <tree-ish>\n           compares the <tree-ish> and the index.\n\n       git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]\n           compares the trees named by the two arguments.\n\n       git-diff-files [<pattern>...]\n           compares the index and the files on the filesystem.\n\nYour invocation triggers the first, though it is not a true comparison\nof what is on the filesystem, but rather a tree/index comparison, taking\ninto account the filesystem values. The all-zeroes sha1 indicates that\nthe index entry is not up to date with what is in the filesystem, but we\ndon't actually read the file contents to refresh the entry.\n\nBack when diff-index was written, it was generally assumed that scripts\nwould refresh the index as their first operation, and then proceed to do\none or more operations like diff-index, which would rely on the refresh\nfrom the first step.\n\nRunning the porcelain \"git diff\" does refresh the index, which is why\nyour step 6 shows no diff.\n\nIf you want a pure tree-to-index comparison, use --cached (this will\nalso be slightly faster, as it does not have to stat the working tree at\nall).\n\n-Peff\n"},{"id":"282308","messageId":"CAJxkE8SVF_ikHqDCh6eHExq=seitHPVpxW2GmPo40jtqWvz1JQ@mail.gmail.com","threadId":"41884","inReplyTo":"20160331140515.GA31116@sigill.intra.peff.net","subject":"BUG in git diff-index","fromName":"Andy Lowry","fromEmail":"andy.work@nglowry.com","sentAt":"2016-03-31T14:12:07Z","receivedAt":"2016-03-31T14:12:07Z","isPatch":false,"sender":{"key":"andy.work@nglowry.com","avatar":null},"body":"Thanks, very helpful.\n\nWhat I'm actually after is a tree-to-filesystem comparison, regardless\nof index. I've currently got a \"diff\" thrown in as a \"work-around\"\nbefore \"diff-index\", but  now I understand it's not a workaround at\nall. If there's a better way to achieve what I'm after, I'd appreciate\na tip. Otherwise I'll just change the comments explaining why there's\na \"diff\" in my script.\n\nandy\n\n> &gt; 5. git diff correctly reports no changes &gt; 6. git diff-index now also reports nothing This is working as designed (though I agree it is a little confusing). From \"git help diff-index\": These commands all compare two sets of things; what is compared differs: git-diff-index  compares the  and the files on the filesystem. git-diff-index --cached  compares the  and the index. git-diff-tree [-r]   [...] compares the trees named by the two arguments. git-diff-files [...] compares the index and the files on the filesystem. Your invocation triggers the first, though it is not a true comparison of what is on the filesystem, but rather a tree/index comparison, taking into account the filesystem values. The all-zeroes sha1 indicates that the index entry is not up to date with what is in the\n  filesystem, but we don't actually read the file contents to refresh the entry. Back when diff-index was written, it was generally assumed that scripts would refresh the index as their first operation, and then proceed to do one or more operations like diff-index, which would rely on the refresh from the first step. Running the porcelain \"git diff\" does refresh the index, which is why your step 6 shows no diff. If you want a pure tree-to-index comparison, use --cached (this will also be slightly faster, as it does not have to stat the working tree at all). -Peff\n"},{"id":"282311","messageId":"20160331142704.GC31116@sigill.intra.peff.net","threadId":"41884","inReplyTo":"CAJxkE8SVF_ikHqDCh6eHExq=seitHPVpxW2GmPo40jtqWvz1JQ@mail.gmail.com","subject":"Re: BUG in git diff-index","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-03-31T14:27:04Z","receivedAt":"2016-03-31T14:27:04Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Mar 31, 2016 at 10:12:07AM -0400, Andy Lowry wrote:\n\n> What I'm actually after is a tree-to-filesystem comparison, regardless\n> of index. I've currently got a \"diff\" thrown in as a \"work-around\"\n> before \"diff-index\", but  now I understand it's not a workaround at\n> all. If there's a better way to achieve what I'm after, I'd appreciate\n> a tip. Otherwise I'll just change the comments explaining why there's\n> a \"diff\" in my script.\n\nIf your workaround is just to refresh the index, then you can do \"git\nupdate-index --refresh\", rather than diff.\n\nI don't think there is a plumbing command to do a direct\nfilesystem-to-tree comparison without having an index at all. \"git diff\n<treeish>\" claims in the documentation to do so, but besides not being\nplumbing, I think it is really just doing the same thing as diff-index,\nunder the hood. The index is a pretty fundamental part of git's view of\nthe working tree.\n\n-Peff\n"},{"id":"282376","messageId":"56FD7AE8.4090905@nglowry.com","threadId":"41884","inReplyTo":"20160331142704.GC31116@sigill.intra.peff.net","subject":"Re: BUG in git diff-index","fromName":"Andy Lowry","fromEmail":"andy.work@nglowry.com","sentAt":"2016-03-31T19:30:48Z","receivedAt":"2016-03-31T19:30:48Z","isPatch":false,"sender":{"key":"andy.work@nglowry.com","avatar":null},"body":"OK, great. I think the update-index command is what I need.\n\nIf you'll indulge me, I'll describe my use-case in detail, and if you \nsee anything screwy about it, I'd appreciate feedback. But don't feel \nobligated - you've been a great help already.\n\nThis is all about publishing updates to a static web site hosted as a \ngh-pages branch on a github repo.\n\nOur master branch has everything that goes into building the site, and \nwe use subtree push to update gh-pages with the embedded subtree that \ncontains the generated site.\n\nI'm creating a bash script that does the publishing, and as a general \nrule, we want to publish only from the master branch, and only if it's \nclean and up-to-date. And we also want to make sure that the embedded \nsite reflects the current source content.\n\nIt's in that last requirement where diff-index comes in. The script runs \na site build, and then should fail the policy check if that results in \nany changes to the working tree (including the embedded site)/. /I don't \nwant the script to change the index in any way (e.g. so that unintended \nchanges revealed by this policy check are less likely to be accidentally \ncommited).\n\nIf I understand correctly, the update-index operation you indicated will \nnot change index membership at all, but will simply resync the index \nmembers with actual working tree files.\n\nSo I think now that the script should do \"update-index --refresh\" \nfollowed by \"diff-index --quiet HEAD\". Sound correct?\n\nAndy\n\nOn 3/31/2016 10:27 AM, Jeff King wrote:\n> On Thu, Mar 31, 2016 at 10:12:07AM -0400, Andy Lowry wrote:\n>\n>> What I'm actually after is a tree-to-filesystem comparison, regardless\n>> of index. I've currently got a \"diff\" thrown in as a \"work-around\"\n>> before \"diff-index\", but  now I understand it's not a workaround at\n>> all. If there's a better way to achieve what I'm after, I'd appreciate\n>> a tip. Otherwise I'll just change the comments explaining why there's\n>> a \"diff\" in my script.\n> If your workaround is just to refresh the index, then you can do \"git\n> update-index --refresh\", rather than diff.\n>\n> I don't think there is a plumbing command to do a direct\n> filesystem-to-tree comparison without having an index at all. \"git diff\n> <treeish>\" claims in the documentation to do so, but besides not being\n> plumbing, I think it is really just doing the same thing as diff-index,\n> under the hood. The index is a pretty fundamental part of git's view of\n> the working tree.\n>\n> -Peff\n"},{"id":"282386","messageId":"xmqqwpoil6vt.fsf@gitster.mtv.corp.google.com","threadId":"41884","inReplyTo":"56FD7AE8.4090905@nglowry.com","subject":"Re: BUG in git diff-index","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-31T20:39:02Z","receivedAt":"2016-03-31T20:39:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Lowry <andy.work@nglowry.com> writes:\n\n> So I think now that the script should do \"update-index --refresh\"\n> followed by \"diff-index --quiet HEAD\". Sound correct?\n\nYes.  That has always been one of the kosher ways for any script to\nmake sure that the files in the working tree that are tracked have\nnot been modified relative to HEAD (assuming that the index matches\nHEAD).  If you are fuzzy about that assumption, you would also do\n\"diff-index --quiet --cached HEAD\" to ensure it, making the whole\nthing:\n\n\tupdate-index --refresh\n        diff-index --quiet --cached HEAD && diff-index --quiet HEAD\n\nOur scripts traditionally do the equivalent in a slightly different\nway.  require_clean_work_tree() in git-sh-setup makes sure that (1)\nyour working tree files match what is in your index and that (2)\nyour index matches the HEAD, i.e.\n\n\tupdate-index --refresh\n        diff-files --quiet && diff-index --cached --quiet HEAD\n\nThey are equivalent in that H==I && H==W (yours) mean H==I==W, while\nI==W && H==I (ours) also mean H==I==W.  Two diff-index would require\nyou to open the tree object of the HEAD twice, so our version may be\nmore efficient but you probably wouldn't be able to measure the\ndifference.\n"},{"id":"328961","messageId":"d9b4725b-3204-03af-1bc2-6469bb815c63@intel.com","threadId":"41884","inReplyTo":"xmqqwpoil6vt.fsf@gitster.mtv.corp.google.com","subject":"Re: BUG in git diff-index","fromName":"Marc Herbert","fromEmail":"marc.herbert@intel.com","sentAt":"2017-09-26T19:46:13Z","receivedAt":"2017-09-26T19:46:52Z","isPatch":false,"sender":{"key":"marc.herbert@intel.com","avatar":null},"body":"On 31/03/16 13:39, Junio C Hamano wrote:\n> Andy Lowry <andy.work@nglowry.com> writes:\n> \n>> So I think now that the script should do \"update-index --refresh\"\n>> followed by \"diff-index --quiet HEAD\". Sound correct?\n> \n> Yes.  That has always been one of the kosher ways for any script to\n> make sure that the files in the working tree that are tracked have\n> not been modified relative to HEAD (assuming that the index matches\n> HEAD).  \n\nToo bad kernel/scripts/setlocalversion didn't get the memo:\n\nhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cdf2bc632ebc9ef51\n> scripts/setlocalversion on write-protected source tree (2013)\n> I don't see how removing \"git update-index\" could do any harm.\n\nThis causes a spurious \"-dirty\" suffix when building from a directory copy\n(as Mike learned the hard way)\n\n  ----\n\nPS: I used NNTP and http://dir.gmane.org/gmane.comp.version-control.git\nto quickly find this old thread (what could we do without NNTP?). Then\nI googled for a web archive of this thread and Google could only find\nthis one: http://git.661346.n2.nabble.com/BUG-in-git-diff-index-tt7652105.html#none\nIs there a robots.txt to block indexing on\nhttps://public-inbox.org/git/1459432667.2124.2.camel@dwim.me ?\n"},{"id":"328964","messageId":"20170926201112.GA26968@whir","threadId":"41884","inReplyTo":"d9b4725b-3204-03af-1bc2-6469bb815c63@intel.com","subject":"Re: BUG in git diff-index","fromName":"Eric Wong","fromEmail":"e@80x24.org","sentAt":"2017-09-26T20:11:12Z","receivedAt":"2017-09-26T20:19:34Z","isPatch":false,"sender":{"key":"e@80x24.org","avatar":null},"body":"Marc Herbert <Marc.Herbert@intel.com> wrote:\n> PS: I used NNTP and http://dir.gmane.org/gmane.comp.version-control.git\n> to quickly find this old thread (what could we do without NNTP?). Then\n> I googled for a web archive of this thread and Google could only find\n> this one: http://git.661346.n2.nabble.com/BUG-in-git-diff-index-tt7652105.html#none\n> Is there a robots.txt to block indexing on\n> https://public-inbox.org/git/1459432667.2124.2.camel@dwim.me ?\n\nThere's no blocks on public-inbox.org and I'm completely against\nany sort of blocking/throttling.  Maybe there's too many pages\nto index?  Or the Message-IDs in URLs are too ugly/scary?  Not\nsure what to do about that...\n\nAnyways, I just put up a robots.txt with Crawl-Delay: 1, since I\nseem to recall crawlers use a more conservative delay by default:\n\n==> https://public-inbox.org/robots.txt <==\nUser-Agent: *\nCrawl-Delay: 1\n\n\nI don't know much about SEO other than keeping a site up and\nresponsive; so perhaps there's more to be done about getting\nthings indexed...\n"},{"id":"328972","messageId":"cb495eeb-73d0-ef88-57b6-a601e1d8cfc0@intel.com","threadId":"41884","inReplyTo":"20170926201112.GA26968@whir","subject":"Google indexing https://public-inbox.org/git (was: BUG in git diff-index)","fromName":"Marc Herbert","fromEmail":"marc.herbert@intel.com","sentAt":"2017-09-26T23:27:15Z","receivedAt":"2017-09-26T23:27:19Z","isPatch":false,"sender":{"key":"marc.herbert@intel.com","avatar":null},"body":"[Reduced Cc: and change Subject:]\n\nOn 26/09/17 13:11, Eric Wong wrote:\n> There's no blocks on public-inbox.org and I'm completely against\n> any sort of blocking/throttling.  Maybe there's too many pages\n> to index?  Or the Message-IDs in URLs are too ugly/scary?  Not\n> sure what to do about that...\n> \n> Anyways, I just put up a robots.txt with Crawl-Delay: 1, since I\n> seem to recall crawlers use a more conservative delay by default:\n\nNot sure what made the difference: Google can now easily find this\nthread on both https://public-inbox.org/git and on spinics too.\n\nSame change observed for another, unrelated thread on this list.\n\nNevermind.\n\n\"Unsearchable are his judgments, and his ways past finding out\"\n"},{"id":"329061","messageId":"89d82c84-7a3b-9c4c-679e-a7a723669592@intel.com","threadId":"41884","inReplyTo":"d9b4725b-3204-03af-1bc2-6469bb815c63@intel.com","subject":"Wrong -dirty suffix set by setlocalversion (was: BUG in git diff-index)","fromName":"Marc Herbert","fromEmail":"marc.herbert@intel.com","sentAt":"2017-09-27T21:06:24Z","receivedAt":"2017-09-27T21:06:44Z","isPatch":false,"sender":{"key":"marc.herbert@intel.com","avatar":null},"body":"+ linux-kbuild list which is not in the output of:\n  ./scripts/get_maintainer.pl -f scripts/setlocalversion \n... but seems relevant anyway.\n\nOn 31/03/16 13:39, Junio C Hamano wrote:\n> Andy Lowry <andy.work@nglowry.com> writes:\n> \n>> So I think now that the script should do \"update-index --refresh\"\n>> followed by \"diff-index --quiet HEAD\". Sound correct?\n> \n> Yes.  That has always been one of the kosher ways for any script to\n> make sure that the files in the working tree that are tracked have\n> not been modified relative to HEAD (assuming that the index matches\n> HEAD).  \n\nToo bad kernel/scripts/setlocalversion didn't get the memo:\n\nhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cdf2bc632ebc9ef51\n> scripts/setlocalversion on write-protected source tree (2013)\n> I don't see how removing \"git update-index\" could do any harm.\n\nThis causes a spurious \"-dirty\" suffix when building from a directory copy\n(as Mike learned the hard way)\n\n[...]\n\nhttps://public-inbox.org/git/1459432667.2124.2.camel@dwim.me \n"},{"id":"348498","messageId":"20180524230334.12452-1-michael.w.mason@intel.com","threadId":"41884","inReplyTo":"89d82c84-7a3b-9c4c-679e-a7a723669592@intel.com","subject":"Re: Wrong -dirty suffix set by setlocalversion (was: BUG in git diff-index)","fromName":"Mike Mason","fromEmail":"michael.w.mason@intel.com","sentAt":"2018-05-24T23:03:34Z","receivedAt":"2018-05-24T23:02:48Z","isPatch":false,"sender":{"key":"michael.w.mason@intel.com","avatar":null},"body":"How about something like this? It ignores attributes that should have no\nbearing on whether the kernel is considered dirty. Copied trees with no other\nchanges would no longer be marked with -dirty. Plus it works on read-only\nmedia since no index updating is required.\n\nWould this also be considered kosher, at least for the purposes of\nsetlocalversion?\n\ndiff --git a/scripts/setlocalversion b/scripts/setlocalversion\nindex 71f39410691b..9da4c5e83285 100755\n--- a/scripts/setlocalversion\n+++ b/scripts/setlocalversion\n@@ -73,8 +73,10 @@ scm_version()\n \t\t\tprintf -- '-svn%s' \"`git svn find-rev $head`\"\n \t\tfi\n \n-\t\t# Check for uncommitted changes\n-\t\tif git diff-index --name-only HEAD | grep -qv \"^scripts/package\"; then\n+\t\t# Check for uncommitted changes. Only check mtime and size.\n+       # Ignore insequential ctime, uid, gid and inode differences.\n+\t\tif git -c \"core.checkstat=minimal\" diff-index --name-only HEAD | \\\n+\t\t\t\tgrep -qv \"^scripts/package\"; then\n \t\t\tprintf '%s' -dirty\n \t\tfi\n \n"},{"id":"348513","messageId":"0dc31052-4cfd-3b92-0a4a-96c8ecfafff6@intel.com","threadId":"41884","inReplyTo":"20180524230334.12452-1-michael.w.mason@intel.com","subject":"Re: Wrong -dirty suffix set by setlocalversion (was: BUG in git diff-index)","fromName":"Marc Herbert","fromEmail":"marc.herbert@intel.com","sentAt":"2018-05-25T03:50:28Z","receivedAt":"2018-05-25T03:55:32Z","isPatch":false,"sender":{"key":"marc.herbert@intel.com","avatar":null},"body":"On 24/05/2018 16:03, Mike Mason wrote:\n\n> diff --git a/scripts/setlocalversion b/scripts/setlocalversion\n> index 71f39410691b..9da4c5e83285 100755\n> --- a/scripts/setlocalversion\n> +++ b/scripts/setlocalversion\n> @@ -73,8 +73,10 @@ scm_version()\n>  \t\t\tprintf -- '-svn%s' \"`git svn find-rev $head`\"\n>  \t\tfi\n>  \n> -\t\t# Check for uncommitted changes\n> -\t\tif git diff-index --name-only HEAD | grep -qv \"^scripts/package\"; then\n> +\t\t# Check for uncommitted changes. Only check mtime and size.\n> +       # Ignore insequential ctime, uid, gid and inode differences.\n> +\t\tif git -c \"core.checkstat=minimal\" diff-index --name-only HEAD | \\\n> +\t\t\t\tgrep -qv \"^scripts/package\"; then\n>  \t\t\tprintf '%s' -dirty\n>  \t\tfi\n\nFWIW:\n\nReported-by: Marc.Herbert@intel.com\nReviewed-by: Marc.Herbert@intel.com  (assuming a future and decent commit message)\nTested-by: Marc.Herbert@intel.com\n\n\nSo the real use case is making a copy of a whole tree before building.\nTypical in automated builds, old example:\nhttps://groups.google.com/a/chromium.org/d/msg/chromium-os-dev/zxOa0OLWFkw/N_Sb7EZOBwAJ \n\nHere's a more complex but faster and more transparent way to test Mike's fix\nthan copying an entire tree:\n\n# Make sure you start from a clean state\ngit describe --dirty      # must not -dirty\n\nmake prepare\n\n# Simulate a copy of the tree but with just one file\nrsync --perms --times  README   README.mtime_backup\nrm  README\nrsync --perms --times  README.mtime_backup   README\nstat  README  README.mtime_backup \n\n# Demo the BUG fixed by Mike\n./scripts/setlocalversion # -dirty BUG! because spurious inode ctime difference\ngit diff-index  HEAD\ngit describe --dirty      # not -dirty\n./scripts/setlocalversion # not -dirty any more cause describe refreshed index\n\n# Make sure mtime still causes -dirty with AND without Mike's fix\ntouch README\n./scripts/setlocalversion # -dirty\n"}]}