From 477c8a98a8d25a4920f770d303c4a24712cf3a70 Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Thu, 18 Jun 2026 15:55:18 -0400 Subject: [PATCH] feat(secrev): doc-drift Plane-1 Tier-1 checker (UNGATED) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Third Plane-1 checker on the Phase-0 shared substrate, mirroring compliance-drift.sh / dependency-cve.sh conventions verbatim (set -euo pipefail, sourced substrate, --canary/--dry-run/--no-api/--refresh/--targets, mode-600 reports under $REPORT_ROOT/doc-drift//, ALARM-only, finding.schema spirit JSON, exit 0/2/3, dotgit->.git fixture trick). Detects documentation drift deterministically (design §4 doc-drift row): - readme-omits-component: README omits an existing major component in the tree (top-level service dir, SAM/CDK stack, Lambda handler dir, openapi/docs spec) - readme-stale-vs-code: README last-touch far older than newest code commit (two-factor: >=DOC_DRIFT_STALE_DAYS AND >=DOC_DRIFT_STALE_COMMITS) A repo with NO README is SKIPPED (compliance-drift owns readme-present; no double-flag). Future Gemini large-context judge (§4) is an inert stub (maybe_judge), off in canary/dry-run/offline. Planted-drift fixture corpus + EXPECTED_DRIFT_COUNT=4, canary-asserted (exit 3 on miss). shellcheck -x clean (only accepted SC1091 source-line info). Does NOT touch checker_coordinator.sh, requirements.txt, or aws-posture. Wiring/systemd is gated (PROVISIONING footer). Design refs §4, §7 Phase 3. --- security-review/checkers/doc-drift.sh | 482 ++++++++++++++++++ .../fixtures/doc-drift/EXPECTED_DRIFT_COUNT | 1 + .../checkers/fixtures/doc-drift/README.md | 43 ++ .../fixtures/doc-drift/clean-repo/README.md | 10 + .../fixtures/doc-drift/clean-repo/api/main.go | 1 + .../clean-repo/dotgit/COMMIT_EDITMSG | 1 + .../fixtures/doc-drift/clean-repo/dotgit/HEAD | 1 + .../doc-drift/clean-repo/dotgit/config | 10 + .../doc-drift/clean-repo/dotgit/description | 1 + .../dotgit/hooks/applypatch-msg.sample | 15 + .../clean-repo/dotgit/hooks/commit-msg.sample | 24 + .../dotgit/hooks/fsmonitor-watchman.sample | 174 +++++++ .../dotgit/hooks/post-update.sample | 8 + .../dotgit/hooks/pre-applypatch.sample | 14 + .../clean-repo/dotgit/hooks/pre-commit.sample | 49 ++ .../dotgit/hooks/pre-merge-commit.sample | 13 + .../clean-repo/dotgit/hooks/pre-push.sample | 53 ++ .../clean-repo/dotgit/hooks/pre-rebase.sample | 169 ++++++ .../dotgit/hooks/pre-receive.sample | 24 + .../dotgit/hooks/prepare-commit-msg.sample | 42 ++ .../dotgit/hooks/push-to-checkout.sample | 78 +++ .../dotgit/hooks/sendemail-validate.sample | 77 +++ .../clean-repo/dotgit/hooks/update.sample | 128 +++++ .../doc-drift/clean-repo/dotgit/index | Bin 0 -> 589 bytes .../doc-drift/clean-repo/dotgit/info/exclude | 6 + .../doc-drift/clean-repo/dotgit/logs/HEAD | 1 + .../clean-repo/dotgit/logs/refs/heads/main | 1 + .../06/ab7d0f9a35a7d1070711496d6ca1cb892a258f | Bin 0 -> 29 bytes .../0b/5c163a57c647bd824a907f7e0b9aa6335a7d77 | Bin 0 -> 184 bytes .../1f/86368c694ecb3d9d64788a988ca4a5365e4df8 | Bin 0 -> 51 bytes .../51/3273c393a63fbff76e46c8a8ed159bd9e83a1c | 1 + .../88/72f0d44bfbbfa113423377b41597af8faacb8d | Bin 0 -> 54 bytes .../98/ec3d6272badf42441f11b2c53b42961a33f5f7 | Bin 0 -> 50 bytes .../a2/549621f3ce0547771b96e53f14e2fcd74a3e50 | Bin 0 -> 36 bytes .../b9/270df7070cc6a5e7dbdec610a7ce4f54c47b20 | 1 + .../bf/de979a9dc263aafe98de15bc024e98440984d7 | 1 + .../d9/178f4ee78dd6637d209f4e7dc70a18b160bf9a | Bin 0 -> 48 bytes .../e5/c55ac820d3272863a874fc1e202908241c2acf | Bin 0 -> 125 bytes .../clean-repo/dotgit/refs/heads/main | 1 + .../clean-repo/handlers/ingest/app.py | 1 + .../doc-drift/clean-repo/openapi/spec.json | 1 + .../doc-drift/clean-repo/template.yaml | 5 + .../doc-drift/drift-omits-repo/README.md | 7 + .../drift-omits-repo/dotgit/COMMIT_EDITMSG | 1 + .../doc-drift/drift-omits-repo/dotgit/HEAD | 1 + .../doc-drift/drift-omits-repo/dotgit/config | 10 + .../drift-omits-repo/dotgit/description | 1 + .../dotgit/hooks/applypatch-msg.sample | 15 + .../dotgit/hooks/commit-msg.sample | 24 + .../dotgit/hooks/fsmonitor-watchman.sample | 174 +++++++ .../dotgit/hooks/post-update.sample | 8 + .../dotgit/hooks/pre-applypatch.sample | 14 + .../dotgit/hooks/pre-commit.sample | 49 ++ .../dotgit/hooks/pre-merge-commit.sample | 13 + .../dotgit/hooks/pre-push.sample | 53 ++ .../dotgit/hooks/pre-rebase.sample | 169 ++++++ .../dotgit/hooks/pre-receive.sample | 24 + .../dotgit/hooks/prepare-commit-msg.sample | 42 ++ .../dotgit/hooks/push-to-checkout.sample | 78 +++ .../dotgit/hooks/sendemail-validate.sample | 77 +++ .../dotgit/hooks/update.sample | 128 +++++ .../doc-drift/drift-omits-repo/dotgit/index | Bin 0 -> 627 bytes .../drift-omits-repo/dotgit/info/exclude | 6 + .../drift-omits-repo/dotgit/logs/HEAD | 1 + .../dotgit/logs/refs/heads/main | 1 + .../19/366a9a93232cf60a444d9a1d4114bc55084d0f | Bin 0 -> 201 bytes .../1f/86368c694ecb3d9d64788a988ca4a5365e4df8 | Bin 0 -> 51 bytes .../36/31a0436785d485c1f063f82fe6755d6cf9ee89 | 2 + .../96/f70ef65cc77ae047293b093219c7f996e1d6fa | Bin 0 -> 52 bytes .../98/ec3d6272badf42441f11b2c53b42961a33f5f7 | Bin 0 -> 50 bytes .../9a/162ac5a718f5b673c538badf3506c17d988fc8 | Bin 0 -> 54 bytes .../9a/24dce1a9a1c4b5bc277b5beeedec49d5604a75 | Bin 0 -> 127 bytes .../9a/81d157c401c61bebf0c4ef31dc7d3777edbcba | Bin 0 -> 35 bytes .../a1/7e6a98edf78d6c4f540aca77932f81e2b4ccdc | Bin 0 -> 48 bytes .../cc/b1aee04842afc8dcb1e6b7f292de8ddef50f73 | Bin 0 -> 35 bytes .../ff/9ded83431a6059a99140b744c351e43bb04eed | Bin 0 -> 103 bytes .../drift-omits-repo/dotgit/refs/heads/main | 1 + .../drift-omits-repo/handlers/charge/app.py | 1 + .../drift-omits-repo/notifier-service/main.py | 1 + .../drift-omits-repo/payments-service/main.py | 1 + .../doc-drift/drift-omits-repo/template.yaml | 5 + .../doc-drift/drift-stale-repo/README.md | 5 + .../drift-stale-repo/dotgit/COMMIT_EDITMSG | 1 + .../doc-drift/drift-stale-repo/dotgit/HEAD | 1 + .../doc-drift/drift-stale-repo/dotgit/config | 10 + .../drift-stale-repo/dotgit/description | 1 + .../dotgit/hooks/applypatch-msg.sample | 15 + .../dotgit/hooks/commit-msg.sample | 24 + .../dotgit/hooks/fsmonitor-watchman.sample | 174 +++++++ .../dotgit/hooks/post-update.sample | 8 + .../dotgit/hooks/pre-applypatch.sample | 14 + .../dotgit/hooks/pre-commit.sample | 49 ++ .../dotgit/hooks/pre-merge-commit.sample | 13 + .../dotgit/hooks/pre-push.sample | 53 ++ .../dotgit/hooks/pre-rebase.sample | 169 ++++++ .../dotgit/hooks/pre-receive.sample | 24 + .../dotgit/hooks/prepare-commit-msg.sample | 42 ++ .../dotgit/hooks/push-to-checkout.sample | 78 +++ .../dotgit/hooks/sendemail-validate.sample | 77 +++ .../dotgit/hooks/update.sample | 128 +++++ .../doc-drift/drift-stale-repo/dotgit/index | Bin 0 -> 744 bytes .../drift-stale-repo/dotgit/info/exclude | 6 + .../drift-stale-repo/dotgit/logs/HEAD | 6 + .../dotgit/logs/refs/heads/main | 6 + .../06/2858f6d6f54e5a930a45178929532313b7a231 | Bin 0 -> 38 bytes .../0c/30159d993e4b7fc86add22ed6ce984618552ef | Bin 0 -> 38 bytes .../0c/d9efe3a4957b0f5336c33f4e40e9e4d779c243 | 3 + .../17/001f0544766545e2b63b2d3e7454ffa28cba39 | Bin 0 -> 139 bytes .../34/a52c1c070ac4df6225a1ef1a73643bcf92ef44 | Bin 0 -> 38 bytes .../4c/217577a9492a8030c5980e5d6796768781ed6d | Bin 0 -> 33 bytes .../59/c4d8defd13e7623f2af0073db64ce8ec4a1612 | Bin 0 -> 165 bytes .../5e/a038ee524a2a7200c3e4eb22febc5aeceb24a5 | Bin 0 -> 94 bytes .../60/3e3162216f19595bd6df1db44faf0f3c168f8f | Bin 0 -> 51 bytes .../64/74695394af5333896c7b296879398ef18776ca | 1 + .../6b/7c13685ae818268d30ed3cf27c86da2820f186 | 2 + .../76/87db2a5781d77b42ced78a6bca02c37a8dbbf0 | 2 + .../76/fcd8c1bd06f4648062d7865d83e0ec5279d8f8 | Bin 0 -> 95 bytes .../8d/2121584af4558168be908795ae74dfbda6169e | Bin 0 -> 86 bytes .../8f/a23b3da38f76c4418ca50353902b048836568f | Bin 0 -> 38 bytes .../93/a7db735d0cfe42f0a57d956915f5e5a7f87378 | 2 + .../9c/2018ca90ae8305bec517e0b8b91b5d8a755404 | Bin 0 -> 156 bytes .../9f/546c4f4a2d0dd2e1058184772a3adb55798f9a | Bin 0 -> 95 bytes .../a0/e549607d67e126ade87dc0bc5725af0f74b95d | Bin 0 -> 94 bytes .../af/8b041ef281bb9d89401efcdf549a9a452f0ecf | 2 + .../b6/a829f82042d95da9d90a470dedc3bfd78578f3 | Bin 0 -> 38 bytes .../bd/2d8bf341977713187d0eb4015969c219c64848 | Bin 0 -> 94 bytes .../c7/d8d3f68781472c6b19cf938ddd41f02995d5ef | 1 + .../d6/7d8cbcffeacd1914a11d726d85a8df8432e95a | 1 + .../ec/d451c0dc54b254b1572587d48fbe617ac3d738 | Bin 0 -> 95 bytes .../drift-stale-repo/dotgit/refs/heads/main | 1 + .../worker-service/feature_1.py | 1 + .../worker-service/feature_2.py | 1 + .../worker-service/feature_3.py | 1 + .../worker-service/feature_4.py | 1 + .../worker-service/feature_5.py | 1 + .../drift-stale-repo/worker-service/main.py | 1 + .../no-readme-repo/dotgit/COMMIT_EDITMSG | 1 + .../doc-drift/no-readme-repo/dotgit/HEAD | 1 + .../doc-drift/no-readme-repo/dotgit/config | 10 + .../no-readme-repo/dotgit/description | 1 + .../dotgit/hooks/applypatch-msg.sample | 15 + .../dotgit/hooks/commit-msg.sample | 24 + .../dotgit/hooks/fsmonitor-watchman.sample | 174 +++++++ .../dotgit/hooks/post-update.sample | 8 + .../dotgit/hooks/pre-applypatch.sample | 14 + .../dotgit/hooks/pre-commit.sample | 49 ++ .../dotgit/hooks/pre-merge-commit.sample | 13 + .../dotgit/hooks/pre-push.sample | 53 ++ .../dotgit/hooks/pre-rebase.sample | 169 ++++++ .../dotgit/hooks/pre-receive.sample | 24 + .../dotgit/hooks/prepare-commit-msg.sample | 42 ++ .../dotgit/hooks/push-to-checkout.sample | 78 +++ .../dotgit/hooks/sendemail-validate.sample | 77 +++ .../no-readme-repo/dotgit/hooks/update.sample | 128 +++++ .../doc-drift/no-readme-repo/dotgit/index | Bin 0 -> 190 bytes .../no-readme-repo/dotgit/info/exclude | 6 + .../doc-drift/no-readme-repo/dotgit/logs/HEAD | 1 + .../dotgit/logs/refs/heads/main | 1 + .../2a/508708278fea9839105388e392dda2a0b42527 | Bin 0 -> 28 bytes .../6e/b474c4350e80479203ab76b02a02822e6c53cb | Bin 0 -> 52 bytes .../90/7ed9bc9b45714bd6d0be7d42463409082cf085 | Bin 0 -> 54 bytes .../aa/56c53150461eebd587634d76f26cf626a18e3b | Bin 0 -> 120 bytes .../no-readme-repo/dotgit/refs/heads/main | 1 + .../no-readme-repo/some-service/main.py | 1 + 164 files changed, 4160 insertions(+) create mode 100755 security-review/checkers/doc-drift.sh create mode 100644 security-review/checkers/fixtures/doc-drift/EXPECTED_DRIFT_COUNT create mode 100644 security-review/checkers/fixtures/doc-drift/README.md create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/README.md create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/api/main.go create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/COMMIT_EDITMSG create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/config create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/description create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/applypatch-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/fsmonitor-watchman.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/post-update.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-applypatch.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-merge-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-push.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-rebase.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-receive.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/prepare-commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/push-to-checkout.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/sendemail-validate.sample create mode 100755 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/update.sample create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/index create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/info/exclude create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/logs/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/logs/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/06/ab7d0f9a35a7d1070711496d6ca1cb892a258f create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/0b/5c163a57c647bd824a907f7e0b9aa6335a7d77 create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/1f/86368c694ecb3d9d64788a988ca4a5365e4df8 create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/51/3273c393a63fbff76e46c8a8ed159bd9e83a1c create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/88/72f0d44bfbbfa113423377b41597af8faacb8d create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/98/ec3d6272badf42441f11b2c53b42961a33f5f7 create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/a2/549621f3ce0547771b96e53f14e2fcd74a3e50 create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/b9/270df7070cc6a5e7dbdec610a7ce4f54c47b20 create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/bf/de979a9dc263aafe98de15bc024e98440984d7 create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/d9/178f4ee78dd6637d209f4e7dc70a18b160bf9a create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/e5/c55ac820d3272863a874fc1e202908241c2acf create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/handlers/ingest/app.py create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/openapi/spec.json create mode 100644 security-review/checkers/fixtures/doc-drift/clean-repo/template.yaml create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/README.md create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/COMMIT_EDITMSG create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/config create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/description create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/applypatch-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/fsmonitor-watchman.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/post-update.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-applypatch.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-merge-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-push.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-rebase.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-receive.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/prepare-commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/push-to-checkout.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/sendemail-validate.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/update.sample create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/index create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/info/exclude create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/19/366a9a93232cf60a444d9a1d4114bc55084d0f create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/1f/86368c694ecb3d9d64788a988ca4a5365e4df8 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/36/31a0436785d485c1f063f82fe6755d6cf9ee89 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/96/f70ef65cc77ae047293b093219c7f996e1d6fa create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/98/ec3d6272badf42441f11b2c53b42961a33f5f7 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/9a/162ac5a718f5b673c538badf3506c17d988fc8 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/9a/24dce1a9a1c4b5bc277b5beeedec49d5604a75 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/9a/81d157c401c61bebf0c4ef31dc7d3777edbcba create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/a1/7e6a98edf78d6c4f540aca77932f81e2b4ccdc create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/cc/b1aee04842afc8dcb1e6b7f292de8ddef50f73 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/ff/9ded83431a6059a99140b744c351e43bb04eed create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/handlers/charge/app.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/notifier-service/main.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/payments-service/main.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-omits-repo/template.yaml create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/README.md create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/COMMIT_EDITMSG create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/config create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/description create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/applypatch-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/fsmonitor-watchman.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/post-update.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-applypatch.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-merge-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-push.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-rebase.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-receive.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/prepare-commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/push-to-checkout.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/sendemail-validate.sample create mode 100755 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/update.sample create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/index create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/info/exclude create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/06/2858f6d6f54e5a930a45178929532313b7a231 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/0c/30159d993e4b7fc86add22ed6ce984618552ef create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/0c/d9efe3a4957b0f5336c33f4e40e9e4d779c243 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/17/001f0544766545e2b63b2d3e7454ffa28cba39 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/34/a52c1c070ac4df6225a1ef1a73643bcf92ef44 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/4c/217577a9492a8030c5980e5d6796768781ed6d create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/59/c4d8defd13e7623f2af0073db64ce8ec4a1612 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/5e/a038ee524a2a7200c3e4eb22febc5aeceb24a5 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/60/3e3162216f19595bd6df1db44faf0f3c168f8f create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/64/74695394af5333896c7b296879398ef18776ca create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/6b/7c13685ae818268d30ed3cf27c86da2820f186 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/87db2a5781d77b42ced78a6bca02c37a8dbbf0 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/fcd8c1bd06f4648062d7865d83e0ec5279d8f8 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/8d/2121584af4558168be908795ae74dfbda6169e create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/8f/a23b3da38f76c4418ca50353902b048836568f create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/93/a7db735d0cfe42f0a57d956915f5e5a7f87378 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/9c/2018ca90ae8305bec517e0b8b91b5d8a755404 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/9f/546c4f4a2d0dd2e1058184772a3adb55798f9a create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/a0/e549607d67e126ade87dc0bc5725af0f74b95d create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/af/8b041ef281bb9d89401efcdf549a9a452f0ecf create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/b6/a829f82042d95da9d90a470dedc3bfd78578f3 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/bd/2d8bf341977713187d0eb4015969c219c64848 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/c7/d8d3f68781472c6b19cf938ddd41f02995d5ef create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/d6/7d8cbcffeacd1914a11d726d85a8df8432e95a create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/ec/d451c0dc54b254b1572587d48fbe617ac3d738 create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_1.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_2.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_3.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_4.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_5.py create mode 100644 security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/main.py create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/COMMIT_EDITMSG create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/config create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/description create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/applypatch-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/fsmonitor-watchman.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/post-update.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-applypatch.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-merge-commit.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-push.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-rebase.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-receive.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/prepare-commit-msg.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/push-to-checkout.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/sendemail-validate.sample create mode 100755 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/update.sample create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/index create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/info/exclude create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/logs/HEAD create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/logs/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/objects/2a/508708278fea9839105388e392dda2a0b42527 create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/objects/6e/b474c4350e80479203ab76b02a02822e6c53cb create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/objects/90/7ed9bc9b45714bd6d0be7d42463409082cf085 create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/objects/aa/56c53150461eebd587634d76f26cf626a18e3b create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/refs/heads/main create mode 100644 security-review/checkers/fixtures/doc-drift/no-readme-repo/some-service/main.py diff --git a/security-review/checkers/doc-drift.sh b/security-review/checkers/doc-drift.sh new file mode 100755 index 0000000..d984216 --- /dev/null +++ b/security-review/checkers/doc-drift.sh @@ -0,0 +1,482 @@ +#!/usr/bin/env bash +# doc-drift.sh — Plane-1 / Tier-1 checker for the R720 agent-team. +# +# Design refs: docs/r720-agent-team-design.md §4 (Tier 1 roster: doc-drift — +# "Flags repos whose architecture moved but Confluence/README did not") and §7 Phase 3 +# ("doc-drift + step-ca/Roles Anywhere + aws-posture"). This is the THIRD Plane-1 checker +# built on the Phase-0 shared substrate (lib/sweep_substrate.sh); it mirrors +# compliance-drift.sh / dependency-cve.sh conventions VERBATIM so the coordinator (§5) can +# drive all of them identically. doc-drift is UNGATED (only aws-posture in this phase is +# hard-gated behind the GPT-4.1 IAM cross-review; that checker is NOT built here). +# +# WHAT IT DOES (read-only): +# Scans the SAME shallow clean clones nightly_sweep.sh already produced in $MIRROR_DIR — it +# does NOT re-clone (mirrors-first; an optional --refresh re-runs discovery+mirror via the +# shared substrate). In each mirror it flags repos whose ARCHITECTURE MOVED but the README +# DID NOT — i.e. documentation drift. The checklist is DETERMINISTIC and GROUNDED in the +# global CLAUDE.md README obligation; it does NOT invent fuzzy judgments. See "CHECKLIST". +# +# This phase is the deterministic core ONLY. The design's "Gemini (large context)" judge +# layer (§4) is a LATER enhancement: a clearly-marked inert stub hook (maybe_judge) marks +# the future seam; it does NOTHING offline and NOTHING in this phase. +# +# REPORTING (matches secrev sweep conventions): +# - Writes a per-run JSON + text report under $REPORT_ROOT//, mode 600 (umask 077). +# - Slack ALARM-ONLY: a clean run (no confirmed drift) posts NOTHING (memory +# feedback_cloudwatch_alarms). Secret-shaped values are redacted from the Slack string. +# - Reuses the substrate's redact() + post_slack_alarm() verbatim. +# +# SUBSTRATE REUSE (lib/sweep_substrate.sh, sourced — bash dynamic scoping): +# redact, post_slack_alarm -> Slack delivery (reads SLACK_WEBHOOK_URL, REPORT_DIR, SWEEP_LOG) +# discover_repos, mirror_repo-> ONLY on --refresh (reads GH_TOKEN, GH_ORG, MIRROR_DIR, REPORT_DIR) +# Default path enumerates EXISTING $MIRROR_DIR/*/.git dirs — zero clones, zero network. +# +# CANARY / DRY-RUN (offline, no network, no token): +# --canary runs the checklist against a planted-drift fixture (checkers/fixtures/doc-drift/) +# and asserts the known drift count. This is the anti-complacency floor (design §6.4) AND the +# routing dry-run (§7 Phase 3): with --dry-run, the Slack alarm is composed + printed but NOT +# POSTed. Fully offline-smoke-testable (the checks are filesystem + `git log`, no network). +# +# SCOPE / SAFETY: +# Read-only. All checks are filesystem + local `git log`; NO network, NO token, NO GitHub API +# (doc-drift has no API-only checks — it is purely tree+history). Fixtures ship git metadata as +# dotgit/ (renamed to .git/ at run time) so they commit into THIS repo without becoming +# submodules — the SAME trick compliance-drift / dependency-cve use. A repo with NO README is +# SKIPPED (compliance-drift owns readme-present); doc-drift never double-flags a missing README. +# +# This script does NOT touch agent_team/ or agent-team/, is NOT wired into systemd, and does NOT +# stand up step-ca / Roles Anywhere / aws-posture — that is Phase-3/6 provisioning (gated). See +# the "PROVISIONING (NOT DONE HERE)" note at the bottom. +# +# Exit: 0 = ran (whether or not it alarmed); 2 = setup/usage error; 3 = canary assertion FAILED. +set -euo pipefail +export PATH="$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:$PATH" + +log() { echo "[doc-drift] $*" >&2; } +die() { echo "[doc-drift] FATAL: $*" >&2; exit 2; } + +# --- Shared substrate --------------------------------------------------------- +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SUBSTRATE="$HERE/../lib/sweep_substrate.sh" +[ -f "$SUBSTRATE" ] || die "shared substrate not found: $SUBSTRATE" +# shellcheck source=../lib/sweep_substrate.sh +. "$SUBSTRATE" + +# --- Config + defaults (env, all optional) ------------------------------------ +GH_ORG="${GH_ORG:-Sea-Haven-Industries}" +MIRROR_DIR="${MIRROR_DIR:-$HOME/repo-mirrors}" +REPORT_ROOT="${REPORT_ROOT:-$HOME/sweep-reports/doc-drift}" +# Docs-only repos describe themselves differently (a handbook is its own doc); skip the +# architecture-omission scan for them. They still get the staleness check. +DOCS_ONLY_REPOS="${DOCS_ONLY_REPOS:-engineering-handbook}" +# Staleness thresholds: README must lag the newest code by BOTH at least this many days AND +# this many substantial code commits before we call it drift (two-factor = no false alarm on a +# single quick fix landed after a doc commit; memory feedback_cloudwatch_alarms). +DOC_DRIFT_STALE_DAYS="${DOC_DRIFT_STALE_DAYS:-60}" +DOC_DRIFT_STALE_COMMITS="${DOC_DRIFT_STALE_COMMITS:-3}" + +REFRESH=0 # --refresh: re-run discovery+mirror via substrate (network). Default: reuse mirrors. +DO_API=1 # --no-api: accepted for interface-parity with the other checkers; doc-drift makes + # NO API calls, so this flag is a documented no-op (kept so the coordinator + # can pass a uniform flag set to every Tier-1 checker). +DRY_RUN=0 # --dry-run: compose the Slack alarm but DO NOT post it (routing dry-run). +CANARY=0 # --canary: run against the planted-drift fixture + assert the known count. +TARGETS_OVERRIDE="" # --targets "p1 p2": scan explicit dirs instead of the mirror set. + +usage() { + cat >&2 </dev/null || die "jq is required" +command -v git >/dev/null || die "git is required" + +# --- Report dir (mode 600 reports; matches sweep conventions) ----------------- +umask 077 +UTC_DATE="$(date -u +%Y-%m-%d)" +UTC_STAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +REPORT_DIR="$REPORT_ROOT/$UTC_DATE" +mkdir -p "$REPORT_DIR"; chmod 700 "$REPORT_ROOT" "$REPORT_DIR" 2>/dev/null || true +# shellcheck disable=SC2034 # read by the sourced substrate (post_slack_alarm) via dynamic scope +SWEEP_LOG="$REPORT_DIR/doc-drift.log" # name the substrate's post_slack_alarm() references +REPORT_JSON="$REPORT_DIR/doc-drift.json" +REPORT_TXT="$REPORT_DIR/doc-drift.txt" + +# doc-drift makes NO API calls, so DO_API is a documented no-op kept only for coordinator +# flag-parity; surface it in the run banner so the chosen value is auditable (and used). +log "=== doc-drift $UTC_STAMP (canary=$CANARY dry_run=$DRY_RUN refresh=$REFRESH api=${DO_API}[no-op] stale_days=$DOC_DRIFT_STALE_DAYS stale_commits=$DOC_DRIFT_STALE_COMMITS) ===" + +# ------------------------------------------------------------------------------ +# CHECKLIST (grounded — every item cites the README obligation; nothing invented): +# +# readme-omits-component README exists but omits a major existing component +# present in the tree (top-level service dir, SAM/CDK stack, +# Lambda handler dir, openapi/docs API spec) +# -> global CLAUDE.md: "README must accurately describe +# architecture, services, data flow, and configuration" +# readme-stale-vs-code README last-touched commit far older than the newest code +# commit (>= DOC_DRIFT_STALE_DAYS) AND >= DOC_DRIFT_STALE_COMMITS +# substantial code commits landed after the README was touched +# -> global CLAUDE.md: "update the README in the same commit" +# +# A repo with NO README is SKIPPED (compliance-drift owns readme-present; double-flagging would +# be a false alarm). Each emitted finding follows the spirit of finding.schema.json +# (id/title/severity/category/proof/status) so the coordinator can route it like an agentic +# finding. category="other" (doc drift is not one of the schema's security categories). +# status="confirmed" only for deterministic filesystem/git-history facts. The future Gemini +# judge (design §4) is an inert stub (maybe_judge) — never invoked offline / in this phase. +# ------------------------------------------------------------------------------ + +# Drift accumulator: one JSON object per finding, appended to a bash array. +declare -a FINDINGS=() +add_finding() { # repo id title severity check proof + local repo="$1" id="$2" title="$3" sev="$4" check="$5" proof="$6" + FINDINGS+=( "$(jq -n \ + --arg repo "$repo" --arg id "$id" --arg title "$title" --arg sev "$sev" \ + --arg check "$check" --arg proof "$proof" \ + '{repo:$repo, id:($repo+"-"+$id), title:$title, severity:$sev, category:"other", + check:$check, status:"confirmed", proof:{outcome:$proof}}')" ) +} +declare -a SKIPPED_CHECKS=() # (repo:check) checks skipped on missing data — reported, never alarmed +note_skip() { SKIPPED_CHECKS+=( "$1" ); } + +in_csv() { # needle csv -> 0 if present + local n="$1" csv="$2"; case ",$csv," in *",$n,"*) return 0 ;; *) return 1 ;; esac +} + +# Inert future seam (design §4 "Gemini (large context)" judge): in LIVE mode an ambiguous +# omission ("is this component material enough to require a README mention?") could be escalated +# to a large-context judge. This phase keeps the deterministic core ONLY — the stub does nothing +# and is never reached offline / in canary / dry-run. +maybe_judge() { # candidate_json (no-op stub; Phase-3 intentionally inert) + return 0 +} + +# --- Does a README mention a component name? (case-insensitive, word-ish, deterministic) ---- +# Matches the bare name OR the name with a trailing slash (how a dir is usually cited). Strips +# a leading "the " never matters; we test the literal token. Pure grep, no fuzzy matching. +readme_mentions() { # readme_file name + local rf="$1" name="$2" + # Escape regex metacharacters in the component name (defensive; dir names are usually plain). + local esc; esc="$(printf '%s' "$name" | sed -E 's/[][(){}.*+?^$|\\/]/\\&/g')" + grep -qiE "(^|[^A-Za-z0-9_-])${esc}([^A-Za-z0-9_-]|/|$)" "$rf" 2>/dev/null +} + +# --- Enumerate the major components present in a repo tree (deterministic) ------ +# Emits "TYPElabelmention_token" lines. mention_token is what the README must contain. +# service-dir a top-level directory whose name ends in -service or -api, or named api/web/worker +# sam-cdk-stack a SAM/CDK stack root (template.yaml | app.py at a stack root | cdk.json) +# lambda-dir a Lambda handler dir (a dir named handlers/ or containing handler.* / app.py under handlers/) +# api-spec an openapi/ or docs/ directory or an openapi.* / swagger.* spec file +enumerate_components() { # repo_dir -> TSV lines + local dir="$1" d nm + + # 1) top-level service-ish directories (the unit a README is expected to name) + for d in "$dir"/*/; do + [ -d "$d" ] || continue + nm="$(basename "$d")" + case "$nm" in + .git|.github|node_modules|dist|build|vendor|__pycache__|.venv) continue ;; + esac + case "$nm" in + *-service|*-api|api|web|worker|backend|frontend) + printf 'service-dir\t%s\t%s\n' "$nm" "$nm" ;; + esac + done + + # 2) SAM / CDK stack roots + if [ -f "$dir/template.yaml" ] || [ -f "$dir/template.yml" ]; then + printf 'sam-cdk-stack\t%s\t%s\n' "template.yaml (SAM stack)" "template.yaml" + fi + if [ -f "$dir/cdk.json" ]; then + printf 'sam-cdk-stack\t%s\t%s\n' "cdk.json (CDK app)" "cdk.json" + fi + + # 3) Lambda handler dirs: a top-level/handlers-rooted dir literally named "handlers" + while IFS= read -r d; do + [ -n "$d" ] || continue + printf 'lambda-dir\t%s\t%s\n' "handlers/ (Lambda handlers)" "handlers" + break # one mention requirement for the handlers tree is enough + done < <(find "$dir" -maxdepth 2 -type d -name handlers -not -path '*/.git/*' 2>/dev/null) + + # 4) API spec: an openapi/ or docs/ dir, or an openapi.*/swagger.* file + if [ -d "$dir/openapi" ]; then + printf 'api-spec\t%s\t%s\n' "openapi/ (API spec)" "openapi" + elif find "$dir" -maxdepth 2 \( -iname 'openapi.*' -o -iname 'swagger.*' \) -not -path '*/.git/*' -print -quit 2>/dev/null | grep -q .; then + printf 'api-spec\t%s\t%s\n' "openapi/swagger spec" "openapi" + fi +} + +# --- README last-touch epoch vs newest code commit (staleness, deterministic git log) ------- +# Returns the staleness facts on stdout as TSV "readme_epochnewest_code_epochcommits_after". +# commits_after = count of commits that touched code (non-doc) files AFTER the README's last touch. +# Code = anything that is NOT a README/markdown/LICENSE/.gitignore/docs file. Prints nothing if +# the repo has no git history or no README in history (caller treats that as "cannot assess"). +readme_staleness_facts() { # repo_dir + local dir="$1" + command -v git >/dev/null || return 0 + git -C "$dir" rev-parse --git-dir >/dev/null 2>&1 || return 0 + + # README last-touch (committer epoch of the most recent commit touching README.md). + local rd_epoch + rd_epoch="$(git -C "$dir" log -1 --format='%ct' -- README.md 2>/dev/null || true)" + [ -n "$rd_epoch" ] || return 0 # README not in history -> cannot assess staleness + + # Newest commit touching a CODE path (exclude docs/markdown/license/config-noise). + local code_epoch + code_epoch="$(git -C "$dir" log -1 --format='%ct' -- \ + ':(exclude)README.md' ':(exclude)*.md' ':(exclude)docs/**' \ + ':(exclude)LICENSE' ':(exclude).gitignore' ':(exclude).github/**' \ + 2>/dev/null || true)" + [ -n "$code_epoch" ] || return 0 # no code commits -> nothing to be stale against + + # Count CODE commits strictly AFTER the README's last touch. + local commits_after + commits_after="$(git -C "$dir" rev-list --count "--since=@${rd_epoch}" HEAD -- \ + ':(exclude)README.md' ':(exclude)*.md' ':(exclude)docs/**' \ + ':(exclude)LICENSE' ':(exclude).gitignore' ':(exclude).github/**' \ + 2>/dev/null || echo 0)" + printf '%s\t%s\t%s\n' "$rd_epoch" "$code_epoch" "${commits_after:-0}" +} + +# ============================================================================== +# PER-REPO CHECK (offline; filesystem + local git log only) +# ============================================================================== +check_repo() { # repo_name repo_dir + local repo="$1" dir="$2" + local docs_only=0; in_csv "$repo" "$DOCS_ONLY_REPOS" && docs_only=1 + + # No README -> doc-drift cannot assess drift; compliance-drift owns readme-present. SKIP. + if [ ! -f "$dir/README.md" ]; then + note_skip "$repo:doc-drift(no-readme — compliance-drift owns readme-present)" + return + fi + local readme="$dir/README.md" + + # --- readme-omits-component (skip for docs-only repos: they document differently) --- + if [ "$docs_only" -eq 0 ]; then + local type label token + while IFS=$'\t' read -r type label token; do + [ -n "$token" ] || continue + if ! readme_mentions "$readme" "$token"; then + add_finding "$repo" "readme-omits-$(printf '%s' "$type-$token" | tr -c 'A-Za-z0-9-' '-')" \ + "README omits existing component: $label" "medium" "readme-omits-component" \ + "global CLAUDE.md: README must accurately describe architecture/services (present in tree, absent from README: $label)" + fi + done < <(enumerate_components "$dir") + else + note_skip "$repo:readme-omits-component(docs-only)" + fi + + # --- readme-stale-vs-code (two-factor: age in days AND code-commits-after) --- + local facts; facts="$(readme_staleness_facts "$dir")" + if [ -z "$facts" ]; then + note_skip "$repo:readme-stale-vs-code(no-history-or-no-readme-in-history)" + else + local rd_epoch code_epoch commits_after age_days + IFS=$'\t' read -r rd_epoch code_epoch commits_after <<< "$facts" + age_days=$(( (code_epoch - rd_epoch) / 86400 )) + [ "$age_days" -lt 0 ] && age_days=0 + if [ "$age_days" -ge "$DOC_DRIFT_STALE_DAYS" ] && [ "$commits_after" -ge "$DOC_DRIFT_STALE_COMMITS" ]; then + add_finding "$repo" "readme-stale" \ + "README is stale: ${age_days}d behind newest code, ${commits_after} code commit(s) since last README touch" \ + "medium" "readme-stale-vs-code" \ + "global CLAUDE.md: update the README in the same commit as functionality changes (thresholds: >=${DOC_DRIFT_STALE_DAYS}d AND >=${DOC_DRIFT_STALE_COMMITS} code commits)" + fi + fi + + maybe_judge "" # inert in this phase (future Gemini large-context seam) +} + +# ============================================================================== +# TARGET RESOLUTION +# ============================================================================== +declare -a REPO_NAMES=(); declare -A REPO_DIR=() + +if [ "$CANARY" -eq 1 ]; then + FIXTURE_ROOT="$HERE/fixtures/doc-drift" + [ -d "$FIXTURE_ROOT" ] || die "canary fixture missing: $FIXTURE_ROOT" + # Pin the exception lists + thresholds the fixtures were authored against, so the canary is + # self-contained and deterministic regardless of the operator's env. + DOCS_ONLY_REPOS="" + DOC_DRIFT_STALE_DAYS=60 + DOC_DRIFT_STALE_COMMITS=3 + # Fixtures ship their git metadata as `dotgit/` (not `.git/`) so they are committable into THIS + # repo without becoming nested submodules. Materialize them into a temp work area — copy each + # fixture and rename dotgit -> .git — so the README/git-log checks run against a real git + # checkout. The temp area is mode 700 and removed on exit (same trick as compliance-drift.sh). + FIXTURE_WORK="$(mktemp -d "${TMPDIR:-/tmp}/doc-drift-canary.XXXXXX")" + trap 'rm -rf "$FIXTURE_WORK"' EXIT + log "canary: materializing planted-drift fixtures from $FIXTURE_ROOT into $FIXTURE_WORK" + for d in "$FIXTURE_ROOT"/*/; do + [ -d "$d/dotgit" ] || continue # only fixture repos (skip README.md, EXPECTED_* etc.) + nm="$(basename "$d")" + cp -R "$d" "$FIXTURE_WORK/$nm" + mv "$FIXTURE_WORK/$nm/dotgit" "$FIXTURE_WORK/$nm/.git" + REPO_NAMES+=( "$nm" ); REPO_DIR["$nm"]="$FIXTURE_WORK/$nm" + done +elif [ -n "$TARGETS_OVERRIDE" ]; then + # shellcheck disable=SC2206 # intentional word-split of the space-separated --targets list + arr=( $TARGETS_OVERRIDE ) + for p in "${arr[@]}"; do p="${p/#\~/$HOME}"; nm="$(basename "$p")"; REPO_NAMES+=( "$nm" ); REPO_DIR["$nm"]="$p"; done + log "explicit targets: ${REPO_NAMES[*]}" +else + if [ "$REFRESH" -eq 1 ]; then + [ -n "${GH_TOKEN:-}" ] || die "--refresh needs GH_TOKEN" + command -v curl >/dev/null || die "--refresh needs curl" + mkdir -p "$MIRROR_DIR" + log "refresh: re-discovering + mirroring via shared substrate (no separate clone path)" + DISCOVERED="$REPORT_DIR/discovered.tsv" + if discover_repos > "$DISCOVERED" 2>>"$REPORT_DIR/discover.log" && [ -s "$DISCOVERED" ]; then + while IFS=$'\t' read -r name url branch; do + [ -n "$name" ] || continue + mirror_repo "$name" "$url" "$branch" || log " mirror FAILED: $name (will use stale mirror if present)" + done < "$DISCOVERED" + else + log "discovery failed — falling back to existing mirrors (coverage may be stale)" + fi + fi + # Default + post-refresh: enumerate EXISTING mirrors. No clone here — reuse the sweep's clones. + [ -d "$MIRROR_DIR" ] || die "mirror dir not found: $MIRROR_DIR (run nightly_sweep.sh first, or use --refresh/--targets)" + for d in "$MIRROR_DIR"/*/; do + [ -d "$d/.git" ] || continue + nm="$(basename "$d")"; REPO_NAMES+=( "$nm" ); REPO_DIR["$nm"]="${d%/}" + done + log "reusing ${#REPO_NAMES[@]} existing mirror(s) in $MIRROR_DIR (no re-clone)" +fi + +[ "${#REPO_NAMES[@]}" -gt 0 ] || die "no repos to scan" + +# ============================================================================== +# RUN CHECKS +# ============================================================================== +for nm in "${REPO_NAMES[@]}"; do + check_repo "$nm" "${REPO_DIR[$nm]}" +done + +# ============================================================================== +# ASSEMBLE REPORT (JSON + text), mode 600 (identical shape to compliance-drift) +# ============================================================================== +if [ "${#FINDINGS[@]}" -gt 0 ]; then + FINDINGS_JSON="$(printf '%s\n' "${FINDINGS[@]}" | jq -cs .)" +else + FINDINGS_JSON="[]" +fi +if [ "${#SKIPPED_CHECKS[@]}" -gt 0 ]; then + SKIPPED_JSON="$(printf '%s\n' "${SKIPPED_CHECKS[@]}" | jq -R . | jq -cs .)" +else + SKIPPED_JSON="[]" +fi + +N_DRIFT="$(echo "$FINDINGS_JSON" | jq 'length')" +N_HIGH="$(echo "$FINDINGS_JSON" | jq '[.[]|select(.severity=="high")] | length')" +N_REPOS_DRIFTED="$(echo "$FINDINGS_JSON" | jq '[.[].repo] | unique | length')" + +jq -n \ + --arg checker "doc-drift" --arg ts "$UTC_STAMP" --arg org "$GH_ORG" \ + --argjson scanned "${#REPO_NAMES[@]}" \ + --argjson findings "$FINDINGS_JSON" --argjson skipped "$SKIPPED_JSON" \ + '{checker:$checker, generated:$ts, org:$org, + repos_scanned:$scanned, drift_count:($findings|length), + repos_with_drift:([$findings[].repo]|unique|length), + findings:$findings, skipped_checks:$skipped}' > "$REPORT_JSON" + +{ + echo "doc-drift report — $UTC_STAMP" + echo "org=$GH_ORG repos_scanned=${#REPO_NAMES[@]} stale_thresholds=${DOC_DRIFT_STALE_DAYS}d/${DOC_DRIFT_STALE_COMMITS}commits" + echo "drift findings: $N_DRIFT ($N_HIGH high) across $N_REPOS_DRIFTED repo(s)" + echo + echo "$FINDINGS_JSON" | jq -r '.[] | "• [\(.severity)] \(.repo): \(.title)\n rule: \(.proof.outcome)"' + if [ "$(echo "$SKIPPED_JSON" | jq 'length')" -gt 0 ]; then + echo; echo "skipped checks (missing data / not doc-drift's job — NOT counted as drift):" + echo "$SKIPPED_JSON" | jq -r '.[] | " - \(.)"' + fi +} > "$REPORT_TXT" +chmod 600 "$REPORT_JSON" "$REPORT_TXT" 2>/dev/null || true + +log "report: $REPORT_JSON ($N_DRIFT drift finding(s), $N_REPOS_DRIFTED repo(s))" + +# ============================================================================== +# CANARY ASSERTION (anti-complacency floor, design §6.4) +# ============================================================================== +if [ "$CANARY" -eq 1 ]; then + EXPECT_FILE="$HERE/fixtures/doc-drift/EXPECTED_DRIFT_COUNT" + [ -f "$EXPECT_FILE" ] || die "canary expected-count file missing: $EXPECT_FILE" + EXPECTED="$(tr -dc '0-9' < "$EXPECT_FILE")" + log "canary assertion: expected drift=$EXPECTED, got=$N_DRIFT" + if [ "$N_DRIFT" -ne "$EXPECTED" ]; then + echo "[doc-drift] CANARY FAIL: planted-drift count mismatch (expected $EXPECTED, got $N_DRIFT)" >&2 + echo " -> the checklist regressed (a check stopped firing) or the fixture changed. See $REPORT_TXT." >&2 + exit 3 + fi + log "canary PASS: all $EXPECTED planted drifts detected." +fi + +# ============================================================================== +# ALARM-ONLY ROUTING (clean = silent; memory feedback_cloudwatch_alarms) +# ============================================================================== +if [ "$N_DRIFT" -eq 0 ]; then + log "no confirmed drift — posting NOTHING to Slack (ALARM-only policy)." + exit 0 +fi + +ALARM_BODY="$(echo "$FINDINGS_JSON" | jq -r ' + group_by(.repo)[] | "*\(.[0].repo)*: " + ([.[] | "[\(.severity)] \(.title)"] | join("; "))' | sed 's/^/• /')" +SLACK_TEXT=":memo: *Sea Haven doc-drift — ALARM* ($UTC_STAMP) +$N_DRIFT documentation-drift finding(s) across $N_REPOS_DRIFTED repo(s) ($N_HIGH high): +$ALARM_BODY + +Checks: README-omits-component · README-stale-vs-code (architecture moved, docs did not) +Report (mode 600): \`$REPORT_JSON\` (on R720)" +SLACK_TEXT="$(echo "$SLACK_TEXT" | redact)" + +echo "$SLACK_TEXT" >&2 + +if [ "$DRY_RUN" -eq 1 ]; then + log "DRY-RUN: alarm composed but NOT posted (routing dry-run, design §7 Phase 3)." + exit 0 +fi +post_slack_alarm "$SLACK_TEXT" +exit 0 + +# ============================================================================== +# PROVISIONING (NOT DONE HERE — gated, Phase 3 / Phase 6): +# - No systemd unit / timer is installed by this script. Wiring it into the live +# sea-haven-secrev schedule (or a sibling timer) is provisioning and is gated. +# - This script is NOT registered in checker_coordinator.sh; the coordinator registry is +# integrated centrally (separate change), so doc-drift is not yet driven by the coordinator. +# - step-ca / IAM Roles Anywhere / the read-only AWS role / aws-posture are NOT stood up or +# built here. The IAM artifacts authored alongside this checker (security-review/iam/) are +# FILES for the mandatory GPT-4.1 cross-review; aws-posture itself is hard-gated behind that +# review and is built only after it is recorded (design §7, B3). +# - The LIVE "Gemini (large context)" doc-drift judge (design §4) is the only LLM seam; it is +# an inert stub here (maybe_judge) and stays off in canary / dry-run / offline. +# - Confluence + project_r720_agent_team memory updates are docs-as-you-go obligations for the +# build session, tracked outside this script. +# ============================================================================== diff --git a/security-review/checkers/fixtures/doc-drift/EXPECTED_DRIFT_COUNT b/security-review/checkers/fixtures/doc-drift/EXPECTED_DRIFT_COUNT new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/EXPECTED_DRIFT_COUNT @@ -0,0 +1 @@ +4 diff --git a/security-review/checkers/fixtures/doc-drift/README.md b/security-review/checkers/fixtures/doc-drift/README.md new file mode 100644 index 0000000..248364c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/README.md @@ -0,0 +1,43 @@ +# doc-drift canary fixtures + +Planted-drift corpus for `checkers/doc-drift.sh --canary` (offline, no network/token). +The checker asserts the total drift count equals `EXPECTED_DRIFT_COUNT` (anti-complacency +floor, design §6.4). If a check regresses (stops firing), the count drops and the canary +FAILS (exit 3). + +doc-drift flags repos whose **architecture moved but the README did not** (design §4, +doc-drift row). It is deliberately deterministic and grounded — no fuzzy LLM judgment. The +LLM judge layer (Gemini large-context) is a later enhancement and is inert offline (see the +`maybe_judge` stub in the checker). + +Each fixture is a real git checkout (its `.git` is shipped as `dotgit/` so it commits into +THIS repo without becoming a nested submodule; the checker renames it back to `.git/` at run +time, the same trick `compliance-drift.sh` / `dependency-cve.sh` use). Real commit history is +required because the staleness check reads `git log` dates. + +## Detected drift (the deterministic checklist) + +| Check | Rule cited | What fires | +|---|---|---| +| `readme-omits-component` | global CLAUDE.md: "README must accurately describe architecture, services, data flow" | A README exists but omits mention of a major existing component present in the tree: a top-level service dir, a SAM/CDK stack (`template.yaml` / `app.py` / `cdk.json`), a Lambda handler dir, or an `openapi`/`docs` API spec. | +| `readme-stale-vs-code` | global CLAUDE.md: "update the README in the same commit" as functionality changes | The README's last-touched commit is far older than the newest code commit (≥ `DOC_DRIFT_STALE_DAYS` days) AND ≥ `DOC_DRIFT_STALE_COMMITS` substantial code commits landed after the README was last touched. | + +A repo with **no README at all** is SKIPPED by doc-drift, not flagged — `readme-present` is +`compliance-drift.sh`'s job, and double-flagging would be a false alarm +(memory `feedback_cloudwatch_alarms`). + +## Fixtures + +| Fixture | Planted drift | Count | +|---|---|---| +| `clean-repo` | none — README names every component (`api/`, the SAM stack, `handlers/`, `openapi/`) and the README was committed alongside the code | 0 | +| `drift-omits-repo` | README mentions only `notifier-service`; omits `payments-service/`, the SAM `template.yaml` stack, and the `handlers/charge` Lambda dir | 3 | +| `drift-stale-repo` | README names its one component (no omission) but was last touched 2026-01-05 while 5 substantial code commits landed in 2026-06 — stale | 1 | +| `no-readme-repo` | no README — doc-drift SKIPS it (must NOT fire; compliance-drift owns this) | 0 | + +Total = **4** (`EXPECTED_DRIFT_COUNT`). The canary pins the staleness thresholds it was +authored against (`DOC_DRIFT_STALE_DAYS`, `DOC_DRIFT_STALE_COMMITS`) internally so it is +deterministic regardless of the operator's env. + +When you add/remove a check or fixture, update both the fixture and `EXPECTED_DRIFT_COUNT` +in the same commit (the canary edit is itself caught on the next run — design §6.4). diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/README.md b/security-review/checkers/fixtures/doc-drift/clean-repo/README.md new file mode 100644 index 0000000..bfde979 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/README.md @@ -0,0 +1,10 @@ +# clean-repo + +Well-documented service. Architecture: + +- The **api/** service exposes the public HTTP surface. +- A SAM stack (see template.yaml) provisions the IngestFn Lambda. +- Lambda handler code lives under handlers/ingest. +- The HTTP contract is published in the openapi/ spec. + +Data flow: api -> IngestFn -> downstream. diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/api/main.go b/security-review/checkers/fixtures/doc-drift/clean-repo/api/main.go new file mode 100644 index 0000000..06ab7d0 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/api/main.go @@ -0,0 +1 @@ +package main diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/COMMIT_EDITMSG b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/COMMIT_EDITMSG new file mode 100644 index 0000000..ffc6555 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/COMMIT_EDITMSG @@ -0,0 +1 @@ +init: code + matching README diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/HEAD b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/HEAD new file mode 100644 index 0000000..b870d82 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/config b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/config new file mode 100644 index 0000000..8bb2ccd --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/config @@ -0,0 +1,10 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true +[user] + email = t@t + name = t diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/description b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/applypatch-msg.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/commit-msg.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/fsmonitor-watchman.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/post-update.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-applypatch.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-commit.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-merge-commit.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-push.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-rebase.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-receive.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/prepare-commit-msg.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/push-to-checkout.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/update.sample b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/index b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/index new file mode 100644 index 0000000000000000000000000000000000000000..e228a0ee2a1f158de715ab844129b0436052fbd7 GIT binary patch literal 589 zcmZ?q402{*U|<4b)+`h6Tx02tVKADJfq|b_=WI9wL*o(#2F9;IH6lRTb^pETv*sR3 zUiELrJ<&Z(eluJ+Tdp&32Dv)A_`2%lrZ9l@GfLOMXs9`1sOB*6vaPP=pJlrIB0IaF zXKv2I)16wX{S4fR1)2J}iJ5tN>G?nlK>%cq(Z6MrVKmgd5H$0Y<=f19GW|~5&P}Q4 zn$fdlsac%w4+gP}#JrT8)S_bj%)Io};u8JDf&#sQN|?FE4E$MOcLHgsxuIz0iYyA5 zrug|Bt9!Zhw5RqWkN#ZuvI}4k%r8jI1G%-hAT?Ppt2jRo;?7@B>cQ>=(opk)(9G)y zG%7wkd71tG?|E(~R=gFRee;Et3 1780329600 -0400 commit (initial): init: code + matching README diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/logs/refs/heads/main b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/logs/refs/heads/main new file mode 100644 index 0000000..d44addb --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 e5c55ac820d3272863a874fc1e202908241c2acf t 1780329600 -0400 commit (initial): init: code + matching README diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/06/ab7d0f9a35a7d1070711496d6ca1cb892a258f b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/06/ab7d0f9a35a7d1070711496d6ca1cb892a258f new file mode 100644 index 0000000000000000000000000000000000000000..8182c9ae6ae6c73694255c738d8711d4314a07de GIT binary patch literal 29 lcmb=n3C5XC5;#conhj2LP&G3!VS~ literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/0b/5c163a57c647bd824a907f7e0b9aa6335a7d77 b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/0b/5c163a57c647bd824a907f7e0b9aa6335a7d77 new file mode 100644 index 0000000000000000000000000000000000000000..657ddba080a028ef40bb4618ad04712879fcc561 GIT binary patch literal 184 zcmV;p07w6L0V^p=O;s>7H)k+3FfcPQQ3!H%bn$i7%S~a}e{cG%xrdTh{hM)5bPto? z3>VIp>m~+3ppaOQ$*@zM_d7e!v8B&%-#aF-{G5Ntk!l5qY(`>UN=|A~F~d#qe!u6v z*OF@$=KIwi=aSf%uzwarNq#|U9>|c6q7PTRfA3!?>||WNMRfZ5{#B=Yq3$S2%`M1D mEJ@X?Ow7$;2sA1_Jb9V@{_lBiCsw=_oqh9#l?(udwoIQ@?^-4R literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/1f/86368c694ecb3d9d64788a988ca4a5365e4df8 b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/1f/86368c694ecb3d9d64788a988ca4a5365e4df8 new file mode 100644 index 0000000000000000000000000000000000000000..502fcf6cbd47b0dbbeabee332e1149d45ec0bdda GIT binary patch literal 51 zcmV-30L=e*0ZYosPf{>8Wk^X)Q^-inOUX$s(nu{!%`4GSNG_?+v{EQaEh#O^Q>d=x J0suMs4u2jN6$=0W literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/51/3273c393a63fbff76e46c8a8ed159bd9e83a1c b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/51/3273c393a63fbff76e46c8a8ed159bd9e83a1c new file mode 100644 index 0000000..dee7780 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/51/3273c393a63fbff76e46c8a8ed159bd9e83a1c @@ -0,0 +1 @@ +xe�1 Â0F�ó+nëH,¼Í%àjC�ÓrŠ�&å.ü÷=gáÞðßœë ¾N×ÇiÝrj*¯©MÄò®¡;;כּè:9yª€ âHü!Î$bU¬š½7w’ºóB‚àV^$-”ÄïF-bØËÒôÎí¥-¡ \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/88/72f0d44bfbbfa113423377b41597af8faacb8d b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/88/72f0d44bfbbfa113423377b41597af8faacb8d new file mode 100644 index 0000000000000000000000000000000000000000..79dfdce897fb010d7023853adf80d223cb86f160 GIT binary patch literal 54 zcmbnitm=etyK K1_s}^0!IJ@qZOP0 literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/98/ec3d6272badf42441f11b2c53b42961a33f5f7 b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/98/ec3d6272badf42441f11b2c53b42961a33f5f7 new file mode 100644 index 0000000000000000000000000000000000000000..afd3888f9903964c1ac3288242e18085e0a9e1e8 GIT binary patch literal 50 zcmbM0XL)du#102u!dZvX%Q literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/b9/270df7070cc6a5e7dbdec610a7ce4f54c47b20 b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/b9/270df7070cc6a5e7dbdec610a7ce4f54c47b20 new file mode 100644 index 0000000..302def6 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/b9/270df7070cc6a5e7dbdec610a7ce4f54c47b20 @@ -0,0 +1 @@ +x+)JMU06e040031QÈMÌÌÓKÏg`[]Ë?ËtùEvvAÏÜœ…§;µTû É \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/bf/de979a9dc263aafe98de15bc024e98440984d7 b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/bf/de979a9dc263aafe98de15bc024e98440984d7 new file mode 100644 index 0000000..ed685cd --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/bf/de979a9dc263aafe98de15bc024e98440984d7 @@ -0,0 +1 @@ +x=�AKÄ0…=çW<ð¢…vAñ²¡ ¢  Xð9W-u`T0)@=H^wi=Kh8b^clZtlTcXE*z+;r61X_}Pr*Y5xt GJr8`-MipBC literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/e5/c55ac820d3272863a874fc1e202908241c2acf b/security-review/checkers/fixtures/doc-drift/clean-repo/dotgit/objects/e5/c55ac820d3272863a874fc1e202908241c2acf new file mode 100644 index 0000000000000000000000000000000000000000..c21c63846aa2e2d86adf01f76d7d1faa012365d9 GIT binary patch literal 125 zcmV-@0D}K`0e#F%3c@fD08rOC#q33xG@ogTh=N_Z@dlGgv{|%)GTvYC0PY`8`nom+ z>)k>3S^;wq8yyFd=qZ\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/fsmonitor-watchman.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/post-update.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-applypatch.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-commit.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-merge-commit.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-push.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-rebase.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-receive.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/prepare-commit-msg.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/push-to-checkout.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/update.sample b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/index b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/index new file mode 100644 index 0000000000000000000000000000000000000000..3a1ce270d7a4ad0ad854ae24a7683c6ff96ef30b GIT binary patch literal 627 zcmZ?q402{*U|<4b)+`h6atQ{VjWC*#fq|b_=Ufs4L*o(#2F9;IH6lPf+01Z(b9(EQ z)`K6Cf9O9ejm`P_u9JZ?$koxs*Hte!g#n~r{8`j@7!5Ti9?cwO`8KnjOuy5%b5kn1 zX7nssY8L1FgF!4KF)t-2wWwG>IU}(sJyk!kpg^yn5@;{P+!uXvU~_>q)Z9cgb46!0 zUJO6Ncue~Bha>L|@6?)?zumKoK_V}|Br`2DwMe%(wWusJIaNP5F*6TrGT6N56WL%i z)Z7GgbI)vC_rSwx{fRpppKbp%>0a->ul&Uf5(SBsxv6<2#W>7;bQm0-;y@Z|ZY-L) z9kW#KJY2c($ksjT)zR8Q2SG%4e+-_e5ztZ>?QzHc$ds~)&(T5}pn9{)M*;k94r yeg-R?C8l+Bxy09P#YZi6-8W@BSUaQtM0H+#$}@@GZfmE0)0op+s`8wzGamp$wB%X< literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/info/exclude b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/HEAD b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/HEAD new file mode 100644 index 0000000..b2878de --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 ff9ded83431a6059a99140b744c351e43bb04eed t 1781107200 -0400 commit (initial): init diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/refs/heads/main b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/refs/heads/main new file mode 100644 index 0000000..b2878de --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 ff9ded83431a6059a99140b744c351e43bb04eed t 1781107200 -0400 commit (initial): init diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/19/366a9a93232cf60a444d9a1d4114bc55084d0f b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/19/366a9a93232cf60a444d9a1d4114bc55084d0f new file mode 100644 index 0000000000000000000000000000000000000000..3a527c2a540f4d26525a0f68e4d8661e2075eca2 GIT binary patch literal 201 zcmV;)05<=40V^p=O;s?ov}73=;D_WN`p-&Z zbAG<-G%)}Ig^a|!l$_L}VupovSu@^#@6GWK;W|}5S-a7-p&5dAM@nk*#~wtE1n&edBpG!K)MiPTpAR DsfuM+ literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/1f/86368c694ecb3d9d64788a988ca4a5365e4df8 b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/1f/86368c694ecb3d9d64788a988ca4a5365e4df8 new file mode 100644 index 0000000000000000000000000000000000000000..502fcf6cbd47b0dbbeabee332e1149d45ec0bdda GIT binary patch literal 51 zcmV-30L=e*0ZYosPf{>8Wk^X)Q^-inOUX$s(nu{!%`4GSNG_?+v{EQaEh#O^Q>d=x J0suMs4u2jN6$=0W literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/36/31a0436785d485c1f063f82fe6755d6cf9ee89 b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/36/31a0436785d485c1f063f82fe6755d6cf9ee89 new file mode 100644 index 0000000..f469015 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/36/31a0436785d485c1f063f82fe6755d6cf9ee89 @@ -0,0 +1,2 @@ +xeÍM +1 @a×=EÀ]¡‚àEz�þdH 6’dôúÆ�Û¯©p»?.WèÊ»'y²[R|I™ØÀPßܨÌ>Ð`Šóέ8Ë´-„™b<;jú��Ý@¯rÌþ'3‡uðå?$¡h#vl~(ná e¼6q \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/96/f70ef65cc77ae047293b093219c7f996e1d6fa b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/96/f70ef65cc77ae047293b093219c7f996e1d6fa new file mode 100644 index 0000000000000000000000000000000000000000..5b2b01f9f13def28c8d52830a3ce6ac0d985c382 GIT binary patch literal 52 zcmV-40L%Y)0V^p=O;s>9WiT`_Ff%bx$W6@5(<`WCnALbO{0QSQ>DM2Qyf?g4YhM0# K&n^H%F%nh|U=?Tp literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/98/ec3d6272badf42441f11b2c53b42961a33f5f7 b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/98/ec3d6272badf42441f11b2c53b42961a33f5f7 new file mode 100644 index 0000000000000000000000000000000000000000..afd3888f9903964c1ac3288242e18085e0a9e1e8 GIT binary patch literal 50 zcmbcR&;VSXi60coj{)LmqrVn0>}6?sXTIo5ErCJbI=}z` literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/9a/81d157c401c61bebf0c4ef31dc7d3777edbcba b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/9a/81d157c401c61bebf0c4ef31dc7d3777edbcba new file mode 100644 index 0000000000000000000000000000000000000000..c040cc4851fac9e73cae48c76e4b99e2346f2be3 GIT binary patch literal 35 rcmb9W-u`T0)^y^#G>?6h8b^clZtlTcXE*z+;r61X_}Pr*Y5xq GLl0cd+7%c8 literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/cc/b1aee04842afc8dcb1e6b7f292de8ddef50f73 b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/cc/b1aee04842afc8dcb1e6b7f292de8ddef50f73 new file mode 100644 index 0000000000000000000000000000000000000000..16e08353bb08f25131014772e38c9aa4ff6ac84e GIT binary patch literal 35 rcmb%a{F literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/ff/9ded83431a6059a99140b744c351e43bb04eed b/security-review/checkers/fixtures/doc-drift/drift-omits-repo/dotgit/objects/ff/9ded83431a6059a99140b744c351e43bb04eed new file mode 100644 index 0000000000000000000000000000000000000000..c4cb0bf86b686735b87396460ebbb904866e6f83 GIT binary patch literal 103 zcmV-t0GR)H0e#Ft3WP8W1yI*LMJ^!xw6PkH!K=i!Vi%4enfnjS0cQVr<-V@&#H@oq ztr2U=+0-<}6w8reB2v}33bX8Gny^U45$xmV{gBh@o4<(Xg&A`MXoLWv{9\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/fsmonitor-watchman.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/post-update.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-applypatch.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-commit.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-merge-commit.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-push.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-rebase.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-receive.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/prepare-commit-msg.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/push-to-checkout.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/update.sample b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/index b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/index new file mode 100644 index 0000000000000000000000000000000000000000..a4e5a466e31ee7abb89da729416da3dae646823c GIT binary patch literal 744 zcmZ?q402{*U|<4b_AC?c2B}wqtT399fq|b_=ez&|L*o(#2F9;IH6lPfU{Gd7Y>U##xAXi5hUst`{6b6uf8Rz}WVKmenV>ENbwyn_oq2P2gcI8bj zciy*$_g`++TLYv1ciB@C0p^4zsX+oaP&$nlIP=tPNy7h=!Va*JMa1vS$CD*=Dci4Yz=yk z(|i+D^A$e)6atwKqM_zbLN}jHBjVe&uYOUJxm?9NHG`Ffw=XipX}&3{`BE3QDuK)g z(NOdG(aab2Q7kQA>8aIVaC8P=Z2Gja_Qtol3}R^Uo12)K2Q@k*$ki1Xy$%fK3Wi*7 zt^^*q6S65}W4LPjmHvH+Rfn%zplW3>Q!wDVR@<}Z|Esf-A`4}Ua$8s2Z!vlqb$_#2 Wr}D9$TW(tg_N~e7+*`HP-v9s}4Djdx literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/info/exclude b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/HEAD b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/HEAD new file mode 100644 index 0000000..64f7bd2 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/HEAD @@ -0,0 +1,6 @@ +0000000000000000000000000000000000000000 7687db2a5781d77b42ced78a6bca02c37a8dbbf0 t 1767632400 -0500 commit (initial): init: worker-service + README +7687db2a5781d77b42ced78a6bca02c37a8dbbf0 af8b041ef281bb9d89401efcdf549a9a452f0ecf t 1781193600 -0400 commit: feat: add feature_1 to worker-service +af8b041ef281bb9d89401efcdf549a9a452f0ecf 93a7db735d0cfe42f0a57d956915f5e5a7f87378 t 1781280000 -0400 commit: feat: add feature_2 to worker-service +93a7db735d0cfe42f0a57d956915f5e5a7f87378 9c2018ca90ae8305bec517e0b8b91b5d8a755404 t 1781366400 -0400 commit: feat: add feature_3 to worker-service +9c2018ca90ae8305bec517e0b8b91b5d8a755404 6b7c13685ae818268d30ed3cf27c86da2820f186 t 1781452800 -0400 commit: feat: add feature_4 to worker-service +6b7c13685ae818268d30ed3cf27c86da2820f186 0cd9efe3a4957b0f5336c33f4e40e9e4d779c243 t 1781539200 -0400 commit: feat: add feature_5 to worker-service diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/refs/heads/main b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/refs/heads/main new file mode 100644 index 0000000..64f7bd2 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/logs/refs/heads/main @@ -0,0 +1,6 @@ +0000000000000000000000000000000000000000 7687db2a5781d77b42ced78a6bca02c37a8dbbf0 t 1767632400 -0500 commit (initial): init: worker-service + README +7687db2a5781d77b42ced78a6bca02c37a8dbbf0 af8b041ef281bb9d89401efcdf549a9a452f0ecf t 1781193600 -0400 commit: feat: add feature_1 to worker-service +af8b041ef281bb9d89401efcdf549a9a452f0ecf 93a7db735d0cfe42f0a57d956915f5e5a7f87378 t 1781280000 -0400 commit: feat: add feature_2 to worker-service +93a7db735d0cfe42f0a57d956915f5e5a7f87378 9c2018ca90ae8305bec517e0b8b91b5d8a755404 t 1781366400 -0400 commit: feat: add feature_3 to worker-service +9c2018ca90ae8305bec517e0b8b91b5d8a755404 6b7c13685ae818268d30ed3cf27c86da2820f186 t 1781452800 -0400 commit: feat: add feature_4 to worker-service +6b7c13685ae818268d30ed3cf27c86da2820f186 0cd9efe3a4957b0f5336c33f4e40e9e4d779c243 t 1781539200 -0400 commit: feat: add feature_5 to worker-service diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/06/2858f6d6f54e5a930a45178929532313b7a231 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/06/2858f6d6f54e5a930a45178929532313b7a231 new file mode 100644 index 0000000000000000000000000000000000000000..60a4d117a6559ddfcd4ecb7698f8abb45a79e3b5 GIT binary patch literal 38 ucmb#+¨ùB˜¹zô¶9̦®z]:(õ¬'p] +û­ ƒ�ÖúQù£˜&UP™áKk—K]à½ô›ôá)ý5‘˜²ù<œ \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/17/001f0544766545e2b63b2d3e7454ffa28cba39 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/17/001f0544766545e2b63b2d3e7454ffa28cba39 new file mode 100644 index 0000000000000000000000000000000000000000..5d7e3774863ea73fff719164161ace79f2d67b68 GIT binary patch literal 139 zcmV;60CfL&0V^p=O;s>7HDxd~FfcPQQAkToEGaEYjW^UQsASl-Li2}$)6LkGH@Vz- z-yYt7y|v;qnmQwpy8cDhwu}4AjyU!#We%R8&C+2O){myn7^Kc*sg4Xg*OB{4steys t6{lFApY+}ZsxCJ%GY_Q1N3pbgrKeVd!ODAR literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/5e/a038ee524a2a7200c3e4eb22febc5aeceb24a5 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/5e/a038ee524a2a7200c3e4eb22febc5aeceb24a5 new file mode 100644 index 0000000000000000000000000000000000000000..751f738cfa9f2b6c1570495e14490ab531bc2edd GIT binary patch literal 94 zcmV-k0HObQ0V^p=O;s?rU@$Z=Ff%bx2y%6F@paY9O<_2Gc_a zoO<=Wi2)EOl;;;^rxxiJrxulECZ{qa*cm1%=1WFKU%M~6#eY4&jaYv_08btuf0BPF A*8l(j literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/60/3e3162216f19595bd6df1db44faf0f3c168f8f b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/60/3e3162216f19595bd6df1db44faf0f3c168f8f new file mode 100644 index 0000000000000000000000000000000000000000..ea99a6748c203944651df9020dca3dfa2a937a44 GIT binary patch literal 51 zcmV-30L=e*0V^p=O;s>9WiT`_Ff%bx$W6@5(<`WC@KG!+U+JmUU~qH>Uu^ocvi8Qe Jxd0oJ4+isS6?p&v literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/64/74695394af5333896c7b296879398ef18776ca b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/64/74695394af5333896c7b296879398ef18776ca new file mode 100644 index 0000000..240db10 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/64/74695394af5333896c7b296879398ef18776ca @@ -0,0 +1 @@ +x+)JMU044e040031QHKM,)-J�7Ô+¨dضBó‡‚ÓÍØ•7¹ÜyßÞ½µâ3š:#�ºþEÖ¶‹ûËŽ8ö,ež ÍÒaÖU—›˜™Râ£XZ¾ÒS«Áàè ¾Øôieí�osþw.f \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/6b/7c13685ae818268d30ed3cf27c86da2820f186 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/6b/7c13685ae818268d30ed3cf27c86da2820f186 new file mode 100644 index 0000000..a80de5e --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/6b/7c13685ae818268d30ed3cf27c86da2820f186 @@ -0,0 +1,2 @@ +x}ÎA +1 @Q×=E. ¤�Ħ"âM$m3(¢#5êõEàî/Þâ·åz=;$Ä•3(3Ó¦ÑLš:öž,"KÊ9餽2ç"sÑp×a7‡ÒFiZPM&äj�c6¬RK¬ÜE33!}úià°óƒï!f‰ÄIa�„ÚoÄí ³©oA{‡o=‡ |�÷2.6Ö¯s³ð¦·<’ \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/87db2a5781d77b42ced78a6bca02c37a8dbbf0 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/87db2a5781d77b42ced78a6bca02c37a8dbbf0 new file mode 100644 index 0000000..3af3019 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/87db2a5781d77b42ced78a6bca02c37a8dbbf0 @@ -0,0 +1,2 @@ +x}ÌA +Â0Fa×9Åì¥0�L»tã Òð‹AÚ@õúŠp÷/×y.F½êÊ@‰ý¢IRæì¡˜D®˜rHÈßÖ\zÚ­62ÚÙÁöÔÇ!^”™:Ì.ÿƆ?Ä•¥Ø–ÞµÝѺÚ«dК.ãñtݽ,f \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/fcd8c1bd06f4648062d7865d83e0ec5279d8f8 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/76/fcd8c1bd06f4648062d7865d83e0ec5279d8f8 new file mode 100644 index 0000000000000000000000000000000000000000..8b238ccb307aae955123846d43700d0ab3341f83 GIT binary patch literal 95 zcmV-l0HFVP0V^p=O;s?rU@$Z=Ff%bx2y%6F@paY9O<_2Gc_a zoO<=Wi2)EOl;;;^rxxiJrxulECZ{s=Dk?^JeF<&M*f*hl>bjEqdzXpL0{~^TBNN{$ BE1&=X literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/8d/2121584af4558168be908795ae74dfbda6169e b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/8d/2121584af4558168be908795ae74dfbda6169e new file mode 100644 index 0000000000000000000000000000000000000000..0fa22fd32a7b9c9aab82d07c2ad9304275998391 GIT binary patch literal 86 zcmV-c0IC0Y0V^p=O;s>AWiT`_Ff%bxNJ~vDDJ@EkH`FVrWZ1Ss^M``d&DfPUx!if* s9^QYwwc;~WU2bA#9!QCgVrltGPpt-nqciwo)2EfSH@?jU0O-&l8Q2si9RL6T literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/8f/a23b3da38f76c4418ca50353902b048836568f b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/8f/a23b3da38f76c4418ca50353902b048836568f new file mode 100644 index 0000000000000000000000000000000000000000..466ddd242b140a8fcb81d583328f29e19fa981b6 GIT binary patch literal 38 ucmb7%Pe3J zcQTlvG}B_~*6Bn<+UiIRxj585g;b4BHMr=ay63?+fn+naLe@8|ot^2JJ+i~g+oa6|aqP8J8M40eHRevMGe-hO>%N}xT@U?C5*@CR_TE~^g^x*NF KE2}p}PCNY-y-`sB literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/9f/546c4f4a2d0dd2e1058184772a3adb55798f9a b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/9f/546c4f4a2d0dd2e1058184772a3adb55798f9a new file mode 100644 index 0000000000000000000000000000000000000000..6d38be2ca1b8f5ea1fcc023a4d9cb42391a18812 GIT binary patch literal 95 zcmV-l0HFVP0V^p=O;s?rU@$Z=Ff%bx2y%6F@paY9O<_2Gc_a zoO<=Wi2)EOl;;;^rxxiJrxulECZ{q)9=UPvukiCEd#w-bw%dGOyzvqf0swlnBLDF! BETsSd literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/a0/e549607d67e126ade87dc0bc5725af0f74b95d b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/a0/e549607d67e126ade87dc0bc5725af0f74b95d new file mode 100644 index 0000000000000000000000000000000000000000..a51ba9b973d94b9181622d8eed390f4fc1d8dfea GIT binary patch literal 94 zcmV-k0HObQ0V^p=O;s?rU@$Z=Ff%bx2y%6F@paY9O<_2Gc_a zoO<=Wi2)EOl;;;^rxxiJrxulECZ{r_lw<}^Ss!fNnNzKqQEA!tvAygR0AE@nM5>-D Ay#N3J literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/af/8b041ef281bb9d89401efcdf549a9a452f0ecf b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/af/8b041ef281bb9d89401efcdf549a9a452f0ecf new file mode 100644 index 0000000..d3dda4d --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/af/8b041ef281bb9d89401efcdf549a9a452f0ecf @@ -0,0 +1,2 @@ +x}ÎÁ Â0 @QΙ TrÒ6qBl‚Û‚¢àÂúàöïðy¹Ýfƒ€¸³¦ +)Vb_câ@ƒ$Š£P¯¨<†4 Ur�Üôn›§$%ä1‘—”ÊX7ŸcáŒ�û”IJ©èòj—¥�ÁÁNv¿y?õ:ÿFLÿW5Û²|kmzö` ¼—vÕÖ=µ½fV÷ Â=l \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/b6/a829f82042d95da9d90a470dedc3bfd78578f3 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/b6/a829f82042d95da9d90a470dedc3bfd78578f3 new file mode 100644 index 0000000000000000000000000000000000000000..ae678060a3cfbaaeee813797f203589b437cd006 GIT binary patch literal 38 ucmbc_a zoO<=Wi2)EOl;;;^rxxiJrxulECZ{rpGsv^Ll%={p+Gee5R}%7nQO_<*07VlZv%YsK A+5i9m literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/c7/d8d3f68781472c6b19cf938ddd41f02995d5ef b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/c7/d8d3f68781472c6b19cf938ddd41f02995d5ef new file mode 100644 index 0000000..556d642 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/c7/d8d3f68781472c6b19cf938ddd41f02995d5ef @@ -0,0 +1 @@ +x ËA Pלbw$4Ñ�kïà(üZ"epf°×—ý{kå•n÷ÇåJYÊfA-VAgç½v�÷'Ëò+ ÞSNP…’MðXœ{JÚ‹!ÙPQÊœÆ�fÈ[¦ÄG¯0PTâmÎIN)VÚ{q$”.Ð \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/d6/7d8cbcffeacd1914a11d726d85a8df8432e95a b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/d6/7d8cbcffeacd1914a11d726d85a8df8432e95a new file mode 100644 index 0000000..e1ed1c2 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/d6/7d8cbcffeacd1914a11d726d85a8df8432e95a @@ -0,0 +1 @@ +x+)JMU026e040031QHKM,)-J�7Ô+¨dضBó‡‚ÓÍØ•7¹ÜyßÞ½µâ3š:#�ºþEÖ¶‹ûËŽ8ö,ež ÍÒaÖ�¦Î¤Îd©Ž ;בûIª ßK§XŸŸôÞM� H��èÜ™vÞõ'²î*½ÍyÙ’ØôM�)H›FÄ·k_ý¢&s¹Šwj+ o_dU—›˜™Râ£XZ¾ÒS«Áàè ¾Øôieí�osÃZ \ No newline at end of file diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/ec/d451c0dc54b254b1572587d48fbe617ac3d738 b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/objects/ec/d451c0dc54b254b1572587d48fbe617ac3d738 new file mode 100644 index 0000000000000000000000000000000000000000..cc644c101595956cf34c246ae596e8ecb40e0686 GIT binary patch literal 95 zcmV-l0HFVP0V^p=O;s?rU@$Z=Ff%bx2y%6F@paY9O<_2Gc_a zoO<=Wi2)EOl;;;^rxxiJrxulECZ{r7tL@qI|J7MZk%h8FxveYiw-~*Q0sw#cBn}Ml BElB_X literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/refs/heads/main b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/refs/heads/main new file mode 100644 index 0000000..45724e5 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/dotgit/refs/heads/main @@ -0,0 +1 @@ +0cd9efe3a4957b0f5336c33f4e40e9e4d779c243 diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_1.py b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_1.py new file mode 100644 index 0000000..b6a829f --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_1.py @@ -0,0 +1 @@ +def feature_1(): pass diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_2.py b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_2.py new file mode 100644 index 0000000..8fa23b3 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_2.py @@ -0,0 +1 @@ +def feature_2(): pass diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_3.py b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_3.py new file mode 100644 index 0000000..34a52c1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_3.py @@ -0,0 +1 @@ +def feature_3(): pass diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_4.py b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_4.py new file mode 100644 index 0000000..0c30159 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_4.py @@ -0,0 +1 @@ +def feature_4(): pass diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_5.py b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_5.py new file mode 100644 index 0000000..062858f --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/feature_5.py @@ -0,0 +1 @@ +def feature_5(): pass diff --git a/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/main.py b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/main.py new file mode 100644 index 0000000..4c21757 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/drift-stale-repo/worker-service/main.py @@ -0,0 +1 @@ +class Worker: pass diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/COMMIT_EDITMSG b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/COMMIT_EDITMSG new file mode 100644 index 0000000..580be90 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/COMMIT_EDITMSG @@ -0,0 +1 @@ +init: code, no README diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/HEAD b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/HEAD new file mode 100644 index 0000000..b870d82 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/config b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/config new file mode 100644 index 0000000..8bb2ccd --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/config @@ -0,0 +1,10 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true +[user] + email = t@t + name = t diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/description b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/applypatch-msg.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/commit-msg.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/fsmonitor-watchman.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/post-update.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-applypatch.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-commit.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-merge-commit.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-push.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-rebase.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-receive.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/prepare-commit-msg.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/push-to-checkout.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/update.sample b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/index b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/index new file mode 100644 index 0000000000000000000000000000000000000000..8a6bc0395752c74bfc4e627778ec2c53afc84064 GIT binary patch literal 190 zcmZ?q402{*U|<4b#w-)>ZpHah&M=yhfq|b_=YlW;L*o*l^jDx75g_K%3TWq0?|(JJ zQXshF@ua(p7Hm;fXAmjQ&rQ`WPAw|SOitC$P0Y;GE2spj27-_vS63iq$6%;n$Tgwv z=APNEh2GaL?5lNhGvVaW`Ou226{yI7D{o855mUYf_espF%Qk2+HR 1781107200 -0400 commit (initial): init: code, no README diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/logs/refs/heads/main b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/logs/refs/heads/main new file mode 100644 index 0000000..4a14af5 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 aa56c53150461eebd587634d76f26cf626a18e3b t 1781107200 -0400 commit (initial): init: code, no README diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/objects/2a/508708278fea9839105388e392dda2a0b42527 b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/objects/2a/508708278fea9839105388e392dda2a0b42527 new file mode 100644 index 0000000000000000000000000000000000000000..1ad3453e79b98c70b4a5b6144005778f12ec091c GIT binary patch literal 28 kcmb2fVL0JshO4dEhR@x`5N3OF|RJ$pvBar MmlJ#%0BCj)QM$DoOl=1$82XOy*rLSvK zvV%Y9EAs~lNy_( literal 0 HcmV?d00001 diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/refs/heads/main b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/refs/heads/main new file mode 100644 index 0000000..b5d670a --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/dotgit/refs/heads/main @@ -0,0 +1 @@ +aa56c53150461eebd587634d76f26cf626a18e3b diff --git a/security-review/checkers/fixtures/doc-drift/no-readme-repo/some-service/main.py b/security-review/checkers/fixtures/doc-drift/no-readme-repo/some-service/main.py new file mode 100644 index 0000000..2a50870 --- /dev/null +++ b/security-review/checkers/fixtures/doc-drift/no-readme-repo/some-service/main.py @@ -0,0 +1 @@ +class S: pass