// tutorial

Use a dev branch so main stays deployable

If main is what's actually running in production, committing straight to it means every half-finished change is one push away from breaking things for real users. Doing the work on a dev branch instead gives you a safe place to build and break things, and turns "shipping" into a deliberate step — merging into main — instead of an accident.

git workflow branching 6 min read
  1. Why not just commit to main?

    main should always be in a state you'd be comfortable deploying right now. Committing feature work directly to it means every in-progress change — an untested query, a half-wired UI, a broken migration — sits on the same branch your deploy pipeline watches. A dev branch (or one branch per feature) gives that work somewhere to live until it's actually done, without ever putting main at risk.

  2. Create the dev branch from main

    Start from an up-to-date main, then branch off it. -b creates the branch and switches to it in one step.

    bash
    git checkout main
    
    git pull origin main
    
    git checkout -b dev
    
    git push -u origin dev

    The last line publishes dev to the remote and links your local branch to it, so plain git push and git pull work from here on.

  3. Do the actual work on dev

    Everything — new features, refactors, risky experiments — happens on dev (or a branch cut from it). Commit as often as makes sense; main never sees any of this until you decide it's ready.

    bash
    git add .
    
    git commit -m "Add checkout validation"
    
    git push
  4. Merge dev into main when it's ready

    Once dev is tested and you actually want it live, merge it into main — not the other way around. --no-ff keeps a merge commit even if the merge could fast-forward, so your history still shows where each round of work landed.

    bash
    git checkout main
    
    git pull origin main
    
    git merge --no-ff dev -m "Merge dev: checkout validation"
    
    git push origin main

    This is also the natural place for a pull request instead of a local merge — same idea, but with review and CI running against dev before it touches main.

  5. Bring dev back up to date

    After main moves — from this merge, a hotfix, or anyone else's work — sync those changes back into dev before you keep building, so you're never merging a badly outdated branch later.

    bash
    git checkout dev
    
    git merge main
    
    git push

    Repeat from step 3: build on dev, merge into main when ready, sync back — main stays deployable at every point in between.