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/aliases.fish. Once they’re installed, I have these commands at my, well…, command:

Update 2024-04-03: I’ve started to track those scripts at my projects.blender.org profile space. Go there to get the latest versions.

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.

prprune

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/aliases.fish:

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 "https://projects.blender.org/api/v1/repos/{$_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
    end
    if [ (jq -r .state <$JSON) = "closed" ]
        printf "\033[91mPR is closed, check $URL\033[0m\n"
        return 50
    end

    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"
    set LOCAL_BRANCH "PR/$PRNUM/$PR_AUTHOR-$PR_BRANCH"

    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
    end
    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
    else
        printf "\033[96mBranch $LOCAL_BRANCH does not exist\033[0m\n"
    end

    git checkout -b $LOCAL_BRANCH main; or return 47
    git pull --ff --commit https://projects.blender.org/$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"
end

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
    end
    git branch -D $BRANCHES
end

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

Related