Gitea Pull Requests

Since Blender moved to Gitea I’ve struggled a bit with the pull requests workflow. Getting contributors’ changes onto my machine wasn’t as simple as I wanted it to be. So, I wrote a little shell script to make my life easier.

The functions below I store in ~/.config/fish/conf.d/ Once they’re installed, I have these commands at my, well…, command:

pr NUMBER [-o owner] [-r repo]

I can just type pr NUMBER to get a Blender pull request, for example pr 104512. It will:

  • Create a branch named PR/104512/author-branch
  • If that branch already existed, it gets removed before creating a brand new one.
  • Pull in the changes from the PR.
  • The options -o and -r are optional, and both default to blender. I use this for Flamenco pull requests, for example, like pr -o studio -r flamenco 12345.

The branch is named like this so that I can easily find it back later.

Update 2023-03-06: addition of the -o and -r options.


This removes all the branches named PR/.... I use it to periodically clean things up.

The code

Store this snippet in ~/.config/fish/conf.d/

function pr -d "Pull in a Blender pull request"
    # Set defaults
    set _flag_owner blender
    set _flag_repo blender

    argparse 'o/owner=' 'r/repo=' -- $argv
    or return 48

    set PRNUM $argv[1]

    set JSON "pr-$PRNUM.json"
    set URL "{$_flag_owner}/{$_flag_repo}/pulls/$PRNUM"
    curl -s -o$JSON $URL
    or return 49

    set PR_STATUS (jq -r .state <$JSON)
    if [ (jq -r .merged <$JSON) = "true" ]
        printf "\033[92mPR is already merged, check $URL\033[0m\n"
        echo "Merged at:" (jq -r .merged_at <$JSON)
        echo "Merged by:" (jq -r .merged_by.full_name <$JSON)
        return 51
    if [ (jq -r .state <$JSON) = "closed" ]
        printf "\033[91mPR is closed, check $URL\033[0m\n"
        return 50

    set PR_NUM (jq -r .number <$JSON)
    set PR_TITLE (jq -r .title <$JSON)
    printf "\033[95mPulling #$PR_NUM: $PR_TITLE\033[0m\n"

    set PR_REPO (jq -r .head.repo.full_name <$JSON)   # "ChrisLend/blender"
    set PR_AUTHOR (jq -r .head.repo.owner.username <$JSON)   # "ChrisLend"
    set PR_BRANCH (jq -r .head.ref <$JSON) # "vertical_scrolling_offscreen"

    printf "\033[90mIncoming branch: $PR_REPO\033[0m\n"
    printf "\033[90mLocal branch   : $LOCAL_BRANCH\033[0m\n"

    rm -f $JSON

    set CURBRANCH (git branch --show-current 2>/dev/null)
    if test "$CURBRANCH" != "main";
        git checkout main
    if git branch | grep -q $LOCAL_BRANCH;
        printf "\033[95mBranch $LOCAL_BRANCH exists, going to refresh it\033[0m\n"
        git branch -D $LOCAL_BRANCH
        printf "\033[96mBranch $LOCAL_BRANCH does not exist\033[0m\n"

    git checkout -b $LOCAL_BRANCH main; or return 47
    git pull --ff --commit$PR_REPO $PR_BRANCH; or return 48

    printf "\033[95mBranch $LOCAL_BRANCH is ready for use\033[0m\n"
    printf "\033[94mPulled #$PR_NUM: $PR_TITLE\033[0m\n"

function prprune -d "Delete all PR/* branches"
    set BRANCHES (string trim (git branch | grep '^  PR/'))
    if test -z "$BRANCHES";
        echo "No PR branches to prune"
        return 0
    git branch -D $BRANCHES

Note that I wrote similar code for Phabricator in my Fish and Gits post, which also shows more of my Git config.

dr. Sybren A. Stüvel
dr. Sybren A. Stüvel
Open Source software developer, photographer, drummer, and electronics tinkerer