summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Cipriani <tcipriani@wikimedia.org>2018-08-20 17:35:45 -0600
committerTyler Cipriani <tcipriani@wikimedia.org>2018-08-20 17:35:45 -0600
commit2fad58fd0631ed8dcb77358bb9b80e4cd091d3fe (patch)
tree8230cf85d4af34c5b5376302d7883850293b330f
parent75fb63d034878cc5be2d4339e52bb6b6983d0626 (diff)
downloadgit-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-xgit-fat17
1 files changed, 12 insertions, 5 deletions
diff --git a/git-fat b/git-fat
index 99facf6..135f4e2 100755
--- a/git-fat
+++ b/git-fat
@@ -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):