Track which files change during complex operations

When administering systems and deploying code we are often updating large numbers of files. When some of these files change as a result of deployment the implications can be time consuming so we might only want to carry out dependent actions on the server when the file actually changes. Enter my little file tracking utility. Here is the content of

Utility to track files and see if they have changed:
checkpoint(file_path) - checkpoints the file
check(file_path) - returns True if the file has not changed since last checkpoint call, False otherwise
import os
import hashlib

__all__ = ['checkpoint', 'same', 'changed']

class NotCheckpointed(Exception):

def get_info(fname):
    return canonical_fname, fhash
    canonical_fname = os.path.abspath(fname)
    with open(fname, 'rb') as f:
        fhash = hashlib.sha1(
    return canonical_fname, fhash

checks = dict()  # canonical filename: sha1 from checkpoint

def checkpoint(fname):
    (canonical_fname, fhash) = get_info(fname)
    checks[canonical_fname] = fhash
    return fhash

def same(fname):
    (canonical_fname, fhash) = get_info(fname)
        return checks[canonical_fname] == fhash
    except KeyError:
        raise NotCheckpointed

def changed(fname):
    return not same(fname)

With this utility in place, repeated calls to check allow you to verify whether a particular file has been changed or not. Here is how it is called from within a Fabric task where this deploy script only installs new requirements if the requirements.txt file has actually changed:

import utils.file_tracker as ft
def deploy():
    Deploy code update to named service and sync/migrate db
    requirements_fname = 'requirements/base.txt'
    site_root = Fab.env.site_setup.site_root

        run('find -name "*.pyc" -exec rm {} \;')
        run('git pull')

        if ft.changed(requirements_fname):



There are currently no comments

New Comment


required (not published)


Australia: 07 3103 2894

International: +61 410 545 357