{"id":1991,"library":"dirhash","title":"dirhash: Directory Hashing Utility","description":"dirhash is a Python module and CLI tool for computing the hash of file system directories based on their structure and content. It supports all hashing algorithms available in Python's `hashlib` module, offers `.gitignore`-style glob/wildcard path matching for filtering files, and leverages multiprocessing for performance. The library computes hashes according to the Dirhash Standard, aiming for consistent and collision-resistant directory hash generation. It is actively maintained with irregular, feature-driven releases, currently at version 0.5.0.","status":"active","version":"0.5.0","language":"python","source_language":"en","source_url":"https://github.com/andhus/dirhash-python","tags":["hashing","directory","filesystem","integrity","checksum","cli"],"install":[{"cmd":"pip install dirhash","lang":"bash","label":"Install from PyPI"}],"dependencies":[{"reason":"Required for experimental Windows support (introduced in v0.5.0).","package":"scantree","optional":false},{"reason":"Used for .gitignore-style glob/wildcard path matching.","package":"pathspec","optional":false}],"imports":[{"symbol":"dirhash","correct":"from dirhash import dirhash"}],"quickstart":{"code":"import os\nimport tempfile\nimport shutil\nfrom dirhash import dirhash\n\n# Create a temporary directory structure for demonstration\nwith tempfile.TemporaryDirectory() as tmpdir:\n    test_dir = os.path.join(tmpdir, 'my_project')\n    os.makedirs(os.path.join(test_dir, 'src'))\n    os.makedirs(os.path.join(test_dir, 'data'))\n\n    with open(os.path.join(test_dir, 'src', 'main.py'), 'w') as f:\n        f.write('print(\"Hello, dirhash!\")')\n\n    with open(os.path.join(test_dir, 'data', 'config.json'), 'w') as f:\n        f.write('{\"key\": \"value\"}')\n\n    with open(os.path.join(test_dir, '.gitignore'), 'w') as f:\n        f.write('*.json')\n\n    # Calculate the MD5 hash of the entire directory\n    full_md5_hash = dirhash(test_dir, 'md5')\n    print(f\"MD5 hash of {test_dir}: {full_md5_hash}\")\n\n    # Calculate SHA1 hash, excluding .json files using .gitignore style patterns\n    sha1_hash_no_json = dirhash(test_dir, 'sha1', ignore=['*.json'])\n    print(f\"SHA1 hash (excluding *.json): {sha1_hash_no_json}\")\n\n    # Calculate SHA256 hash, only including .py files\n    sha256_hash_only_py = dirhash(test_dir, 'sha256', match=['*.py'])\n    print(f\"SHA256 hash (only *.py): {sha256_hash_only_py}\")\n\n    # Demonstrate including empty directories (default is to exclude if no content included by filters)\n    # First, a hash without explicitly including empty dirs\n    empty_dir_path = os.path.join(test_dir, 'empty_folder')\n    os.makedirs(empty_dir_path)\n    hash_without_empty = dirhash(test_dir, 'md5')\n    print(f\"MD5 hash (without explicit empty dirs): {hash_without_empty}\")\n    # Now, a hash explicitly including empty dirs\n    hash_with_empty = dirhash(test_dir, 'md5', empty_dirs=True)\n    print(f\"MD5 hash (with empty dirs): {hash_with_empty}\")\n\n    # Cleanup is handled by TemporaryDirectory\n","lang":"python","description":"This quickstart demonstrates how to compute directory hashes using different algorithms and filtering options (`match` and `ignore` for `.gitignore` style patterns) using the `dirhash` function. It also shows the effect of including empty directories."},"warnings":[{"fix":"Review and test any existing directory hashing logic, especially those relying on `match` or `ignore` patterns, to ensure the new `.gitignore`-aligned behavior is as expected.","message":"The `pathspec` dependency's upper version limit was removed in `v0.4.0`. This change means that `dirhash` now uses `pathspec` versions greater than `0.10.0`. This update alters how some match/ignore patterns are treated, aligning behavior with `.gitignore` standards. Users upgrading from `v0.3.0` or earlier might observe different hash results for directories with complex filtering patterns.","severity":"breaking","affected_versions":">=0.4.0"},{"fix":"Users migrating from `v0.1.x` versions must thoroughly review the API and expected hash outputs against the new 'Dirhash Standard' implementation in `v0.2.0` and later.","message":"Version `0.2.0` introduced 'significant breaking changes' from `v0.1.1`, primarily by adopting the formal 'Dirhash Standard'. This was a fundamental re-implementation that likely affected API calls and internal hash calculation logic.","severity":"breaking","affected_versions":">=0.2.0"},{"fix":"Ensure your project is running on Python 3.8 or a newer compatible version.","message":"Python 2.7 support was officially dropped in version `0.3.0`. The library now requires Python 3.8 or newer.","severity":"deprecated","affected_versions":">=0.3.0"},{"fix":"Report any Windows-specific issues to the project's GitHub repository. Consider thorough testing on Windows environments before using in production.","message":"Windows support in `v0.5.0` is marked as 'experimental'. While `scantree>=0.0.4` was added for this purpose, users on Windows platforms may encounter platform-specific issues.","severity":"gotcha","affected_versions":"0.5.0"},{"fix":"Carefully configure `empty_dirs`, `no_linked_dirs`, `no_linked_files`, `allow_cyclic_links`, and `properties` arguments to precisely define what should be included in the hash, especially in environments with complex file structures or symbolic links. Refer to the 'Dirhash Standard' documentation for detailed behavior.","message":"The default behavior regarding symbolic links, empty directories, and which file/directory properties (`name`, `data`, `is_link`) are included in the hash can significantly impact the resulting hash. Misunderstanding these options can lead to inconsistent or unexpected hash values. By default, `name` and `data` are included, but `is_link` is not.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"search_vec":"'0.5.0':84 'accord':56 'activ':73 'aim':61 'algorithm':31 'avail':32 'base':21 'checksum':89 'cli':11,90 'collis':66 'collision-resist':65 'comput':14,54 'consist':63 'content':26 'current':81 'directori':2,20,68,86 'dirhash':1,5,59 'driven':79 'featur':78 'feature-driven':77 'file':18,46 'filesystem':87 'filter':45 'generat':70 'gitignor':39 'glob/wildcard':41 'hash':3,16,30,55,69,85 'hashlib':36 'integr':88 'irregular':76 'leverag':48 'librari':53 'maintain':74 'match':43 'modul':9,37 'multiprocess':49 'offer':38 'path':42 'perform':51 'python':8,34 'releas':80 'resist':67 'standard':60 'structur':24 'style':40 'support':28 'system':19 'tool':12 'util':4 'version':83","created_at":"2026-04-09T18:38:51.422056+00:00","updated_at":"2026-04-16T14:25:49.779673+00:00","problems":[{"fix":"pip install dirhash","cause":"The 'dirhash' library is not installed in the Python environment.","error":"ModuleNotFoundError: No module named 'dirhash'"},{"fix":"dirhash /path/to/directory","cause":"The command-line interface (CLI) for dirhash was called without specifying the target directory to hash.","error":"dirhash: error: the following arguments are required: directory"},{"fix":"Use a valid hashing algorithm from Python's hashlib, such as 'md5', 'sha1', 'sha256', 'sha512', etc.\nExample: dirhash('/path/to/directory', 'sha256')","cause":"An invalid or unsupported hashing algorithm was provided to the `dirhash` function or CLI via the `-a` or `--algorithm` argument.","error":"ValueError: Unsupported hashing algorithm: 'invalid_algo'"},{"fix":"Ensure the user running `dirhash` has read permissions for all files and directories within the target path, or use the `ignore` argument (e.g., `--ignore 'path/to/inaccessible_dir/*'` in CLI or `ignore=['path/to/inaccessible_dir/*']` in Python) to exclude the inaccessible paths.","cause":"The `dirhash` tool or function attempted to access a directory or file for which the current user lacks read permissions. This can also occur if a directory is not accessible and not explicitly excluded by filtering options.","error":"PermissionError: [Errno 13] Permission denied: '/path/to/inaccessible_file_or_dir'"},{"fix":"Always enclose glob/wildcard patterns in quotes when using them with `dirhash` on the command line.\nExample: dirhash path/to/directory --match \"*.py\"","cause":"When using glob/wildcard patterns (like `*`) in the command line without quotes, the shell expands the pattern before `dirhash` receives it, leading to incorrect arguments or a syntax error if multiple files match.","error":"SyntaxError: invalid syntax (from shell when using unquoted glob patterns)"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.5.0","cli_name":"dirhash","cli_version":"dirhash 0.5.0","type":"library","homepage":null,"github":"https://github.com/andhus/dirhash-python","docs":null,"changelog":null,"pypi":"https://pypi.org/project/dirhash/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["devops","data","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}