Skip to content

Instantly share code, notes, and snippets.

@JanTvrdik
Forked from Mikulas/README.md
Last active May 3, 2017 11:51
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JanTvrdik/6911c39bb68a6d9835d9ee4b00eeef50 to your computer and use it in GitHub Desktop.
git-nudge

git-nudge

Same as git push, but suppresses GitHub branch protection for admins on pushed branches.

Installation

Put this file to any location in your $PATH and make it executable.

Usage

Identical to git-push command. If protected branch is detected, it removes status check requirement for admins, pushes, and reverts requirements for admins. This allows you to bypass status checks, but does not allow force push. Non-admin users cannot use this utility.

Example

$ git push
Counting objects: 1, done.
Writing objects: 100% (1/1), 184 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
remote: error: GH006: Protected branch update failed for refs/heads/somebranch.
remote: error: 2 of 2 required status checks are pending
To git@github.com:myorg/coolrepo.git
 ! [remote rejected] somebranch -> somebranch (protected branch hook declined)
error: failed to push some refs to 'git@github.com:myorg/coolrepo.git'

$ git nudge
Pushing dry
Requesting refs/heads/somebranch protection status
Removing somebranch protection
Counting objects: 1, done.
Writing objects: 100% (1/1), 184 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:myorg/coolrepo.git
   7928557..675e5ae  somebranch -> somebranch
Reverting somebranch protection
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
GITHUB_TOKEN='dae867df8b19b545ed3ab01c9efa7bc7ca1d877b'
function normalize_branch {
echo "$1" | sed 's|^refs/heads/||g'
}
function is_protected {
ORG_REPO="$1"
BRANCH="$(normalize_branch "$2")"
curl "https://api.github.com/repos/$ORG_REPO/branches/$BRANCH/protection/enforce_admins" \
-XGET \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.loki-preview+json" \
-sS \
| grep --count '"enabled": *true'
}
function set_protection {
ORG_REPO="$1"
BRANCH="$(normalize_branch "$2")"
METHOD="X$3" # string 'DELETE' or 'POST'
curl "https://api.github.com/repos/$ORG_REPO/branches/$BRANCH/protection/enforce_admins" \
-"$METHOD" \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.loki-preview+json" \
-sS -o /dev/null
}
echo "Pushing dry"
DRY_RUN="$(git push --dry-run --porcelain "$@" 2>/dev/null || true)"
# To git@github.com:orgname/reponame.git
# ! refs/heads/pr/brname:refs/heads/pr/brname [rejected] (non-fast-forward)
# Done
ORG_REPO="$(echo "$DRY_RUN" | sed -n 1p | awk 'BEGIN {FS=":"} {print $2}' | sed 's/\.git$//g')"
# orgname/reponame
BRANCHES="$(echo "$DRY_RUN" | sed 1d | grep --invert-match '^Done' | awk 'BEGIN {FS=":"} {print $2}' | awk '{print $1}')"
# refs/heads/pr/brname
PROTECT_BRANCHES=""
for BRANCH in $BRANCHES; do
echo "Requesting $BRANCH protection status"
if is_protected "$ORG_REPO" "$BRANCH" >/dev/null; then
echo "Removing $BRANCH protection"
set_protection "$ORG_REPO" "$BRANCH" DELETE
PROTECT_BRANCHES="$PROTECT_BRANCHES"$'\n'"$BRANCH"
fi
done
set +e
git push "$@"
CODE="$?"
set -e
for BRANCH in $PROTECT_BRANCHES; do
echo "Reverting $BRANCH protection"
set_protection "$ORG_REPO" "$BRANCH" POST
done
exit "$CODE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment