Git workflow scripts: designing processes that earn engineering trust
Rebase helpers, link checks, commit chunking, and branch scripts — how designing your own git workflows changes the way engineering teams see design.
Knowing git commands is table stakes. Every tutorial will teach you git rebase, git commit --amend, and git add -p. What those tutorials skip is the layer above the commands: the git workflow scripts that encode your process into something repeatable, teachable, and fast. I run shell scripts for rebasing, link checking before commits, breaking long sessions into grouped commits, and switching branches without losing context. These aren’t complex — most are under twenty lines. But they changed how I work in codebases and, more importantly, how engineering teams perceive the design function. When you show up with a system for working in git rather than a loose collection of memorized commands, the trust equation shifts.
Why process design matters more than command memorization
There is a meaningful difference between knowing that git rebase -i HEAD~5 lets you squash commits and having a script that fetches the latest main, checks for uncommitted changes, rebases your branch, and reports whether conflicts occurred — all in one command. The first is knowledge. The second is a process.
Processes compound in ways that individual commands do not. When your rebase workflow is a script, you run it the same way every time. You never forget to fetch first. You never accidentally rebase with a dirty working tree. You never lose track of which branch you were on. The script handles the mechanics; you handle the judgment calls — which commits to squash, how to resolve that token conflict, whether this branch should even exist anymore.
More importantly, processes are transferable. When a junior designer or a new team member asks how you work in the codebase, you hand them your scripts folder. That is a concrete onboarding artifact — not a Notion page that drifts out of date, but executable documentation of how you actually work. The same applies when coordinating branch naming and PR patterns across a design-engineering team: conventions encoded in scripts get followed; conventions written in wikis get forgotten.
Scripts for the git workflows you repeat every day
Every script here solves a friction point I hit repeatedly. Each one is under twenty-five lines, runs in bash or zsh, and does one job well.
Pull latest and rebase safely
The most common git operation for anyone working on a feature branch: bring your branch up to date with main without losing work or creating a mess.
#!/bin/bash
# rebase-latest.sh — fetch main and rebase current branch onto it safely
set -e
BRANCH=$(git branch --show-current)
if [ -n "$(git status --porcelain)" ]; then
echo "Dirty working tree. Commit or stash your changes first."
exit 1
fi
echo "Fetching origin..."
git fetch origin main
CONFLICTS=$(git rebase origin/main 2>&1) || {
echo "Rebase conflicts detected. Resolve them, then run: git rebase --continue"
exit 1
}
echo "Branch '$BRANCH' rebased onto latest main."
git log --oneline -5
The script checks for uncommitted changes before doing anything destructive. If the working tree is dirty, it exits with a clear message instead of silently stashing or — worse — losing changes mid-rebase. After a successful rebase, it prints the last five commits so you can verify the history looks right.
Link and lint check before committing
Committing code that breaks the linter or ships dead links is the kind of mistake that erodes trust with engineering reviewers. This script gates the commit on passing checks.
#!/bin/bash
# pre-commit-check.sh — run lint + link check, then commit if clean
set -e
echo "Running linter..."
npm run lint 2>&1 || {
echo "Lint errors found. Fix them before committing."
exit 1
}
echo "Checking internal links..."
npm run check:links 2>&1 || {
echo "Broken links detected. Fix them before committing."
exit 1
}
echo "All checks passed."
git add -A
git commit -m "$1"
echo "Committed: $1"
Run it as ./scripts/pre-commit-check.sh "fix: update card spacing to 8px". The linter and link checker run first; the commit only happens if both pass. Adapt the npm run commands to whatever your project uses — the structure stays the same regardless of toolchain.
Branch switching with stash
Context-switching between branches mid-session is inevitable. This script auto-stashes your current work, switches branches, and tells you what it stashed so you can restore later.
#!/bin/bash
# switch.sh — stash current work, switch branch, report
set -e
TARGET=$1
if [ -z "$TARGET" ]; then
echo "Usage: ./scripts/switch.sh <branch-name>"
exit 1
fi
if [ -n "$(git status --porcelain)" ]; then
STASH_MSG="auto-stash before switching to $TARGET"
git stash push -m "$STASH_MSG"
echo "Stashed current changes: '$STASH_MSG'"
fi
git checkout "$TARGET"
echo "Switched to '$TARGET'. Run 'git stash pop' to restore stashed changes."
The stash message includes the target branch name so when you run git stash list later, you can see exactly which context switch caused which stash entry. Small detail, meaningful when you have three stash entries and no memory of what each one contains.
Quick rebase onto main with log
A tighter version of the rebase script for when you just want to bring your branch current and see the result.
#!/bin/bash
# rebase-main.sh — rebase onto origin/main and show divergence
set -e
git fetch origin main --quiet
BEFORE=$(git rev-parse HEAD)
git rebase origin/main
AFTER=$(git rev-parse HEAD)
if [ "$BEFORE" = "$AFTER" ]; then
echo "Already up to date with main."
else
echo "Rebased. New commits on top of main:"
git log --oneline origin/main..HEAD
fi
The origin/main..HEAD log range shows only the commits that are on your branch but not on main — the exact diff that will appear in your pull request. Reviewing this output before pushing is the fastest way to catch commits that should have been squashed or messages that need rewriting.
How do you break a long coding session into reviewable commits?
The scenario: you spent three hours deep in a feature. You touched twelve files across components, styles, and tests. Your changes are correct, but if you commit them all as a single “feat: implement card redesign” commit, the reviewer has no structure to work with. If you commit them as they happened chronologically, the history is a mess of back-and-forth edits.
The solution is commit chunking — staging your changes in logical groups after the fact, writing a clear message for each group, and pushing a history that tells the story of what you built, not the order you built it in.
git add -p is the core tool. It walks through every changed hunk in your working tree and asks whether to stage it. You say yes to the hunks that belong in this commit, no to the rest, then commit that group and repeat.
A script that structures this workflow:
#!/bin/bash
# chunk-commits.sh — guided commit chunking for long sessions
set -e
echo "Unstaged changes:"
git diff --stat
echo ""
ROUND=1
while [ -n "$(git diff --name-only)" ] || [ -n "$(git diff --cached --name-only)" ]; do
echo "--- Commit group $ROUND ---"
echo "Use 'git add -p' to stage the next logical group, then press Enter."
echo "(Or type 'done' to finish)"
read -r INPUT
[ "$INPUT" = "done" ] && break
git add -p
if [ -n "$(git diff --cached --name-only)" ]; then
echo "Staged files:"
git diff --cached --stat
echo ""
read -r -p "Commit message: " MSG
git commit -m "$MSG"
ROUND=$((ROUND + 1))
else
echo "Nothing staged. Try again or type 'done'."
fi
done
echo "Chunking complete. Final history:"
git log --oneline -$((ROUND - 1))
The script loops through your remaining changes, prompting you to stage a group with git add -p, write a message, and move to the next group. When you finish, it prints the commits you just created. The result: a PR where each commit represents a coherent unit — “refactor: extract card shadow tokens,” “feat: add elevated card variant,” “test: card component visual regression” — instead of one monolithic diff.
The principle behind commit chunking is that commits are a communication artifact, not a journal entry. They should be structured for the person reading them six months from now, not for the order your brain happened to work through the problem.
Designing your own development processes
The scripts above are small — ten to twenty-five lines each. Their value is not in the code but in the practice they represent: identifying a friction point, scripting the repeatable parts, and iterating the script as your workflow evolves.
The process for designing a process:
- Notice the friction. Every time you run more than three git commands in sequence to accomplish one task, that sequence is a candidate for a script.
- Write the manual checklist first. Before scripting, write down the steps you follow. “Fetch main. Check for dirty tree. Rebase. Review log. Push.” The checklist is the spec.
- Automate one step at a time. Start with the riskiest or most forgettable step — usually the safety check. Add the rest as the script proves useful.
- Put scripts in a
scripts/folder in the repo. When scripts live alongside the code, they are versioned, reviewable, and discoverable by anyone who clones the project. They become part of the codebase, not a personal secret. - Iterate. When you find yourself working around the script — adding a manual step before or after — update the script. It should reflect how you actually work, not how you worked six months ago.
Your scripts folder is your development process made executable. It documents how you work more honestly than any process wiki because it runs — and if it drifts from reality, it breaks. That feedback loop keeps it accurate in a way that documentation alone never does.
One implication worth naming: these scripts work identically whether you run them yourself or an AI coding agent calls them. A ./scripts/rebase-latest.sh invoked by an agent in your terminal produces the same result as you typing it. The infrastructure you build for your own workflow becomes infrastructure that scales with AI tooling. For the deeper angle on building shell scripts and skill files specifically for AI agent workflows, shell scripts, skills, and memory that make AI agents useful covers the AI infrastructure layer in detail.
What happens when engineering sees you have a process
The trust shift that happens when engineers see a design director with scripted workflows — not just using git, but having a system for using git — is qualitatively different from the trust you earn by knowing commands.
Commands signal competence. A process signals discipline. Engineers build systems for a living; they recognize system-thinking when they see it in a collaborator from another function. When you open a PR with cleanly chunked commits, and your commit messages follow a consistent format, and your branch was rebased before review — that consistency is visible. It is the artifact of a process, and engineers read it correctly.
The compounding effect matters. One clean PR could be luck. Five clean PRs with the same structure, the same commit message format, the same pre-push checks passing — that is a pattern. Patterns earn trust. Trust changes the relationship: engineers start looping design into architecture decisions earlier, they ask for PR reviews on front-end work because they know design will give actionable feedback, and they stop making silent UI judgment calls because they know someone with design authority is in the same tools, running the same workflows, and will see it.
The cultural change starts from a technical practice. The technical practice starts from designing your process. For how this connects to the day-to-day embedding practice in engineering teams — sprint rituals, PR review cadence, and async collaboration patterns — how I embed in engineering teams as a design director covers the broader workflow.
Key Takeaways
- Git workflow scripts encode your process into something repeatable and teachable — they are executable documentation of how you actually work, not aspirational wiki pages
- Four scripts cover most daily friction: safe rebase, pre-commit checks, branch switching with stash, and commit chunking for long sessions
- Commit chunking with
git add -plets you restructure a long coding session into logical, reviewable commit groups after the fact — commits should tell the story of what you built, not the order you built it - The meta-practice is the real skill: notice friction, write the manual checklist, automate one step at a time, version the scripts alongside your code, and iterate as your workflow evolves
- Engineers recognize system-thinking in collaborators from other functions — a scripted workflow signals discipline in a way that memorized commands do not, and that discipline compounds into trust over time