{"id":26993914,"url":"https://github.com/agarwalvishal/verifycopy","last_synced_at":"2026-05-05T21:33:32.707Z","repository":{"id":286023004,"uuid":"960090871","full_name":"agarwalvishal/verifycopy","owner":"agarwalvishal","description":"A lightweight shell script to verify successful file and folder copies by comparing path, size, and optional timestamps.","archived":false,"fork":false,"pushed_at":"2025-04-04T04:47:13.000Z","size":20,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T16:53:43.552Z","etag":null,"topics":["backup","copy-validation","file-check","macos","shell","utility","verification","zsh"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agarwalvishal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-04-03T21:00:41.000Z","updated_at":"2025-04-04T16:49:48.000Z","dependencies_parsed_at":"2025-04-09T16:44:19.036Z","dependency_job_id":null,"html_url":"https://github.com/agarwalvishal/verifycopy","commit_stats":null,"previous_names":["agarwalvishal/verifycopy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/agarwalvishal/verifycopy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agarwalvishal%2Fverifycopy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agarwalvishal%2Fverifycopy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agarwalvishal%2Fverifycopy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agarwalvishal%2Fverifycopy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agarwalvishal","download_url":"https://codeload.github.com/agarwalvishal/verifycopy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agarwalvishal%2Fverifycopy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32669431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup","copy-validation","file-check","macos","shell","utility","verification","zsh"],"created_at":"2025-04-04T00:19:29.507Z","updated_at":"2026-05-05T21:33:32.700Z","avatar_url":"https://github.com/agarwalvishal.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# verifycopy.zsh\n\nA clean, reliable shell script to verify whether files and folders were completely and correctly copied from a source to a destination directory — including subdirectories and hidden files.\n\nDesigned for **post-copy sanity checking**: useful after backups, manual drag-and-drop transfers, SD card dumps, or Android file transfers.\n\n---\n\n## What This Script Does\n\n- Recursively compares all files (including hidden ones) between source and destination\n- Compares:\n  - Relative file paths\n  - File sizes (in bytes)\n  - (Optionally) file modification timestamps\n- Detects:\n  - Files missing in the destination\n  - Extra files in the destination\n  - Files with same path but different size or timestamp (marked as changed)\n- Skips:\n  - macOS AppleDouble files (`._*`) that contain metadata but not actual file content\n  - `.DS_Store` files — macOS Finder metadata that clutters directories but has no user data\n- Outputs:\n  - A **color-coded summary** in terminal\n  - A detailed **diff-style log** saved as `verifycopy_diff_output.txt` in the script directory\n\n---\n\n## Why AppleDouble Files (`._*`) Are Excluded\n\nWhen copying to non-macOS file systems (e.g. FAT32, exFAT, NTFS, SMB), macOS generates `._*` files — known as **AppleDouble files** — to store extended metadata like:\n\n- Finder tags and labels\n- Custom icons\n- Resource forks\n\nThese files are not user content, are invisible on macOS, and often confuse verification.  \nThis script **excludes them by default**, ensuring they don't pollute the results.  \nNormal dotfiles (like `.bashrc`, `.config`) are **not affected** and are fully included.\n\n---\n\n## Why Timestamp Checking Matters\n\nTimestamps detect changes that file size cannot — for example:\n\n- File was edited but size didn't change\n  - In real-world edits, file size can remain the same (e.g., a text file is edited but eventually it contains the same number of characters and therefore has the same size), but timestamp can change — enabling timestamp check helps detect such changes reliably without needing checksums.\n- File was re-encoded or touched\n- File was modified during sync\n\n**Timestamp comparison is optional** because some copy methods don’t preserve timestamps.\n\n### When to Enable Timestamp Checks\n\n\u003e Enable when:\n\u003e\n\u003e - You used reliable methods that preserve timestamps\n\u003e - You want to ensure copied files weren’t modified after transfer\n\n### When to Disable Timestamp Checks\n\n\u003e Disable when:\n\u003e\n\u003e - You copied via MTP, browser, or plain `cp`\n\u003e - You want to avoid false positives due to timestamp differences\n\n**Recommendation:** Enable timestamp checks unless you know your copy tool strips them\n\n---\n\n## Reference: Copy Methods and Timestamps\n\n### Copy Methods That Preserve Timestamps\n\n| Method                     | Preserves Timestamps |\n|----------------------------|----------------------|\n| `rsync -a`, `rsync -av`    | ✅ Yes               |\n| `cp -p`, `cp -a`           | ✅ Yes               |\n| macOS Finder (drag \u0026 drop) | ✅ Yes               |\n\n### Copy Methods That Strip Timestamps\n\n| Method / Tool                 | Preserves Timestamps |\n|-------------------------------|----------------------|\n| `cp` (without `-p`)           | ❌ No                |\n| Web/browser downloads         | ❌ No                |\n| Android MTP transfer          | ❌ No                |\n| Some network (SMB/NFS) shares | ❌ No                |\n\n---\n\n## What This Script Does Not Do\n\nWhile `verifycopy.zsh` is ideal for most real-world usage, it does **not** perform full content-level validation. Specifically:\n\n- It does **not** compare actual file contents (no hashing or checksums)\n- It does **not** verify file permissions, symlinks, or extended attributes\n- It does **not** detect bit-level corruption when size and timestamp are identical\n\nIf you need full integrity verification, use `rsync` with checksums (see next section).\n\n---\n\n## Why Not Just Use rsync?\n\nWhile `rsync` is a powerful tool that can detect missing or changed files — and even verify content with checksums — this script exists because:\n\n| Feature / Need                            | `verifycopy.zsh` ✅ | `rsync` (with `--dry-run`) |\n|-------------------------------------------|----------------------|-----------------------------|\n| Designed purely for **post-copy verification** | ✅ Yes              | ❌ No (sync-focused)        |\n| Fully **read-only**, always safe          | ✅ Yes              | ⚠️ Only with `--dry-run`    |\n| Clear, **human-readable summary**         | ✅ Yes              | ❌ No (cryptic output)      |\n| Detects **extras in destination**         | ✅ Yes              | ❌ No (requires complex setup) |\n| Color-coded terminal output               | ✅ Yes              | ❌ No                       |\n| Logs to diff-style file                   | ✅ Yes              | ❌ No                       |\n| Skips macOS `._*` clutter automatically   | ✅ Yes              | ⚠️ Only with `--exclude='._*'` |\n| Supports **timestamp optionality**        | ✅ Yes              | ✅ Yes (`--size-only`)      |\n| Supports **checksum-based comparison**    | ❌ No               | ✅ Yes (`-c`)               |\n\nIf you need full bit-level verification (e.g. for archives or production systems), use:\n\n```bash\nrsync -avc --dry-run --exclude='._*' /source/ /destination/\n```\n\nBut for day-to-day safety checks after copying files, `verifycopy.zsh` is faster, simpler, and safer to use.\n\n---\n\n## Installation\n\n### Clone the Script\n\n```bash\ngit clone https://github.com/agarwalvishal/verifycopy.git ~/Tools/verifycopy\ncd ~/Tools/verifycopy\nchmod +x verifycopy.zsh\n```\n\n### Create a Symlink to Run It Anywhere\n\n```bash\nln -s ~/Tools/verifycopy/verifycopy.zsh /usr/local/bin/verifycopy\n```\n\nYou can now run:\n\n```bash\nverifycopy\n```\n\n---\n\n## Usage\n\nRun the script:\n\n```bash\nverifycopy\n```\n\nThen:\n\n- Enter the source folder path\n- Enter the destination folder path\n- Choose whether to compare timestamps\n\nAfter scanning and comparing, a diff log is saved as:\n\n```bash\n~/Tools/verifycopy/verifycopy_diff_output.txt\n```\n\n---\n\n## Uninstalling\n\nTo remove the command:\n\n```bash\nrm /usr/local/bin/verifycopy\n```\n\nTo delete the script and diff output:\n\n```bash\nrm -rf ~/Tools/verifycopy\n```\n\n---\n\n## Summary\n\n`verifycopy.zsh` is a focused tool that answers a simple but critical question:\n\n\u003e \"Did all my files copy correctly?\"\n\n- It verifies the success of manual file copies and provides peace of mind before deleting original files and helps catch skips, overwrites, or modifications.\n- It’s designed to give you fast, trustworthy feedback — without needing to understand `rsync`, parse obscure flags, or risk overwriting data.\n- Use it confidently for backups, file migrations, or post-transfer validation when bit-level hashing is overkill.\n\n---\n\n## Test Coverage\n\nThis script is backed by an automated test suite covering all meaningful file copy edge cases — including missing files, size mismatches, timestamp-only differences, and known safe exclusions.\n\n👉 [View the full test coverage matrix here](./TEST_COVERAGE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagarwalvishal%2Fverifycopy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagarwalvishal%2Fverifycopy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagarwalvishal%2Fverifycopy/lists"}