Short answer: Pull
main, branch for every feature, push often, open a pull request for review before merging, then delete the branch. Five steps, no extra process, built for small teams that need to stay in sync without Git ceremony.
In enterprise, startups, and consulting I've seen Git workflows get bloated: too many steps, too much process, too many tools. For small teams, that's just waste. We don't need everything. We just need the basics that let us collaborate and ship. Here's the Vibecoders Git Flow, the smallest set of moves that keep us in sync.
1. Pull first
Start your day fresh.
git checkout main
git pull origin main
In VS Code: use the Source Control panel, then the "…" menu, then Pull.
2. Branch fast
Never commit straight to main. Create a new branch for each feature:
git checkout -b feature-login-form
In VS Code: click the branch name in the bottom-left corner, then Create New Branch. One branch, one idea.
3. Push often
Commit and push as soon as something works.
git add .
git commit -m "feat: add login form UI"
git push origin feature-login-form
In VS Code: stage changes in the Source Control panel, write a commit message, hit Commit & Push. If it's not pushed, the team can't see it.
4. Merge with a gatekeeper
When your feature is ready:
git checkout main
git pull origin main
git merge feature-login-form
git push origin main
In practice we skip the local merge and open a pull request on GitHub instead: push the feature branch, open a PR against main, and have the repo owner or whoever's leading review and merge it there. No silent merges, always a quick check.
5. Delete the branch
After merging, clean up:
git branch -d feature-login-form
git push origin --delete feature-login-form
In VS Code: after the merge, switch back to main and choose Delete Branch from the branch menu. Start fresh next time. No stale branches lying around.
The commit message format we use
We write commits as type: short description, following the Conventional Commits convention: feat: for a new feature, fix: for a bug fix, docs:, refactor:, chore:, and so on. It keeps history scannable and makes it obvious what changed without opening the diff.
The point
Our Git practice is as lean as possible: pull latest, branch for your work, push often, open a PR and merge with review, then delete the branch. That's all we need. It's simple, it's transparent, and it keeps us focused on what matters: shipping.
Frequently asked questions
Why git checkout -b instead of git switch -c?
Both create a new branch and switch to it in one command. checkout -b is the older, more widely known form and still fully supported; switch -c is the newer, more explicit command Git added later. Use whichever your team already knows.
What does git branch -d actually check before deleting?
-d (delete) only removes a branch that's fully merged into its upstream or into HEAD. If it isn't merged, Git refuses and you'd need -D to force it, which we avoid unless we're sure the work is safe to discard.
Do we ever merge locally instead of opening a PR?
Rarely, and only for solo work on a personal branch. Anything a teammate needs to review goes through a pull request so there's a record of what changed and why.
What if two people edit the same file on different branches?
Pull main into your branch often so conflicts stay small, and resolve them locally before opening the PR. The fewer commits between your branch and main, the smaller the conflict.
Do we squash commits when merging?
We don't mandate it. What matters more is that the PR title and the final commit message describe the change clearly, since that's what shows up in history later.
Sources
- Git documentation: git-branch, Git.
- Git documentation: git-push, Git.
- About pull requests, GitHub Docs.
- Conventional Commits v1.0.0.
- Git Branching - Basic Branching and Merging, Pro Git book.