From 9f52324add1a4ededc8f47d11e90216f40cab497 Mon Sep 17 00:00:00 2001 From: James Murty Date: Fri, 23 May 2014 16:20:30 +0100 Subject: Fail with a clear error if 'git fat pull' is run on uninitialised repo. This fixes issue #25 in the original project. --- git-fat | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'git-fat') diff --git a/git-fat b/git-fat index 97315ea..7a9c00d 100755 --- a/git-fat +++ b/git-fat @@ -370,6 +370,7 @@ class GitFat(object): def cmd_pull(self, args): 'Pull anything that I have referenced, but not stored' self.setup() + self.assert_init_done() refargs = dict() if '--all' in args: refargs['all'] = True @@ -414,9 +415,15 @@ class GitFat(object): fname = os.path.join(self.objdir, obj) print('%10d %s' % (os.stat(fname).st_size, obj)) os.remove(fname) + def is_init_done(self): + return gitconfig_get('filter.fat.clean') or gitconfig_get('filter.fat.smudge') + def assert_init_done(self): + if not self.is_init_done(): + print('Git fat is not yet configured in this repository, run "git fat init"') + sys.exit(1) def cmd_init(self): self.setup() - if gitconfig_get('filter.fat.clean') or gitconfig_get('filter.fat.smudge'): + if self.is_init_done(): print('Git fat already configured, check configuration in .git/config') else: gitconfig_set('filter.fat.clean', 'git-fat filter-clean') -- cgit v1.2.1 From f879d34548fe3181026d9e49bb24af1987db6892 Mon Sep 17 00:00:00 2001 From: James Murty Date: Sat, 24 May 2014 14:21:34 +0100 Subject: Moved requirement for init to `checkout` operation. Since `checkout` op is where the repo really needs to be init'ed for git-fat I moved the requirement to there. This way it is still triggered by a `pull` op, but only at the end after any files have been synced. --- git-fat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-fat') diff --git a/git-fat b/git-fat index 7a9c00d..a2b4395 100755 --- a/git-fat +++ b/git-fat @@ -352,6 +352,7 @@ class GitFat(object): sys.exit(p.returncode) def checkout(self, show_orphans=False): 'Update any stale files in the present working tree' + self.assert_init_done() for digest, fname in self.orphan_files(): objpath = os.path.join(self.objdir, digest) if os.access(objpath, os.R_OK): @@ -370,7 +371,6 @@ class GitFat(object): def cmd_pull(self, args): 'Pull anything that I have referenced, but not stored' self.setup() - self.assert_init_done() refargs = dict() if '--all' in args: refargs['all'] = True -- cgit v1.2.1 From 6ca25da37333bbffe10cbb837c0002fd250931b1 Mon Sep 17 00:00:00 2001 From: James Murty Date: Sat, 24 May 2014 21:34:01 +0100 Subject: Add `verify` command to check git-fat object data matches hash filename. While experimenting with using the --partial option with rsync I managed to corrupt one of my git-fat objects by truncating it. This caused some behaviour in git-fat which seemed odd until I worked out what had happened: it would check out the truncated data but git would see the file as modified and show the changed hash in a diff, while a re-checkout did not reset the file to its original data/hash. This commit adds a `verify` command that cross-checks git-fat object file names (the original SHA1) against the SHA1 of the object's actual data and prints any mismatches. So you can quickly find any dubious objects and decide what to do about them. A better solution might be to calcuate and verify objects' data hash during filter-smudge/checkout though this would likely hurt performance. --- git-fat | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'git-fat') diff --git a/git-fat b/git-fat index 97315ea..e5f75cc 100755 --- a/git-fat +++ b/git-fat @@ -414,6 +414,24 @@ class GitFat(object): fname = os.path.join(self.objdir, obj) print('%10d %s' % (os.stat(fname).st_size, obj)) os.remove(fname) + + def cmd_verify(self): + """Print details of git-fat objects with incorrect data hash""" + corrupted_objects = [] + for obj in self.catalog_objects(): + fname = os.path.join(self.objdir, obj) + h = hashlib.new('sha1') + for block in readblocks(open(fname)): + h.update(block) + data_hash = h.hexdigest() + if obj != data_hash: + corrupted_objects.append((obj, data_hash)) + if corrupted_objects: + print('Corrupted objects: %d' % len(corrupted_objects)) + for obj, data_hash in corrupted_objects: + print('%s data hash is %s' % (obj, data_hash)) + sys.exit(1) + def cmd_init(self): self.setup() if gitconfig_get('filter.fat.clean') or gitconfig_get('filter.fat.smudge'): @@ -539,6 +557,8 @@ if __name__ == '__main__': fat.cmd_pull(sys.argv[2:]) elif cmd == 'gc': fat.cmd_gc() + elif cmd == 'verify': + fat.cmd_verify() elif cmd == 'checkout': fat.cmd_checkout(sys.argv[2:]) elif cmd == 'find': @@ -546,4 +566,4 @@ if __name__ == '__main__': elif cmd == 'index-filter': fat.cmd_index_filter(sys.argv[2:]) else: - print('Usage: git fat [init|status|push|pull|gc|checkout|find|index-filter]', file=sys.stderr) + print('Usage: git fat [init|status|push|pull|gc|verify|checkout|find|index-filter]', file=sys.stderr) -- cgit v1.2.1 From b1af5996fd2b1fc5eb21bab2d2477095f72ffa27 Mon Sep 17 00:00:00 2001 From: Jed Brown Date: Sun, 25 May 2014 21:05:21 -0600 Subject: Print fatal error message to stderr --- git-fat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git-fat') diff --git a/git-fat b/git-fat index a2b4395..049844f 100755 --- a/git-fat +++ b/git-fat @@ -419,7 +419,8 @@ class GitFat(object): return gitconfig_get('filter.fat.clean') or gitconfig_get('filter.fat.smudge') def assert_init_done(self): if not self.is_init_done(): - print('Git fat is not yet configured in this repository, run "git fat init"') + sys.stderr.write('fatal: git-fat is not yet configured in this repository.\n') + sys.stderr.write('Run "git fat init" to configure.\n') sys.exit(1) def cmd_init(self): self.setup() -- cgit v1.2.1 From 407ae4d45b81c6f9c8bcec39a7eeff04a98d3c08 Mon Sep 17 00:00:00 2001 From: Jed Brown Date: Sun, 25 May 2014 22:47:03 -0600 Subject: Move init diagnostics out of cmd_* section --- git-fat | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'git-fat') diff --git a/git-fat b/git-fat index 7035db7..7d4e8ad 100755 --- a/git-fat +++ b/git-fat @@ -135,6 +135,13 @@ class GitFat(object): self.magiclens = [magiclen(enc) for enc in [self.encode_v1, self.encode_v2]] # All prior versions def setup(self): mkdir_p(self.objdir) + def is_init_done(self): + return gitconfig_get('filter.fat.clean') or gitconfig_get('filter.fat.smudge') + def assert_init_done(self): + if not self.is_init_done(): + sys.stderr.write('fatal: git-fat is not yet configured in this repository.\n') + sys.stderr.write('Run "git fat init" to configure.\n') + sys.exit(1) def get_rsync(self): cfgpath = os.path.join(self.gitroot,'.gitfat') remote = gitconfig_get('rsync.remote', file=cfgpath) @@ -415,13 +422,6 @@ class GitFat(object): fname = os.path.join(self.objdir, obj) print('%10d %s' % (os.stat(fname).st_size, obj)) os.remove(fname) - def is_init_done(self): - return gitconfig_get('filter.fat.clean') or gitconfig_get('filter.fat.smudge') - def assert_init_done(self): - if not self.is_init_done(): - sys.stderr.write('fatal: git-fat is not yet configured in this repository.\n') - sys.stderr.write('Run "git fat init" to configure.\n') - sys.exit(1) def cmd_verify(self): """Print details of git-fat objects with incorrect data hash""" -- cgit v1.2.1