{"thread":{"id":"22215","subject":"touching a file causes it to be listed using git diff-files","startedAt":"2010-01-13T23:57:28Z","lastAt":"2010-01-14T06:39:39Z","messageCount":6,"participants":["Stephen Bannasch","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"131551","messageId":"p0624080ec7740ddc4caf@[63.138.152.134]","threadId":"22215","inReplyTo":null,"subject":"touching a file causes it to be listed using git diff-files","fromName":"Stephen Bannasch","fromEmail":"stephen.bannasch@deanbrook.org","sentAt":"2010-01-13T23:57:28Z","receivedAt":"2010-01-13T23:57:28Z","isPatch":false,"sender":{"key":"stephen.bannasch@deanbrook.org","avatar":null},"body":"If I touch a file in the working directory (only changing it's last-modified) attribute it shows up when running git diff-files.\n\nIf I then run git status followed by git diff-files again it doesn't show up either time.\n\nIs this an error?\n\nSimple example:\n\n[dev]$ git --version\ngit version 1.6.5.3\n\n[dev]$ git init t\nInitialized empty shared Git repository in /Users/stephen/dev/t/.git/\n\n[dev]$ cd t\n[t (master)]$ echo 'hi' > hello; git add hello; git commit -am 'initial commit'\n[master (root-commit) f39d21a] initial commit\n  1 files changed, 1 insertions(+), 0 deletions(-)\n  create mode 100644 hello\n\n[t (master)]$ git diff-files\n\n[t (master)]$ git status\n# On branch master\nnothing to commit (working directory clean)\n\n[t (master)]$ touch hello\n\n[t (master)]$ git diff-files\n:100644 100644 45b983be36b73c0788dc9cbcb76cbb80fc7bb057 0000000000000000000000000000000000000000 M      hello\n\n[t (master)]$ git status\n# On branch master\nnothing to commit (working directory clean)\n\n[t (master)]$ git diff-files\n"},{"id":"131575","messageId":"20100114030204.GB1878@coredump.intra.peff.net","threadId":"22215","inReplyTo":"p0624080ec7740ddc4caf@[63.138.152.134]","subject":"Re: touching a file causes it to be listed using git diff-files","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-14T03:02:04Z","receivedAt":"2010-01-14T03:02:04Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jan 13, 2010 at 06:57:28PM -0500, Stephen Bannasch wrote:\n\n> If I touch a file in the working directory (only changing it's last-modified) attribute it shows up when running git diff-files.\n> \n> If I then run git status followed by git diff-files again it doesn't show up either time.\n> \n> Is this an error?\n\nNo. For performance reasons[1], plumbing commands like diff-files do not\nupdate the index. You must run \"git update-index --refresh\" manually.\n\nUser-facing porcelain commands like \"git diff\" and \"git status\" will\nrefresh the index automatically. So \"git status\" will, as a side effect,\nrefresh the index and impact further calls to diff-files.\n\n-Peff\n\n[1] Refreshing the index needs to stat all of the files. If you are\nwriting a script using plumbing commands, you probably want to do the\npossibly-expensive refresh once at the start of your script, and then\nissue many diff commands. This makes a lot of sense for \"diff-index\",\nwhich otherwise does not need to touch the working tree at all. I'm not\nsure how much it helps with diff-files, though, which clearly ends up\nstat'ing the working tree file anyway.\n"},{"id":"131577","messageId":"p06240810c774498d4a2e@[63.138.152.134]","threadId":"22215","inReplyTo":"20100114030204.GB1878@coredump.intra.peff.net","subject":"Re: touching a file causes it to be listed using git diff-files","fromName":"Stephen Bannasch","fromEmail":"stephen.bannasch@deanbrook.org","sentAt":"2010-01-14T05:01:46Z","receivedAt":"2010-01-14T05:01:46Z","isPatch":false,"sender":{"key":"stephen.bannasch@deanbrook.org","avatar":null},"body":"At 10:02 PM -0500 1/13/10, Jeff King wrote:\n>On Wed, Jan 13, 2010 at 06:57:28PM -0500, Stephen Bannasch wrote:\n>\n>> If I touch a file in the working directory (only changing it's last-modified) attribute it shows up when running git diff-files.\n>>\n>> If I then run git status followed by git diff-files again it doesn't show up either time.\n>>\n>> Is this an error?\n>\n>No. For performance reasons[1], plumbing commands like diff-files do not\n>update the index. You must run \"git update-index --refresh\" manually.\n>\n>User-facing porcelain commands like \"git diff\" and \"git status\" will\n>refresh the index automatically. So \"git status\" will, as a side effect,\n>refresh the index and impact further calls to diff-files.\n>\n>-Peff\n>\n>[1] Refreshing the index needs to stat all of the files. If you are\n>writing a script using plumbing commands, you probably want to do the\n>possibly-expensive refresh once at the start of your script, and then\n>issue many diff commands. This makes a lot of sense for \"diff-index\",\n>which otherwise does not need to touch the working tree at all. I'm not\n>sure how much it helps with diff-files, though, which clearly ends up\n>stat'ing the working tree file anyway.\n\nJeff,\n\nThanks for that explanation.\n\nDo you know if there is a plumbing command that will stat all of the files without listing the files that actually do need updating?\n\nIn the case where file1 has been only touched but file2 has been changed (and both are tracked) I'd like to stat both filesand then run diff-files as plumbing to see that only file2 has been changed in the working directory.\n\n'git diff' also stats the files but strangely 'git diff --quiet' doesn't ???\n\nIn this example .snarfit.yml has real changes.\n\n  $ touch nowebdb.cs\n\n  $ git diff-files\n  :100644 100644 22dab3b1c864d808da4d2be40196250ba879f68f 0000000000000000000000000000000000000000 M      .snarfit.yml\n  :100644 100644 57982f13c69a91e3341d5b06021d31944633b5a3 0000000000000000000000000000000000000000 M      nowebdb.css\n\n  $ git diff --quiet\n\n  $ git diff-files\n  :100644 100644 22dab3b1c864d808da4d2be40196250ba879f68f 0000000000000000000000000000000000000000 M      .snarfit.yml\n  :100644 100644 57982f13c69a91e3341d5b06021d31944633b5a3 0000000000000000000000000000000000000000 M      nowebdb.css\n\n  $ git diff --shortstat\n   1 files changed, 2 insertions(+), 2 deletions(-)\n\n  $ git diff-files\n  :100644 100644 22dab3b1c864d808da4d2be40196250ba879f68f 0000000000000000000000000000000000000000 M      .snarfit.yml\n\nI thought adding '-q' to update-index would cause it to run quietly but that is not the case:\n\n  $ git diff-files\n  :100644 100644 22dab3b1c864d808da4d2be40196250ba879f68f 0000000000000000000000000000000000000000 M      .snarfit.yml\n  :100644 100644 57982f13c69a91e3341d5b06021d31944633b5a3 0000000000000000000000000000000000000000 M      nowebdb.css\n\n  $ git update-index --refresh -q\n  .snarfit.yml: needs update\n\n  $ git diff-files\n  :100644 100644 22dab3b1c864d808da4d2be40196250ba879f68f 0000000000000000000000000000000000000000 M      .snarfit.yml\n"},{"id":"131580","messageId":"20100114052658.GA13973@coredump.intra.peff.net","threadId":"22215","inReplyTo":"p06240810c774498d4a2e@[63.138.152.134]","subject":"Re: touching a file causes it to be listed using git diff-files","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-14T05:26:58Z","receivedAt":"2010-01-14T05:26:58Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 14, 2010 at 12:01:46AM -0500, Stephen Bannasch wrote:\n\n> Do you know if there is a plumbing command that will stat all of the\n> files without listing the files that actually do need updating?\n> \n> In the case where file1 has been only touched but file2 has been\n> changed (and both are tracked) I'd like to stat both filesand then run\n> diff-files as plumbing to see that only file2 has been changed in the\n> working directory.\n\nJudging from the scripts in git itself, I think the recommended practice\nis to simply \"git update-index --refresh -q >/dev/null\".\n\n> 'git diff' also stats the files but strangely 'git diff --quiet' doesn't ???\n\nI can't reproduce that behavior here on the current \"master\". Old\nversions of git used to not do the index refresh for \"diff\". What\nversion of git are you using?\n\n-Peff\n"},{"id":"131603","messageId":"p06240813c77462aa2cfb@[63.138.152.134]","threadId":"22215","inReplyTo":"20100114052658.GA13973@coredump.intra.peff.net","subject":"Re: touching a file causes it to be listed using git diff-files","fromName":"Stephen Bannasch","fromEmail":"stephen.bannasch@deanbrook.org","sentAt":"2010-01-14T05:57:05Z","receivedAt":"2010-01-14T05:57:05Z","isPatch":false,"sender":{"key":"stephen.bannasch@deanbrook.org","avatar":null},"body":"At 12:26 AM -0500 1/14/10, Jeff King wrote:\n>On Thu, Jan 14, 2010 at 12:01:46AM -0500, Stephen Bannasch wrote:\n>\n>> Do you know if there is a plumbing command that will stat all of the\n>> files without listing the files that actually do need updating?\n>>\n>> In the case where file1 has been only touched but file2 has been\n>> changed (and both are tracked) I'd like to stat both filesand then run\n>> diff-files as plumbing to see that only file2 has been changed in the\n>> working directory.\n>\n>Judging from the scripts in git itself, I think the recommended practice\n>is to simply \"git update-index --refresh -q >/dev/null\".\n>\n>> 'git diff' also stats the files but strangely 'git diff --quiet' doesn't ???\n>\n>I can't reproduce that behavior here on the current \"master\". Old\n>versions of git used to not do the index refresh for \"diff\". What\n>version of git are you using?\n\nThe most recent test was on:\n\n$ git --version\ngit version 1.6.6\n"},{"id":"131604","messageId":"20100114063939.GA17565@coredump.intra.peff.net","threadId":"22215","inReplyTo":"p06240813c77462aa2cfb@[63.138.152.134]","subject":"Re: touching a file causes it to be listed using git diff-files","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-14T06:39:39Z","receivedAt":"2010-01-14T06:39:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 14, 2010 at 12:57:05AM -0500, Stephen Bannasch wrote:\n\n> >> 'git diff' also stats the files but strangely 'git diff --quiet' doesn't ???\n> >\n> >I can't reproduce that behavior here on the current \"master\". Old\n> >versions of git used to not do the index refresh for \"diff\". What\n> >version of git are you using?\n> \n> The most recent test was on:\n> \n> $ git --version\n> git version 1.6.6\n\nAh, OK, I figured it out. It is due to the early return of \"--quiet\".\nSince we know we are simply returning a status of \"all the same\" or \"at\nleast one difference\", we can quit after finding the first difference.\n\nSo if you have two files, \"a\" and \"b\", you can try:\n\n  $ touch a\n  $ echo changes >b\n  $ git diff --quiet\n  $ git diff-files\n\nand you will see that 'a' has been updated, because we traverse the\nfiles in sorted order and quit only after seeing 'b'.\n\nBut if you do instead:\n\n  $ touch b\n  $ echo change >a\n  $ git diff --quiet\n  $ git diff-files\n\nwe quit after 'a' and never refresh 'b'.\n\nI don't think it should be considered a bug, though. \"git diff\" produces\nthe correct result, and it is under no obligation to produce its side\neffect. If a caller really wants the index refreshed, he should use\nupdate-index instead.\n\n-Peff\n"}]}