Skip to content

Instantly share code, notes, and snippets.

@tkellogg
Created April 5, 2023 19:05
Show Gist options
  • Save tkellogg/286852d1e9d1c942c297b108c1560292 to your computer and use it in GitHub Desktop.
Save tkellogg/286852d1e9d1c942c297b108c1560292 to your computer and use it in GitHub Desktop.
git-rebranch: A simpler git workflow

Overview

Git-rebranch is my git workflow that's a lot simpler than gitflow or other alternatives. I have 1-2 "pull request" branches that I constantly reuse.

The principal assumptions are:

  1. There is a single long-lived branch, typically called main or master
  2. Pull requests made from a short-lived branch that is deleted after the PR is merged
  3. PRs are merged via "squashing" into a single commit
  4. Therefore, no one cares what your branch is called since there's never many branches open

If this doesn't describe your workflow, you're not going to like this.

How to use it

TL;DR — run git rebranch when you start a new feature. It recreates the current branch on top of origin/main.

sequenceDiagram
participant main
participant tim-pr
participant Github

rect rgb(50, 50, 120)
    note right of main: git-rebranch
    tim-pr->>Github: Check for PRs <br/>open on tim-pr
    tim-pr->>tim-pr: git branch -D
    tim-pr->>main: git checkout
    Github->>main: git pull
    main->>tim-pr: git checkout -b
end

tim-pr->>tim-pr: Do Work

tim-pr->>Github: git push
Github->>Github: Create Pull Request
Github->>main: Merge tim-pr into main
Github->>tim-pr: Delete tim-pr

What do you call you branch?

I call mine tim-pr so it's abundantly clear what it does. Its a branch that I, Tim, use for pull requests.

What if I need multiple branches?

Generally, having multiple branches open is a smell that means you have a lot of work in progress. But whatever, if you really want to, just create a new branch called tim-pr-2 or whatever makes sense, and run git rebranch.

What if another PR is open on tim-pr?

In a previous version of this script it would delete my local branch and I'd eventually figure out that I messed things up when I went to createa a pull request. Now, in the current version, it uses the Github CLI to check if there's a branch open. It definitely saves a lot of headaches. If rejected, I just create a new branch and run git rebranch again.

What's oil shell?

Awesome. It's awesome. I wrote this in oil shell so I could try it out, and it's great. The idea is to have a shell language that looks more like Python or JavaScript.

#!/usr/local/bin/oil
# Re-create the current branch on top of "master" after pulling latest.
#
# Normal usage:
# git rebranch
#
# On a branch other than master:
# git rebranch prod-master
#
# Alternately, configure a default branch in the local repository:
# git config --local scripts.defaultbranch prod-master
# git rebranch
#
var master="master"
var carry_head=""
for arg in @ARGV {
if (arg === '--hard') {
setvar carry_head=$(git log | head -n1 | awk '{ print $2 }')
} else {
setvar master=(arg)
}
}
const current_branch=$(git rev-parse --abbrev-ref HEAD)
const default_branch=$(git config scripts.defaultbranch || echo "master")
if (default_branch !== "") {
setvar master="$default_branch"
}
git show $master >/dev/null 2>/dev/null || {
echo "Unknown branch: '$master'. Set a default branch via:"
echo ""
echo " git config --local scripts.defaultbranch main"
echo ""
exit 1
}
const jq_query='.[] | select(.headRefName == "' ++ current_branch ++ '") | .url'
const remote_prs=$(gh pr list --json headRefName,url | jq -rc $jq_query)
if (remote_prs !== "") {
echo "Branch $current_branch currently has a PR open: $remote_prs"
exit 1
} else {
echo "No PRs open: GOOD!"
}
echo "$current_branch <-> $master"
git checkout $master
git pull
git branch -D $current_branch
git checkout -b $current_branch
if (carry_head !== "") {
git cherry-pick $carry_head
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment