{"id":35225771,"url":"https://github.com/vegardit/copycat","last_synced_at":"2026-04-01T17:38:03.838Z","repository":{"id":36955326,"uuid":"316784891","full_name":"vegardit/copycat","owner":"vegardit","description":"Copycat is a cross-platform one-way file synchronization tool for local file systems similar to robocopy on Windows.","archived":false,"fork":false,"pushed_at":"2026-03-18T16:54:41.000Z","size":659,"stargazers_count":40,"open_issues_count":2,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-19T06:12:18.349Z","etag":null,"topics":["backup","cli","command-line-tool","cross-platform","filesync","graalvm-native-image","java","linux","macos","robocopy","windows"],"latest_commit_sha":null,"homepage":"https://buymeacoffee.com/vegardit","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vegardit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-11-28T17:21:07.000Z","updated_at":"2026-03-18T16:49:13.000Z","dependencies_parsed_at":"2023-12-26T15:50:45.610Z","dependency_job_id":"fcd8755a-a4de-4b93-8aff-0a368fbe4b59","html_url":"https://github.com/vegardit/copycat","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/vegardit/copycat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fcopycat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fcopycat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fcopycat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fcopycat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vegardit","download_url":"https://codeload.github.com/vegardit/copycat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fcopycat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: 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","cli","command-line-tool","cross-platform","filesync","graalvm-native-image","java","linux","macos","robocopy","windows"],"created_at":"2025-12-30T01:05:21.537Z","updated_at":"2026-04-01T17:38:03.829Z","avatar_url":"https://github.com/vegardit.png","language":"Java","readme":"# copycat - the fast and sweet file syncing tool\n\n[![Build Status](https://github.com/vegardit/copycat/workflows/Build/badge.svg \"GitHub Actions\")](https://github.com/vegardit/copycat/actions?query=workflow%3A%22Build%22)\n[![Download](https://img.shields.io/badge/Download-latest-orange.svg)](https://github.com/vegardit/copycat/releases/tag/latest)\n[![License](https://img.shields.io/github/license/vegardit/copycat.svg?color=blue\u0026label=License)](LICENSE.txt)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v3.0%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)\n\n1. [What is it?](#what-is-it)\n1. [Installation](#installation)\n1. [Quick Start](#quick-start)\n1. [Usage](#usage)\n   1. [`sync` command](#sync)\n   1. [`watch` command](#watch)\n   1. [Filters: including/excluding files](#filters)\n1. [Contributing](#contributing)\n1. [License](#license)\n\n\n## \u003ca name=\"what-is-it\"\u003e\u003c/a\u003eWhat is it?\n\nCopycat is a cross platform file synchronization tool for local file systems similar to [robocopy](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy) for Windows.\n\nIt's written in Java but compiled to native binaries for Windows/Linux/MacOS using the [GraalVM - Community Edition](https://graalvm.org).\n\n![screen](src/site/img/screen1.png)\n\n![screen](src/site/img/screen2.png)\n\nAdvantages over robocopy:\n- exclude files/folders using relative paths and glob patterns\n- cross-platform support\n- ANSI-colored, concise console output\n- Desktop notifications and tray icon on major sync events\n- YAML config for defaults and multiple tasks\n- Date/time filters (`--since`, `--before`, `--until`) with natural language support\n\n\n## \u003ca name=\"installation\"\u003e\u003c/a\u003eInstallation\n\nFor Windows/Linux/macOS, self-contained single-file binaries can be downloaded at https://github.com/vegardit/copycat/releases/latest\n\nNo installation is required.\n\n- Windows: download the `.exe` and either run it directly or place it somewhere on your `PATH`.\n- Linux/macOS: download the binary, `chmod +x copycat`, then run it (optionally move to a directory on your `PATH`, e.g. `/usr/local/bin`).\n\n### Bash completion\n\nCopycat provides a generated Bash completion script that you can download from https://github.com/vegardit/copycat/releases/download/latest/bashcompletion.sh\n\nExample (Linux/macOS, or Git Bash on Windows):\n```bash\ncurl -fsSL -o bash-completions.sh https://github.com/vegardit/copycat/releases/download/latest/bashcompletion.sh\nsource ./bash-completions.sh\n```\n\nTo enable it permanently, source it from your `~/.bashrc` (or equivalent).\n\n\n## \u003ca name=\"quick-start\"\u003e\u003c/a\u003eQuick Start\n\n- One-time sync (with deletion):\n  - Windows: `copycat sync C:\\src X:\\dst --delete`\n  - Linux/macOS: `copycat sync /src /mnt/dst --delete`\n- Continuous sync (watch for changes): `copycat watch \u003cSOURCE\u003e \u003cTARGET\u003e`\n- Increase verbosity with `-v`, `-vv`, `-vvv`, or use `-q` for quiet.\n\n\n## \u003ca name=\"usage\"\u003e\u003c/a\u003eUsage\n\nCopycat understands two commands:\n- `sync` is used to synchronize files from one directory to another\n- `watch` is used to continuously watch a directory for changes and instantly syncs the changes to a given target\n\n\n### \u003ca name=\"sync\"\u003e\u003c/a\u003e`sync` command\n\n```\n$ copycat sync --help\n\nUsage: copycat sync [-hqVv] [--allow-reading-open-files] [--copy-acl] [--delete] [--delete-excluded] [--dry-run]\n                    [--exclude-hidden-files] [--exclude-hidden-system-files] [--exclude-older-files] [--exclude-other-links]\n                    [--exclude-system-files] [--ignore-errors] [--ignore-symlink-errors] [--log-errors-to-stdout]\n                    [--before \u003cwhen\u003e] [--config \u003cpath\u003e] [--log-file \u003cpath\u003e] [--max-depth \u003cdepth\u003e] [--since \u003cwhen\u003e]\n                    [--stall-timeout \u003cduration\u003e] [--threads \u003ccount\u003e] [--until \u003cwhen\u003e] [--filter (in|ex):\u003cpattern\u003e]...\n                    [--no-log \u003cop\u003e[,\u003cop\u003e...]]... [SOURCE] [TARGET]\n\nPerforms one-way recursive directory synchronization copying new files/directories.\n\nPositional parameters:\n      [SOURCE]              Directory to copy from files.\n      [TARGET]              Directory to copy files to.\n\nOptions:\n      --allow-reading-open-files\n                            On Windows, open source files with shared read access (best-effort).\n                              May copy an inconsistent snapshot for actively written files and may skip copying some metadata.\n      --before \u003cwhen\u003e       Sync only files modified before this date/time (exclusive). Format same as --since.\n                              Mutually exclusive with --until.\n      --config \u003cpath\u003e       Path to a YAML config file.\n      --copy-acl            Copy file permissions (ACL) for newly copied files.\n      --delete              Delete extraneous files/directories from target.\n      --delete-excluded     Delete excluded files/directories from target.\n      --dry-run             Don't perform actual synchronization.\n      --exclude-hidden-files\n                            Don't synchronize hidden files.\n      --exclude-hidden-system-files\n                            Don't synchronize hidden system files.\n      --exclude-older-files Don't override newer files in target with older files in source.\n      --exclude-other-links Don't synchronize symlinks whose targets are missing or are neither files nor directories.\n      --exclude-system-files\n                            Don't synchronize system files.\n      --filter (in|ex):\u003cpattern\u003e\n                            Glob pattern for files/directories to be excluded (ex:\u003cpattern\u003e) from or\n                              included (in:\u003cpattern\u003e) in sync.\n  -h, --help                Show this help message and exit.\n      --ignore-errors       Continue sync when errors occur.\n      --ignore-symlink-errors\n                            Continue if creation of symlinks on target fails.\n      --log-errors-to-stdout\n                            Log errors to stdout instead of stderr.\n      --log-file \u003cpath\u003e     Write console output also to the given log file.\n      --max-depth \u003cdepth\u003e   Maximum directory traversal depth from the source root.\n                            0=only top-level files (no subdirs), 1=include immediate subdirectories, etc.\n                            Default: unlimited.\n      --no-log \u003cop\u003e[,\u003cop\u003e...]\n                            Don't log the given sync operation. Valid values: CREATE, MODIFY, DELETE, SCAN\n  -q, --quiet               Quiet mode.\n      --since \u003cwhen\u003e        Sync only files modified on or after this date/time. Accepts ISO-8601 (2024-12-25,\n                              2024-12-25T14:30, 2024-12-25T14:30Z), durations (P3D, PT2H), or relative\n                              expressions (3 days ago, yesterday 14:00).\n      --stall-timeout \u003cduration\u003e\n                            Abort sync if no progress is observed for this long.\n                            Examples: PT10M, 10m, 2h 30m. Use 0 to disable.\n                            Bare numbers are minutes. Default: 10m\n      --threads \u003ccount\u003e     Number of concurrent threads. Default: 2\n      --until \u003cwhen\u003e        Sync only files modified on or before this date/time (inclusive). Format same as --since.\n                              Combined with --since to define a date range. Mutually exclusive with --before.\n  -v, --verbose             Specify multiple -v options to increase verbosity.\n                            For example `-v -v -v` or `-vvv`.\n```\n\nUnder the hood, the `sync` command uses a first-match-wins include/exclude filter engine with directory creation aligned to filtering:\n\n- First matching `in:` / `ex:` rule wins; unmatched paths are included by default.\n- Date filters (`--since`, `--before`, `--until`) apply only to files; directories are never excluded based on modification time.\n- Hidden/system flags apply to both files and directories.\n- Directory creation follows the filter rules:\n  - Directories are created when they contain at least one included entry.\n  - Empty directories are created if they are explicitly included (e.g. in:somedir) or when no filters are configured.\n\nExamples:\n```batch\n:: Basic sync with deletion\ncopycat sync C:\\myprojects X:\\myprojects --delete --threads 4\n\n:: Sync only files modified in the last 3 days\ncopycat sync C:\\mydata X:\\backup --since \"3 days ago\"\n\n:: Sync files modified between specific dates\ncopycat sync C:\\docs X:\\archive --since 2024-01-01 --until 2024-12-31\n\n:: Sync files modified since yesterday at 2 PM\ncopycat sync C:\\work X:\\backup --since \"yesterday 14:00\"\n```\n\nDefault values and/or multiple sync tasks can be configured using a YAML config file:\n```yaml\n# default values for sync tasks\ndefaults:\n  copy-acl: false\n  # Optional (Windows): allow copying files that are currently open for writing by other processes (best-effort)\n  # allow-reading-open-files: false\n  delete: true\n  delete-excluded: true\n  dry-run: false\n  exclude-older-files: false\n  exclude-hidden-files: false\n  exclude-system-files: true\n  exclude-hidden-system-files: false\n  filters:\n    - ex:**/node_modules\n    - in:logs/latest.log # keep latest log file\n    - ex:logs/*.log # exclude all other log files\n  ignore-errors: false\n  ignore-symlink-errors: false\n  threads: 2\n  # Optional: limit directory traversal depth (0=no subdirs)\n  # max-depth: 0\n  # Optional: sync only recent files\n  # since: \"7 days ago\"   # or \"2024-01-01\" or \"yesterday\"\n  # until: \"today\"        # inclusive upper bound (mutually exclusive with 'before')\n  # before: \"tomorrow\"    # exclusive upper bound (mutually exclusive with 'until')\n\n# one or more sync tasks\nsync:\n- source: C:\\mydata\n  target: \\\\myserver\\mydata\n\n- source: D:\\myotherdata\n  target: \\\\myserver\\myotherdata\n  # Optional: sync only files modified in the last week\n  since: \"7 days ago\"\n\n- source: E:\\archives\n  target: \\\\backup\\archives\n  # Optional: sync files from a specific date range\n  since: 2024-01-01\n  until: 2024-12-31\n```\n\nTo enable editor validation/autocompletion for `config.yaml`, a JSON schema is published at:\n\n- https://github.com/vegardit/copycat/releases/download/latest/config.schema.json\n\nIf you use the YAML Language Server (e.g. via VS Code), you can reference it by adding this as the first line of your YAML file:\n\n```yaml\n# yaml-language-server: $schema=https://github.com/vegardit/copycat/releases/download/latest/config.schema.json\n```\n\n\n### \u003ca name=\"watch\"\u003e\u003c/a\u003e`watch` command\n\n```\n$ copycat watch --help\n\nUsage: copycat watch [-hqVv] [--allow-reading-open-files] [--copy-acl] [--delete-excluded] [--exclude-hidden-files]\n                     [--exclude-hidden-system-files] [--exclude-system-files] [--log-errors-to-stdout]\n                     [--config \u003cpath\u003e] [--log-file \u003cpath\u003e] [--max-depth \u003cdepth\u003e] [--since \u003cwhen\u003e] [--until\n                     \u003cwhen\u003e] [--before \u003cwhen\u003e] [--filter (in|ex):\u003cpattern\u003e]... [--no-log \u003cop\u003e[,\u003cop\u003e...]]...\n                     [SOURCE] [TARGET]\n\nContinuously watches a directory recursively for changes and synchronizes them to another directory.\n\nPositional parameters:\n      [SOURCE]              Directory to copy from files.\n      [TARGET]              Directory to copy files to.\n\nOptions:\n      --allow-reading-open-files\n                            On Windows, open source files with shared read access (best-effort).\n                              May copy an inconsistent snapshot for actively written files and may skip copying some metadata.\n      --before \u003cwhen\u003e       Sync only files modified before this date/time (exclusive). Format same as --since.\n                              Mutually exclusive with --until.\n      --config \u003cpath\u003e       Path to a YAML config file.\n      --copy-acl            Copy file permissions (ACL) for newly copied files.\n      --delete-excluded     Delete excluded files/directories from target.\n      --exclude-hidden-files\n                            Don't synchronize hidden files.\n      --exclude-hidden-system-files\n                            Don't synchronize hidden system files.\n      --exclude-other-links Don't synchronize symlinks whose targets are neither files nor directories.\n      --exclude-system-files\n                            Don't synchronize system files.\n      --filter (in|ex):\u003cpattern\u003e\n                            Glob pattern for files/directories to be excluded (ex:\u003cpattern\u003e) from or\n                              included (in:\u003cpattern\u003e) in sync.\n  -h, --help                Show this help message and exit.\n      --log-errors-to-stdout\n                            Log errors to stdout instead of stderr.\n      --log-file \u003cpath\u003e     Write console output also to the given log file.\n      --max-depth \u003cdepth\u003e   Maximum directory traversal depth from the source root.\n                            0=only top-level files (no subdirs), 1=include immediate subdirectories, etc.\n                            Default: unlimited.\n      --no-log \u003cop\u003e[,\u003cop\u003e...]\n                            Don't log the given filesystem operation. Valid values: CREATE, MODIFY, DELETE\n  -q, --quiet               Quiet mode.\n      --since \u003cwhen\u003e        Sync only files modified on or after this date/time. Accepts ISO-8601 (2024-12-25,\n                              2024-12-25T14:30, 2024-12-25T14:30Z), durations (P3D, PT2H), or relative\n                              expressions (3 days ago, yesterday 14:00).\n      --until \u003cwhen\u003e        Sync only files modified on or before this date/time (inclusive). Format same as\n                              --since. Combined with --since to define a date range. Mutually exclusive with\n                              --before.\n  -v, --verbose             Specify multiple -v options to increase verbosity.\n                            For example `-v -v -v` or `-vvv`.\n```\n\nExample:\n```batch\n$ copycat watch C:\\myprojects X:\\myprojects\n```\n\n\nDefault values and/or multiple sync tasks can be configured using a YAML config file:\n```yaml\n# default values for sync tasks\ndefaults:\n  copy-acl: false\n  delete-excluded: true\n  exclude-hidden-files: false\n  exclude-system-files: true\n  exclude-hidden-system-files: false\n  # Optional: limit directory traversal depth for watching (0=no subdirs)\n  # max-depth: 0\n  filters:\n    - ex:**/node_modules\n    - in:logs/latest.log # keep latest log file\n    - ex:logs/*.log # exclude all other log files\n\n# one or more sync tasks\nsync:\n- source: C:\\mydata\n  target: \\\\myserver\\mydata\n\n- source: D:\\myotherdata\n  target: \\\\myserver\\myotherdata\n```\n\n\n### \u003ca name=\"filters\"\u003e\u003c/a\u003eFilters: including/excluding files\n\nBy default all files are synced from source to target.\n\n#### Filter semantics\n\n- Filters apply to both files and directories.\n- Each filter is prefixed with `in:` (include) or `ex:` (exclude); the prefix is case-insensitive.\n- Paths are matched against the full source-relative or target-relative path using `/` as separator; on Windows, backslashes in patterns are normalized to `/`.\n- Filters are evaluated in the order they are defined; the first matching filter decides:\n  - `ex:` → excluded\n  - `in:` → included\n- If no filter matches, the entry is included by default, even if only `in:` filters are configured.\n- Date filters (`--since`, `--until`, `--before`) are applied only to files, never to directories; hidden/system flags apply to both files and directories and are evaluated before glob filters.\n\n#### Pattern-Based Filtering\n\nFiles/folders can be excluded/included using [glob](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)) patterns.\nThe patterns must be prefixed with `ex:` for exclude patterns and with `in:` for include patterns. The prefix is case-insensitive, i.e. `EX:` and `IN:` can also be used.\n\n**The order in which patterns are declared is important.**\nCopycat checks the relative path of each file to be synced against the configured list of include/exclude patterns, and **the first matching pattern is acted on**:\n- if it is an exclude pattern, the file is not synced;\n- if it is an include pattern, the file is synced;\n- if no matching pattern is found, the file is synced.\n\n1. YAML config example:\n   ```yaml\n   sync:\n   - source: C:\\mydata\n     target: \\\\myserver\\mydata\n     filters:\n       - ex:**/node_modules\n       - in:logs/latest.log # keep latest log file\n       - ex:logs/*.log # exclude all other log files\n   ```\n\n2. CLI example:\n   ```batch\n    copycat sync --filter ex:**/node_modules --filter in:logs/latest.log --filter ex:logs/*.log C:\\mydata \\\\myserver\\mydata\n   ```\n\n#### Directories and traversal\n\n- Copycat distinguishes between:\n  - *Traversal*: whether a directory is descended into.\n  - *Inclusion/materialization*: whether a directory itself is created on the target.\n- A global `ex:**` (or `ex:**/*`) does not by itself stop traversal when there are `in:` rules that might match descendants (for example `in:**/patch.xml, ex:**` still traverses into `dev/...` to find `patch.xml`).\n- Directories on the target are created lazily:\n  - A directory is created when the first included child (file or subdirectory) under it is synced, or\n  - When the directory itself is explicitly included by a pattern.\n- Empty directory semantics:\n  - `in:somedir` includes an empty `somedir` directory (it will be created even without files).\n  - `in:somedir/**` matches only descendants of `somedir`, so an empty `somedir` is not created.\n\n#### Whitelist and blacklist recipes\n\n- Whitelist-style (copy only some patterns):\n  ```yaml\n  filters:\n    - in:dir/subdir/*.log\n    - in:**/patch.xml\n    - ex:**          # exclude everything else\n  ```\n- Blacklist-style (copy everything except some patterns):\n  ```yaml\n  filters:\n    - ex:**/node_modules/**\n    - ex:logs/*.log\n    - in:logs/latest.log # re-include a specific file\n  ```\n\n#### Target filters and deletes\n\n- Target-side filters use the same syntax and semantics as source filters (same `in:`/`ex:` rules, first match wins, default include).\n- They are mainly used when `--delete` or `--delete-excluded` is enabled:\n  - `--delete` considers target entries that do not exist in the source; filters can protect some of them.\n  - `--delete-excluded` also deletes target entries that are excluded by filters.\n- Matching is done on target-relative paths, again using `/` as separator (backslashes in patterns are normalized on Windows).\n\n#### Date/Time Filtering\n\nYou can filter files based on their modification time using `--since`, `--until`, and `--before` options:\n\n**Supported date/time formats:**\n- **ISO-8601 dates**: `2024-12-25`, `2024-12-25T14:30`, `2024-12-25 14:30:45`\n- **Keywords**: `yesterday`, `today`, `tomorrow` (with optional time like `yesterday 14:00`)\n- **Relative expressions** (case-insensitive, including ISO-8601 durations):\n  - ISO duration syntax: `[in] \u003cduration\u003e [ago]`, for example `PT1H`, `PT1H ago`, `in PT2H30M`, `P3D ago`\n  - Human-readable syntax: `[in] \u003camount\u003e\u003cunit\u003e [\u003camount\u003e\u003cunit\u003e ...] [ago]`, for example `3h ago`, `2d 3h 15m ago`, `in 5 hours`\n    - Units for human-readable forms: `d`/`day`/`days`, `h`/`hour`/`hours`, `m`/`min`/`mins`/`minute`/`minutes`, `s`/`sec`/`secs`/`second`/`seconds`\n    - Order does not matter: `2d 3h`, `3h 2d`, `1h 30m`, etc.\n  - Semantics:\n    - `in ...` → future (relative to now), for example `in 2 hours`, `in PT2H`\n    - `... ago` → past, for example `3 days ago`, `PT1H ago`\n    - Without `in` or `ago` it **defaults to past**, for example `3h 30m` and `PT1H` are interpreted as *3h30m ago* and *1 hour ago* respectively.\n\n**Examples:**\n```batch\n# Sync files modified in the last week\ncopycat sync source/ target/ --since \"7 days ago\"\n\n# Sync files modified in the last hour using ISO duration\ncopycat sync source/ target/ --since \"PT1H ago\"\n\n# Sync files modified between specific dates\ncopycat sync source/ target/ --since 2024-01-01 --until 2024-06-30\n\n# Sync files modified since yesterday at 2 PM\ncopycat sync source/ target/ --since \"yesterday 14:00\"\n\n# Sync files modified today\ncopycat sync source/ target/ --since today\n```\n\n\n## \u003ca name=\"contributing\"\u003e\u003c/a\u003eContributing\n\n- See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n- This project follows the Contributor Covenant; see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).\n\n\n## \u003ca name=\"license\"\u003e\u003c/a\u003eLicense\n\nAll files are released under the [Apache License 2.0](LICENSE.txt).\n\nIndividual files contain the following tag instead of the full license text:\n```\nSPDX-License-Identifier: Apache-2.0\n```\n\nThis enables machine processing of license information based on the SPDX License Identifiers that are available here: https://spdx.org/licenses/.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvegardit%2Fcopycat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvegardit%2Fcopycat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvegardit%2Fcopycat/lists"}