Back to all articles
Branches, workflows, and Git for grown-ups

Branches, workflows, and Git for grown-ups

Learn how to organize your Git workflow: branches, strategies, pull requests, merge, rebase, and more.

Human-architected research synthesized with the assistance of AI personas.
8 min read

TL;DR / Executive Summary

Learn how to organize your Git workflow: branches, strategies, pull requests, merge, rebase, and more.

💡 TL;DR (Too Long; Didn't Read)

Git branches are fundamental for teams. Pick a strategy (Git Flow or Trunk-Based), keep main always deployable, use short-lived feature branches, make small focused PRs, understand merge vs rebase, and establish simple agreements with your team. The difference between a chaotic dev and a professional is exactly this: workflow organization.

If your Git usage boils down to git add ., git commit, and git push straight to main, you're playing on easy mode and leaving a lot of productivity (and sanity) on the table.

In this article we'll move from "solo" Git to team Git:

  • How to use branches intelligently
  • Branching strategies (without turning it into religion)
  • Merge vs rebase in practice
  • How not to be the dev who breaks main every week
  • Real-world tips for PRs (pull requests) your team will actually like

1. Why branches matter so much

Branches are the foundation of any halfway decent Git workflow.

Without branches:

  • Everything lands directly on main
  • Test bugs take down stable code
  • It's hard to see what was deployed when

With well-used branches:

  • You isolate features, bugfixes, and hotfixes
  • You review code in small chunks (pull requests)
  • You can roll back specific functionalities more easily

Golden rule: main (or master) should always be in a deployable state.

If you can't deploy main at almost any moment, your workflow is sabotaging you.


2. Creating and navigating branches

Let's recap and organize key branch operations.

Create a new branch from the current one

bash
git checkout -b feature/login-screen

Same as:

bash
git branch feature/login-screen git checkout feature/login-screen

List branches

bash
git branch # local git branch -a # local + remote

Switch branches

bash
git checkout main

Or with newer Git:

bash
git switch -c feature/profile-screen # create and switch git switch main # just switch

3. Branching strategies without fanboyism

There are many named models. We'll talk about the two most common in real life.

3.1. Git Flow (classic)

Useful for teams with more defined release cycles.

Main branches:

  • main → production
  • develop → continuous integration of features

Supporting branches:

  • feature/* → new functionalities
  • release/* → stabilize a version before releasing
  • hotfix/* → emergency fixes in production

Pros:

  • Well-structured for release-based products
  • Good for versioned software (1.2.3, 1.2.4, etc.)

Cons:

  • Can be too heavy for small teams
  • Lots of branches for few people

3.2. Trunk-Based Development (TBD)

More modern and common in teams with frequent deploys.

  • main (or trunk) is the central branch
  • Features live in short-lived branches that return quickly to main
  • Feature flags control unfinished features in production

Pros:

  • Fewer "forgotten" branches
  • Enables continuous delivery more easily

Cons:

  • Requires strong discipline with tests and automation
  • When done wrong, main turns into a party

Honest summary: pick ONE model, adapt, document it, and make everyone follow. A model without team consensus is just versioned chaos.


4. A healthy feature lifecycle

A good flow for a new feature might look like this:

  1. Update your local main
bash
git checkout main git pull origin main
  1. Create a feature branch
bash
git checkout -b feature/login-screen
  1. Make small, focused commits with meaningful messages
bash
git add . git commit -m "feat: add basic login screen layout" # ... git commit -m "feat: integrate login screen with auth API"
  1. Sync your branch with main

Safer option (merge):

bash
git checkout feature/login-screen git fetch origin git merge origin/main

Cleaner history (rebase):

bash
git checkout feature/login-screen git fetch origin git rebase origin/main
  1. Open a Pull Request (PR) from your branch to main or develop

  2. After review, merge and optionally delete the feature branch

bash
git checkout main git pull origin main # get the merge git branch -d feature/login-screen # local git push origin --delete feature/login-screen # remote (to keep things tidy)

5. Merge in practice: when and how to use it

Basic command:

bash
git checkout main git pull origin main git merge feature/login-screen

If there are no conflicts, Git creates a merge commit.

Merge commit vs fast-forward

  • Fast-forward: when main hasn't moved since you branched off. Git just "moves the pointer" with no merge commit.

  • Merge commit: when main also changed. Git creates an extra commit with two parents.

Control it with flags:

bash
git merge --no-ff feature/login-screen # always create merge commit git merge --ff-only feature/login-screen # only fast-forward, otherwise fail

Teams that like to see each feature as a clear block often use --no-ff to preserve that structure.


6. Rebase: making history linear (and beautiful)

git rebase rewrites the base of your commits as if they were created on top of another point.

Common flow:

bash
git checkout feature/login-screen git fetch origin git rebase origin/main

If there are conflicts:

  1. Edit the conflicting files
  2. git add the resolved ones
  3. Continue the rebase:
bash
git rebase --continue

If things get ugly and you want to abort:

bash
git rebase --abort

Survival rule: rewriting public history is asking for chaos. Rebase is excellent on local branches, dangerous on shared ones.


7. Pull requests your team will actually like

A pull request isn't just "pressing the button".

Practical tips:

  • Keep PRs small and focused (ideally 100–300 lines, not 3000)
  • Write a clear description: what was done, why, how to test
  • Tag the right reviewers (not the entire team every time)
  • Use labels to categorize (bug, feature, hotfix)

Example description:

text
## What was done
- Add login screen with email/password
- Integrate with /auth/login API

## How to test
1. Run `npm install && npm start`
2. Go to /login
3. Try logging in with a valid user

## Notes
- "Forgot password" flow is not implemented yet

The clearer it is, the easier it is to approve.


8. Handling conflicts without panicking

Merge or rebase conflicts don't mean you failed. They mean the team is working in parallel.

When Git reports a conflict:

  1. See which files are conflicted
bash
git status
  1. Open the file: you'll see something like:
text
<<<<<<< HEAD
code from your current branch
=======
code from the other branch
>>>>>>> feature/something
  1. Edit the file, keeping what makes sense (sometimes both sides), and remove <<<<<<<, =======, >>>>>>> markers.

  2. Mark as resolved and continue:

bash
git add path/to/file # if it's a regular merge git commit # if it's a rebase git rebase --continue

Tip: tools like VS Code, IntelliJ, etc. are GREAT for visualizing conflicts, but you should still understand what's happening underneath.


9. Tiny team agreements that avoid huge fights

Some simple team rules:

  • "We never push --force to main"
  • "We always sync from main before opening a PR"
  • "PRs need at least 1 or 2 approvals"
  • "We don't merge red builds"
  • "Feature branches should live for days, not months"

These may sound like bureaucracy, but they save you from a ton of rework.


10. Summary: grown-up Git is more about TEAM than COMMANDS

In this article, you saw:

  • Why branches are essential in real teams
  • Different strategies (Git Flow vs Trunk-Based)
  • Merge and rebase applied to daily work
  • How to design a healthy feature lifecycle
  • How to write PRs that make everyone's life easier

Mastering this changes how your team sees you:

  • You go from "knows how to run git" to "helps organize our workflow".

In the next article, we'll dive into powerful, less obvious commands:

  • revert, cherry-pick, reflog, bisect
  • And more tactics to investigate bugs and recover work.

Receive new articles

Subscribe to receive notifications about new articles directly to your email

We won't send spam. You can unsubscribe at any time.