diff options
author | Tyler Cipriani <tcipriani@wikimedia.org> | 2018-08-20 17:35:45 -0600 |
---|---|---|
committer | Tyler Cipriani <tcipriani@wikimedia.org> | 2018-08-20 17:35:45 -0600 |
commit | 2fad58fd0631ed8dcb77358bb9b80e4cd091d3fe (patch) | |
tree | 8230cf85d4af34c5b5376302d7883850293b330f | |
parent | 75fb63d034878cc5be2d4339e52bb6b6983d0626 (diff) | |
download | git-fat-2fad58fd0631ed8dcb77358bb9b80e4cd091d3fe.tar.gz |
Invalidate git index cache before smudging
Occasionally we hit the problem where a git smudge filter is not
triggered -- for instance, when a file in a working tree's lstat info
matches the file in the git index cache. (see racy-git.txt in the git
documentation)
The previous work-around was touching the git-fat file; however, in
cases where git fat checkout is automated there is a chance that
touching the file will make no modification to the lstat information
(when a touch happens in the same second as a git checkout). In those
instances, git will not trigger the smudge filter and the file in the
checkout will remain orphaned.
We can work around this by ensuring that the timestamp on a file is
modified by looking at its previous timestamp and adding 1 to it.
-rwxr-xr-x | git-fat | 17 |
1 files changed, 12 insertions, 5 deletions
@@ -412,11 +412,18 @@ class GitFat(object): # the file in .git/fat/objects, but git caches the file stat # from the previous time the file was smudged, therefore it # won't try to re-smudge. I don't know a git command that - # specifically invalidates that cache, but touching the file - # also does the trick. - os.utime(fname, None) - # This re-smudge is essentially a copy that restores permissions. - subprocess.check_call(['git', 'checkout-index', '--index', '--force', fname]) + # specifically invalidates that cache, but changing the mtime + # on the file will invalidate the cache. + # Here we set the mtime to mtime + 1. This is an improvement + # over touching the file as it catches the edgecase where a + # git-checkout happens within the same second as a git fat + # checkout. + stat = os.lstat(fname) + os.utime(fname, (stat.st_atime, stat.st_mtime + 1)) + # This re-smudge is essentially a copy that restores + # permissions. + subprocess.check_call( + ['git', 'checkout-index', '--index', '--force', fname]) elif show_orphans: print('Data unavailable: %s %s' % (digest,fname)) def cmd_pull(self, args): |