1#!/usr/bin/env bash
 2
 3# intialize a new worktree from a PR number:
 4#
 5# - creates a new remote using the fork's clone URL
 6# - creates a local branch tracking the remote branch
 7# - creates a new worktree in a parent folder, suffixed with "-pr-$PR"
 8#
 9# sample usage:
10#   ./scripts/pr2wt.sh 12345
11#   ./scripts/pr2wt.sh 12345 opencode
12#   ./scripts/pr2wt.sh 12345 "cmake -B build && cmake --build build"
13#   ./scripts/pr2wt.sh 12345 "bash -l"
14
15function usage() {
16    echo "usage: $0 <pr_number> [cmd]"
17    exit 1
18}
19
20# check we are in the right directory
21if [[ ! -f "scripts/pr2wt.sh" ]]; then
22    echo "error: this script must be run from the root of the repository"
23    exit 1
24fi
25
26if [[ $# -lt 1 || $# -gt 2 ]]; then
27    usage
28fi
29
30PR=$1
31[[ "$PR" =~ ^[0-9]+$ ]] || { echo "error: PR number must be numeric"; exit 1; }
32
33url_origin=$(git config --get remote.origin.url) || {
34    echo "error: no remote named 'origin' in this repository"
35    exit 1
36}
37
38org_repo=$(echo $url_origin | cut -d/ -f4-)
39org_repo=${org_repo%.git}
40
41echo "org/repo: $org_repo"
42
43meta=$(curl -sSLf -H "Accept: application/vnd.github+json" "https://api.github.com/repos/$org_repo/pulls/$PR")
44
45url_remote=$(echo "$meta" | jq -r '.head.repo.clone_url')
46head_ref=$(echo "$meta" | jq -r '.head.ref')
47
48echo "url:      $url_remote"
49echo "head_ref: $head_ref"
50
51url_remote_cur=$(git config --get "remote.pr/$PR.url" 2>/dev/null || true)
52
53if [[ "$url_remote_cur" != "$url_remote" ]]; then
54    git remote rm  pr/$PR 2> /dev/null
55    git remote add pr/$PR "$url_remote"
56fi
57
58git fetch "pr/$PR" "$head_ref"
59
60dir=$(basename $(pwd))
61
62git branch -D pr/$PR 2> /dev/null
63git worktree add -b pr/$PR ../$dir-pr-$PR pr/$PR/$head_ref 2> /dev/null
64
65wt_path=$(cd ../$dir-pr-$PR && pwd)
66
67echo "git worktree created in $wt_path"
68
69cd $wt_path
70git branch --set-upstream-to=pr/$PR/$head_ref
71git pull   --ff-only || {
72    echo "error: failed to pull pr/$PR"
73    exit 1
74}
75
76if [[ $# -eq 2 ]]; then
77    echo "executing: $2"
78    eval "$2"
79fi