Repository Diff
Compare two repository snapshots and produce deterministic added, removed, and modified file changes.
Implement diff_repositories(old_files, new_files), a deterministic file-level diff between two repository snapshots.
Requirements
- Inputs are dictionaries from path to content hash.
- Return a list of
(status, path)pairs. - Status must be
"ADDED","REMOVED", or"MODIFIED". - Unchanged files must not appear.
- Output must be sorted by path. At most one event is emitted per path, so a secondary status sort never changes order.
- Treat renames as remove plus add.
- Raise
ValueErrorfor invalid paths with empty segments,.segments, or..traversal (validate keys in bothold_filesandnew_files). - Leave
old_filesandnew_filesunchanged.
Example
README.md is present with the same hash in both snapshots, so it produces no row. src/app.py changes hash, and src/test.py appears only in the new snapshot:
1old = {"README.md": "a", "src/app.py": "1"}
2new = {"README.md": "a", "src/app.py": "2", "src/test.py": "3"}
3
4assert diff_repositories(old, new) == [
5 ("MODIFIED", "src/app.py"),
6 ("ADDED", "src/test.py"),
7]Decide by path presence before comparing values. An empty string is still a supplied hash label; it doesn't mean that a file is missing.
| Path in old? | Path in new? | Hash comparison | Result |
|---|---|---|---|
| No | Yes | No old value | ADDED |
| Yes | No | No new value | REMOVED |
| Yes | Yes | Different | MODIFIED |
| Yes | Yes | Equal | No event |
For old={"old.py": "same"} and new={"new.py": "same"}, predict the output order. It is [("ADDED", "new.py"), ("REMOVED", "old.py")]: the hash match doesn't preserve path identity, and sorting follows the path rather than the status. Validate paths even when their hashes are equal; an unchanged invalid path is still an invalid input.
Constraints
- Keep the implementation deterministic.
- Use the provided content hashes directly.
- Matching content hashes indicate unchanged content only within this exercise; authenticity requires a trusted hash algorithm and trusted snapshot roots.
- Don't try to infer renames unless a follow-up asks for it.