pr2wt.sh 1.9 KB

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