I push a feature branch a dozen times a week. Every single time, the dance is the same: git push, switch to the browser, click the “Create MR” button, set assignee, set reviewer, add labels, wait for CI, click merge, switch back to terminal, git checkout main, git pull, git branch -d feature/.... It’s not hard. It’s just tedious — and the kind of friction that adds up over a week.
I had a shell script glued together with glab, gh, jq, yq, and gum doing this for years. It worked, but it broke whenever any of those tools updated and was a pain to ship to a fresh laptop. So I rewrote the whole thing in Go and called it auto-mr. One binary, no external CLIs, works on both GitLab and GitHub.
What it does
You’re on a feature branch with a clean working tree. You run auto-mr. The tool:
- Detects whether the remote is GitLab or GitHub
- Pushes the current branch
- Lets you pick labels interactively
- Opens the MR/PR with the right assignee and reviewer
- Waits for the CI pipeline to finish
- Auto-approves (GitLab only) and merges
- Switches back to main and deletes the local branch
That’s it. One command, no browser tab.
Why a Go rewrite
The original shell version had a hard dependency on five external tools — glab, gh, jq, yq, gum, plus git itself. Every fresh machine meant brew install five times. Every CI image meant five extra layers.
The Go rewrite replaces all of that with libraries:
| Was | Now |
|---|---|
glab | GitLab Go client |
gh | GitHub Go client |
jq | encoding/json |
yq | yaml.v3 |
gum | survey |
git | go-git |
One static binary. No PATH dance.
Installation
The project ships releases for the usual platforms, plus Homebrew and go install:
# Homebrew
brew tap sgaunet/homebrew-tools
brew install sgaunet/tools/auto-mr
# Go
go install github.com/sgaunet/auto-mr@latest
Configuration
A small YAML file at ~/.config/auto-mr/config.yml tells it who to assign and who to ask for review:
gitlab:
assignee: your-gitlab-username
reviewer: reviewer-gitlab-username
github:
assignee: your-github-username
reviewer: reviewer-github-username
And a token in your environment:
export GITLAB_TOKEN="..."
export GITHUB_TOKEN="..."
For GitLab, the token needs api, read_repository, write_repository. For GitHub, repo (and workflow if you have GitHub Actions).
Daily use
The whole point is brevity. From a feature branch:
auto-mr
If you want squashed commits on merge:
auto-mr --squash
That’s the entire surface area I use day to day. There’s also --log-level debug if something misbehaves.
What I didn’t expect
Two things surprised me after switching:
- Pipeline waiting changed how I context-switch. Because the tool blocks until CI is green, I stopped opening four tabs and refreshing. I either wait (small change) or background it and go work on the next branch.
- Interactive label selection actually gets used. With the browser flow I’d skip labels half the time. With a TUI prompt that takes one keystroke, I label everything. The repo’s filters and reports got way more useful.
Where to find it
- Source: github.com/sgaunet/auto-mr
- License: MIT
If you bounce between GitLab and GitHub projects and you’re tired of the same six clicks every time you ship a branch, give it a try. It’s the first tool I install on any new machine.