Skip to main content

PRE_PUSH_BODY

Constant PRE_PUSH_BODY 

Source
pub const PRE_PUSH_BODY: &str = "#!/bin/sh\n# Managed by `drep init`.\n# git runs this as: pre-push <remote-name> <remote-url>, and sends one line per\n# ref on stdin:\n#   <local ref> <local oid> <remote ref> <remote oid>\n#\n# Three things here are not obvious, and each was a real defect:\n#\n#  * The ref being pushed is NOT always the checked-out branch\n#    (`git push origin feature:feature` from elsewhere, or `git push --all`),\n#    so `--tip` names the oid actually being pushed. Reviewing HEAD instead\n#    lets the pushed code through unseen.\n#  * The base search is BOUNDED. An all-zero remote oid means the branch is\n#    new upstream; falling back to the root commit there sends the repository\'s\n#    entire history to the model, which on a mature repo is hours of wall clock\n#    and real money from one `git push`.\n#  * `drep` reads no stdin, but `< /dev/null` makes that structural: a command\n#    inside a `while read` loop that did would swallow the remaining refs and\n#    the push would go green having reviewed one of them.\nremote=\"${1:-origin}\"\nzeros=0000000000000000000000000000000000000000\nstatus=0\n\nif ! command -v drep > /dev/null 2>&1; then\n    echo \"drep: not found on PATH; refusing to let the push through unreviewed.\" >&2\n    echo \"  (GUI git clients often use a minimal PATH - see the drep README.)\" >&2\n    exit 1\nfi\n\nwhile read -r _local_ref local_oid _remote_ref remote_oid; do\n    # A branch deletion has no content to review.\n    case \"$local_oid\" in \"$zeros\"*) continue ;; esac\n\n    case \"$remote_oid\" in\n        \"$zeros\"*)\n            # New upstream: find the nearest sensible base, cheapest first, and\n            # never scan further back than 50 commits.\n            base=$(git rev-parse --verify --quiet \"$remote/HEAD\") ||\n            base=$(git rev-parse --verify --quiet \"$remote/main\") ||\n            base=$(git rev-parse --verify --quiet \"$remote/master\") ||\n            base=$(git rev-parse --verify --quiet \"$local_oid~50\") ||\n            base=$(git rev-list --max-parents=0 \"$local_oid\" | tail -n 1)\n            ;;\n        *) base=$remote_oid ;;\n    esac\n\n    [ -n \"$base\" ] || continue\n\n    drep check --push-gate --diff \"$base\" --tip \"$local_oid\" < /dev/null\n    rc=$?\n    # Failure precedence is semantic, not numeric: 2 (could not analyze), then\n    # 1 (findings), then 3 (review cached; reconnect), then 0. Exit 3 is\n    # numerically highest but is a successful review, so it must not hide a\n    # harder failure from another ref.\n    case \"$rc\" in\n        2) status=2 ;;\n        1) [ \"$status\" -ne 2 ] && status=1 ;;\n        3) [ \"$status\" -eq 0 ] && status=3 ;;\n        0) ;;\n        *) status=2 ;;\n    esac\ndone\n\nexit $status\n";
Expand description

The body drep writes for pre-push.

git sends one line per ref on stdin: <local ref> <local oid> <remote ref> <remote oid> An all-zero remote oid means the branch does not exist upstream yet, so there is no previous state to diff against; fall back to the remote’s default branch. An all-zero local oid is a branch deletion, which has no content to review.

--push-gate performs a cache-only verdict first. A cold review is completed and cached, but exits 3 so Git closes the connection it opened before invoking this hook; repeating the push reconnects and reads the warm verdict instead of resuming a transport that sat idle for minutes.