Skip to content

Instantly share code, notes, and snippets.

@Mikulas
Last active May 3, 2017 11:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Mikulas/c1ebc63a0a42515b7d55fcf82f81cb21 to your computer and use it in GitHub Desktop.
Save Mikulas/c1ebc63a0a42515b7d55fcf82f81cb21 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/required_status_checks" \
-XGET \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.loki-preview" \
-sS -o /dev/null \
--write-out "%{http_code}" \
| grep --count '200'
}
function set_protection {
ORG_REPO="$1"
BRANCH="$(normalize_branch "$2")"
TOGGLE="$3" # string 'true' or 'false'
curl "https://api.github.com/repos/$ORG_REPO/branches/$BRANCH/protection/required_status_checks" \
-XPATCH \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.loki-preview" \
-d "{\"enforce_admins\": $TOGGLE}" \
-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" "false"
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" "true"
done
exit "$CODE"
@Mikulas
Copy link
Author

Mikulas commented Jul 19, 2016

Update GITHUB_TOKEN with your own from https://github.com/settings/tokens
screenshot 2016-07-19 11 41 07

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment