Last active
March 8, 2026 04:11
-
-
Save keturn/9ea3aa7e005cb7cfa5b0bb236c5526e8 to your computer and use it in GitHub Desktop.
Document git fork as "Pull-Request Only"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Replace the repo's default branch with a README explaining this fork is only for its submitted pull requests. | |
| set -e -x -o pipefail | |
| REMOTE=origin | |
| GH_USERNAME="${GH_USERNAME:-$USER}" | |
| TRUNK="$(git symbolic-ref --short refs/remotes/$REMOTE/HEAD | sed "s:${REMOTE}/::")" | |
| REMOTE_URL="$(git remote get-url $REMOTE)" | |
| UPSTREAM_REPO="${REMOTE_URL%%.git}" | |
| GIT_ROOT=$( git rev-parse --show-toplevel ) | |
| PROJECT_NAME="${GIT_ROOT##*/}" | |
| # Move old trunk out of the way. | |
| git branch -m "$TRUNK" upstream-"$TRUNK" | |
| # Make a new orphan branch with that name. | |
| git checkout --orphan "$TRUNK" | |
| # checkout --orphan left everything staged in the index; remove it | |
| git reset | |
| # Remove most files, except for those that might cause a lot of editor thrashing | |
| # or things the host needs for repo metadata (e.g. LICENSE) | |
| git clean --force -d --exclude=.gitignore --exclude=.editorconfig --exclude=LICENSE | |
| cat > README.md << EOF | |
| # Pull-Request Only Fork | |
| This fork exists only for making pull requests against upstream. | |
| See | |
| * [branches here](https://github.com/${GH_USERNAME}/${PROJECT_NAME}/branches) | |
| * [upstream repository](${UPSTREAM_REPO}) | |
| * [pull requests to upstream](${UPSTREAM_REPO}/pulls/${GH_USERNAME}) | |
| EOF |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/zsh | |
| # Replace the repo's default branch with a README explaining this fork is only for its submitted pull requests. | |
| # | |
| # This version depends on gh so it can be smarter about constructing URLs. | |
| set -e -o pipefail | |
| # The goal is to set what someone sees when they land on your fork's page on GitHub. | |
| # We can either replace the main branch, or change the default branch of the fork. | |
| typeset SET_NEW_DEFAULT_BRANCH=1 | |
| typeset NEW_DEFAULT_BRANCH="PR-ONLY-FORK" | |
| typeset GH_HOST | |
| typeset GH_USERNAME | |
| gh auth status --json hosts --jq '.hosts[][] | "\(.host)\t\(.login)"' \ | |
| | read -r GH_HOST GH_USERNAME | |
| typeset PROJECT_NAME | |
| gh repo view --json name --jq '"\(.name)"' \ | |
| | read -r PROJECT_NAME | |
| # `gh repo view` defaults to "the repository for the current directory," but if a remote is defined | |
| # for upstream, it may use that instead of the fork. So explicitly use the username here. There are | |
| # edge cases where this may not reflect how you've forked things, but it should work for the common | |
| # case. | |
| typeset TRUNK | |
| typeset UPSTREAM_REPO | |
| gh repo view \ | |
| --json defaultBranchRef,parent \ | |
| --jq '"\(.defaultBranchRef.name)\t\(.parent.owner.login)/\(.parent.name)"' \ | |
| ${GH_USERNAME}/${PROJECT_NAME} \ | |
| | read -r TRUNK UPSTREAM_REPO | |
| typeset WEB_UPSTREAM_REPO="https://${GH_HOST}/${UPSTREAM_REPO}" | |
| function branch_with_old_name () { | |
| # Move old trunk out of the way. | |
| git branch -m "$TRUNK" upstream-"$TRUNK" | |
| # Make a new orphan branch with that name. | |
| git checkout --orphan "$TRUNK" | |
| } | |
| function branch_with_new_name () { | |
| git checkout --orphan "$NEW_DEFAULT_BRANCH" | |
| } | |
| if (( SET_NEW_DEFAULT_BRANCH > 0 )); then | |
| branch_with_new_name | |
| else | |
| branch_with_old_name | |
| fi | |
| # checkout --orphan left everything staged in the index; remove it | |
| git reset | |
| # Remove most files, except for those that might cause a lot of editor thrashing | |
| # or things the host needs for repo metadata (e.g. LICENSE) | |
| git clean --force -d --exclude=.gitignore --exclude=.editorconfig --exclude=LICENSE | |
| cat > README.md << EOF | |
| # Pull-Request Only Fork | |
| This fork exists only for making pull requests against upstream. | |
| See | |
| * [branches here](https://${GH_HOST}/${GH_USERNAME}/${PROJECT_NAME}/branches) | |
| * [upstream repository](${WEB_UPSTREAM_REPO}) | |
| * [pull requests to upstream](${WEB_UPSTREAM_REPO}/pulls/${GH_USERNAME}) | |
| EOF | |
| git add -A | |
| git commit -m '! Document GitHub repo as a pull-request only fork' | |
| typeset REMOTE_FORK=$( git remote -v | grep $GH_USERNAME/${PROJECT_NAME} | head -n1 | cut -f1 ) | |
| read -q "?Push this branch to your fork ($REMOTE_FORK)? [y/N] " || exit 1 | |
| if (( SET_NEW_DEFAULT_BRANCH > 0 )); then | |
| git push $REMOTE_FORK $NEW_DEFAULT_BRANCH | |
| else | |
| git push --force $REMOTE_FORK $TRUNK | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment