Created
August 15, 2025 18:12
-
-
Save mjeffryes/ec181f0e0593d9735fdeb6b4f9d0cb84 to your computer and use it in GitHub Desktop.
Script to checkout a GitHub PR branch from a fork and push it to a new branch in target repo. This is useful for testing PRs from forks in the main repository.
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 | |
| # Script to checkout a GitHub PR branch from a fork and push it to a new branch in target repo | |
| # This is useful for testing PRs from forks in the main repository. | |
| set -euo pipefail | |
| # Check if PR URL is provided | |
| if [ $# -eq 0 ]; then | |
| echo "Usage: $0 <github-pr-url>" | |
| echo "Example: $0 https://github.com/owner/repo/pull/123" | |
| exit 1 | |
| fi | |
| PR_URL="$1" | |
| # Extract owner, repo, and PR number from URL | |
| if [[ ! "$PR_URL" =~ github\.com/([^/]+)/([^/]+)/pull/([0-9]+) ]]; then | |
| echo "Error: Invalid GitHub PR URL format" | |
| echo "Expected format: https://github.com/owner/repo/pull/NUMBER" | |
| exit 1 | |
| fi | |
| OWNER="${BASH_REMATCH[1]}" | |
| REPO="${BASH_REMATCH[2]}" | |
| PR_NUMBER="${BASH_REMATCH[3]}" | |
| echo "Fetching PR information for $OWNER/$REPO#$PR_NUMBER..." | |
| # Get PR information using gh CLI | |
| PR_INFO=$(gh pr view "$PR_NUMBER" --repo "$OWNER/$REPO" --json headRefName,headRepository,headRepositoryOwner,baseRefName,isCrossRepository) | |
| # Extract branch name and repository information | |
| HEAD_BRANCH=$(echo "$PR_INFO" | jq -r '.headRefName') | |
| HEAD_REPO_NAME=$(echo "$PR_INFO" | jq -r '.headRepository.name') | |
| HEAD_REPO_OWNER=$(echo "$PR_INFO" | jq -r '.headRepositoryOwner.login') | |
| IS_CROSS_REPO=$(echo "$PR_INFO" | jq -r '.isCrossRepository') | |
| BASE_REPO="$OWNER/$REPO" # The base repo is the one we're querying | |
| # Construct head repository name | |
| if [ "$IS_CROSS_REPO" = "true" ]; then | |
| HEAD_REPO="$HEAD_REPO_OWNER/$HEAD_REPO_NAME" | |
| else | |
| HEAD_REPO="$BASE_REPO" | |
| fi | |
| echo "Source branch: $HEAD_BRANCH" | |
| echo "Source repo: $HEAD_REPO" | |
| echo "Target repo: $BASE_REPO" | |
| NEW_BRANCH_NAME="pr-$PR_NUMBER-$HEAD_BRANCH" | |
| echo "New branch name: $NEW_BRANCH_NAME" | |
| # Check if we need to clone the target repository | |
| if ! git rev-parse --is-inside-work-tree &>/dev/null; then | |
| # Create temp directory and clone target repository | |
| TEMP_DIR=$(mktemp -d) | |
| echo "Creating temporary directory: $TEMP_DIR" | |
| cd "$TEMP_DIR" | |
| echo "Cloning target repository..." | |
| git clone "https://github.com/$OWNER/$REPO.git" | |
| cd "$REPO" | |
| # Set cleanup trap | |
| trap "rm -rf '$TEMP_DIR'" EXIT | |
| fi | |
| # Add the source repository as a remote if it's different from the base repo | |
| if [ "$HEAD_REPO" != "$BASE_REPO" ]; then | |
| REMOTE_NAME="pr-source-$PR_NUMBER" | |
| echo "Adding remote for source repository..." | |
| echo "DEBUG: Adding remote $REMOTE_NAME with URL https://github.com/$HEAD_REPO.git" | |
| # Remove existing remote if it exists | |
| git remote remove "$REMOTE_NAME" 2>/dev/null || true | |
| git remote add "$REMOTE_NAME" "https://github.com/$HEAD_REPO.git" | |
| git fetch "$REMOTE_NAME" | |
| SOURCE_REF="$REMOTE_NAME/$HEAD_BRANCH" | |
| else | |
| git fetch origin | |
| SOURCE_REF="origin/$HEAD_BRANCH" | |
| fi | |
| # Checkout the PR branch | |
| echo "Checking out branch $HEAD_BRANCH..." | |
| git checkout -b "$NEW_BRANCH_NAME" "$SOURCE_REF" | |
| # Push the new branch to origin | |
| echo "Pushing new branch $NEW_BRANCH_NAME to origin..." | |
| git push -u origin "$NEW_BRANCH_NAME" | |
| echo "Successfully created and pushed branch: $NEW_BRANCH_NAME" | |
| echo "Branch is now available in the target repository" | |
| # Clean up remote if we added one | |
| if [ "$HEAD_REPO" != "$BASE_REPO" ]; then | |
| git remote remove "$REMOTE_NAME" | |
| echo "Cleaned up temporary remote: $REMOTE_NAME" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment