September 11, 2026
Git for Product Designers

Most designers meet Git sideways. A developer says "it's on the feature/onboarding branch," someone asks you to "open a PR," and you nod. Then one day you want to fix a typo in the empty state you specced three sprints ago, and the gap between knowing what Git is and being able to use it becomes a real cost.
You do not need to become a developer. You do need enough of Git to move around a codebase without breaking anything, and to speak the same language as the people shipping your work.
What Git actually is
Git is a version control system. It records snapshots of a set of files over time, so you can see what changed, when, who changed it, and why. Think of it as version history for a project, with every version kept permanently and retrievable.
Two things make it different from the autosave history in Figma or Google Docs:
It is distributed. Every person working on a project has a complete copy of the entire history on their machine. There is no single master file that can be locked or lost. When you sync with a shared server, you are reconciling two complete copies, not checking a file in and out.
It is explicit. Nothing is saved to history until you decide to save it, and when you do, you attach a message explaining the change. This sounds like overhead. It is actually the feature. Six months later, the history reads like a narrative of decisions rather than a wall of timestamps.
A quick note on names. Git is the tool. GitHub, GitLab, and Bitbucket are companies that host Git projects online and add collaboration features on top: pull requests, code review, issue tracking, automated deploys. You can use Git with no account anywhere. You will almost never want to.
Why a designer would touch it
You may already have reasons and not know they are Git-shaped.
Design tokens and design systems live in code. If your team maintains tokens as JSON or CSS variables, changing a color ramp is a Git change. Doing it yourself is often faster than filing a ticket.
Copy and content changes. Microcopy, error messages, empty states, and onboarding text frequently sit in the repo as plain strings. Fixing them yourself removes a handoff.
Reading the actual implementation. Being able to look at a component's code, even without editing it, tells you what states really exist versus what the spec claimed.
Reviewing work. Pull requests are where implementation gets discussed before it ships. A designer who can open a PR, look at the change, and leave a comment catches drift at the cheapest possible moment.
Prototypes and side projects. Anything you build yourself, from a portfolio site to a coded prototype, benefits from a history you can roll back.
Documentation. A lot of teams keep specs and decision records in Markdown files inside the repo, next to the thing they describe.
The mental model
Five concepts carry most of the weight.
Repository (repo). The project folder, plus the hidden .git directory holding its entire history.
Commit. A saved snapshot with a message. The unit of history. Commits are meant to be small and coherent, not end-of-day dumps.
Branch. A parallel line of work. You branch off the main line, make commits, and later merge back. The default main line is usually called main. Branching is why twelve people can work on the same project without colliding.
Remote. The shared copy, usually on GitHub. Conventionally named origin. Your local copy and the remote are separate; you push changes up and pull changes down.
Merge. Combining one branch into another. Usually smooth. Occasionally two people changed the same lines and Git asks you to decide, which is a merge conflict.
There is also a staging area, which trips people up. Before committing, you choose which changes go into the commit. So saving a file is three steps, not one: edit, stage, commit. It feels redundant until the first time you want to commit two of the five files you touched.
Installing Git
macOS. Open Terminal and type git --version. If Git is missing, macOS offers to install the Xcode Command Line Tools, which include it. Accept. If you use Homebrew and want a newer version, brew install git.
Windows. Download the installer from git-scm.com. Accept the defaults unless you have a reason not to. The installer includes Git Bash, a terminal that behaves like the Mac and Linux ones, which makes every tutorial you read apply to you. If you use winget: winget install --id Git.Git -e.
Linux. On Debian or Ubuntu: sudo apt update && sudo apt install git.
Then confirm and configure. Run these once:
git --version
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
The name and email get stamped on every commit you make, so use the email tied to your GitHub account.
About GUIs. GitHub Desktop, Fork, Tower, and the Git panel built into VS Code all work, and there is no shame in using them. Visual tools are genuinely better for reviewing a diff or picking apart which changes to stage. Learn the commands anyway. Every GUI is a different metaphor over the same underlying operations, and when something goes wrong, the advice you find will be phrased as commands.
The commands worth knowing
These fifteen cover nearly everything in a normal week.

Getting a project
git clone https://github.com/company/project.git
Downloads a full copy of a repo, history included. You do this once per project.
git init
Turns a folder you already have into a new repo. For starting something fresh.
Seeing where you are
git status
The command you run most. Shows your current branch, which files you have changed, and what is staged. When you feel lost, run this.
git log --oneline
The commit history, one line each. Add --graph to see how branches split and merged.
git diff
Shows exactly what you changed, line by line, before you stage it. git diff --staged shows what you have staged but not yet committed.
Working on a branch
git switch -c feature/onboarding-copy
Creates a new branch and moves you onto it. Older tutorials use git checkout -b, which does the same thing. Branch names usually describe the work: fix/login-contrast, feature/token-update.
git switch main
Moves you back to an existing branch. Your files on disk change to match.
git branch
Lists local branches, marking the one you are on.
Saving work
git add path/to/file.css
git add .
Stages changes for the next commit. The first stages one file; the second stages everything changed in the current folder and below. git add . is convenient and occasionally too broad, so glance at git status first.
git commit -m "Fix contrast on disabled button state"
Saves the staged changes as a snapshot with a message. Write messages in the imperative and describe the why where it is not obvious. "Update styles" helps nobody.
git restore path/to/file.css
Throws away uncommitted changes to a file, returning it to its last committed state. Useful and unforgiving, since those changes are gone.
Syncing with everyone else
git pull
Fetches the latest commits from the remote and merges them into your current branch. Run it before you start work and before you push.
git push
Sends your commits to the remote. The first time you push a new branch, Git will ask you to be specific:
git push -u origin feature/onboarding-copy
The -u links your local branch to the remote one, so future pushes are just git push.
Combining work
git merge main
Pulls the latest main into the branch you are on, which is how you keep a long-running branch from drifting too far. In most teams the merge back into main happens through a pull request on GitHub rather than on your machine.
git stash
git stash pop
Shelves your uncommitted changes so you can switch branches, then brings them back. The escape hatch for "I am mid-thought and someone needs me to look at something else."
What a normal day looks like
git switch main # start from the main line
git pull # get everyone else's latest work
git switch -c fix/empty-state-copy
# ...edit files...
git status # confirm what changed
git add .
git commit -m "Rewrite empty state copy for clarity"
git push -u origin fix/empty-state-copy
Then open a pull request on GitHub, which is a web form and a button. Someone reviews it, you discuss, and it merges. That loop, repeated, is most of professional Git use.
The parts that will bite you
Merge conflicts. When two people edit the same lines, Git marks the spot in the file with <<<<<<< and >>>>>>> and asks you to pick. Delete the markers, leave the version you want, save, then git add and git commit. It is annoying, not dangerous.
Committing things that should not be committed. Dependency folders like node_modules, environment files with keys, and giant binary exports do not belong in a repo. A .gitignore file lists patterns Git should skip. Most projects already have one. Check it before adding a new file type.
Design files. Git handles text beautifully and binaries poorly. It cannot show you a meaningful diff between two versions of a .fig or .psd, and large binaries bloat the repo permanently. Keep design source files where they belong and commit exports only when the build needs them.
Force pushing. git push --force rewrites remote history and can erase a colleague's work. On a branch only you touch, it is fine. On a shared branch, ask first.
Nothing is really lost. Once something is committed, Git is extremely reluctant to lose it, even when you think you have destroyed it. Before panicking about a broken repo, ask a developer. The recovery usually takes thirty seconds and they will enjoy knowing it.
Where to start
Pick something with no stakes. Put your portfolio, a coded prototype, or a folder of notes into a repo and work in it for a week. Make small commits. Break a branch on purpose and fix it. The commands become muscle memory quickly, and the conceptual model is the part that actually transfers.
The goal is not to write production code. It is to stop being downstream of your own work.