On do, 2015-07-09 at 10:56 -0700, Junio C Hamano wrote: > Dennis Kaarsemaker <dennis@xxxxxxxxxxxxxxx> writes: > > > I'm seeing some behaviour with git reset that I find odd. Basically if I > > do > > > > git fetch && \ > > git reset --hard simple-tag-that-points-to-the-current-commit > > > > sometimes the reset will update the mtime of all files and directories > > in the repo and sometimes it will leave them alone. Changing it to > > > > git fetch && \ > > git status && \ > > git reset --hard simple-tag-that-points-to-the-current-commit > > > > Cause the mtime update to reliably not happen. > > If my theory on what is happening is correct, I do not think there > is any bug in what "reset --hard" is doing. > > My theory is that something is causing the stat info that is cached > in your index and the lstat(2) return you get from your working tree > files go out of sync. Even though you are not actively touching any > working tree files (otherwise, you wouldn't be complaining about > mtime changing in the first place), perhaps your build of Git > records timestamps in NS but your filesystem and the operating > system does not preserve nanosecond resolution of timestamps when it > evicts inode data from the core, or something like that? If that is > what is happening, I think that "fetch" is a red herring, but any > operation that takes some time and/or hits filesystem reasonably > hard would trigger it. > > And the reason why I say there is no bug in what "reset --hard" is > doing here, if the above theory is correct, is because: > > - The user asked "reset --hard" to "make sure that my working tree > files are identical to those of HEAD"; > > - "reset --hard" looks at lstat(2) return and the cached stat info > in the index and find them not to match. It can do one of two > things: > > (1) see if the user did something stupid, like "touch file", that > modifies only lstat(2) info without actually changing its > contents, by reading from the working tree, reading HEAD:file > from the object database, and comparing them, and overwrite > the working tree file only when they do not match. > > or > > (2) the contents might happen to be the same, but the end result > user desires to have is that the contents of the working tree > file is the same as that from the HEAD, so overwrite it > without wasting time reading two and compare before doing so. > > and it is perfectly reasonable to do the latter. After all, the > whole point of having its cached lstat(2) data in the index is to > so that we do not have to always compare the contents before > deciding something has changed in the working tree. > > Running "git update-index --refresh" immediately before "reset" may > alleviate the issue. "git status" has the same effect, only because > it does "update-index --refresh" at the beginning of its processing, > but it wastes a lot more time and resource doing other things. > > But unless/until you know _why_ the cached stat info in your index > goes stale relative to what lstat(2) tells you, it would not "solve" > it, because that magical thing (and my theory is cached data in your > operating system that keeps a file timestamp with more precision > than your underlying filesystem can represent is being flushed, and > reading the file timestamp back from the disk has to truncate the > nanoseconds part) can happen at any time between the "--refresh" and > your "reset". Thanks Junio! If I understand you correctly, reset should not touch files if it thinks they are up-to-date, so at least that assumption is safe to make. I'll test your theory about why reset thinks all the files are outdated. I did notice 'fetch' updates the index (well, mtime of .git/index changes, I didn't look at index content yet), so maybe fetch isn't quite a red herring. I'll try to eliminate this variable as well. -- Dennis Kaarsemaker www.kaarsemaker.net -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html