On a freelance project years ago, a collaborator and I were both pushing straight to the same branch without ever pulling first. I sat down one afternoon, made a batch of changes, and pushed — and only found out later that I'd just erased several hours of his work, because my local copy had no idea his commits existed. Nothing about that was Git being unreliable; it was two people skipping the one step that keeps everyone's copy in sync.

That step is git pull, and it belongs at the start of a work session, not the end. Pulling downloads any commits that exist on GitHub but not on your machine yet and merges them into your local copy, so you're always building on the latest version before you add to it. The full everyday loop is: pull, make your edits, git add the files you changed, git commit them with a message, then git push to send that commit back up to GitHub. Skip the pull and you're working from a stale copy; skip the push and your work never leaves your machine.

That loop works fine solo, but it breaks down the moment two people are changing the same project at once — which is where branches come in. A branch is a separate line of work that starts as an exact copy of main but doesn't affect main until you explicitly bring it back in. Instead of committing a half-finished feature straight to main, you create a branch for it with git checkout -b, do all your commits there, and push that branch to GitHub under its own name. main stays clean and deployable the whole time you're still working.

Once the work on a branch is done, git merge is what folds it back into main. Switch back to main, make sure it's up to date with a pull, then run git merge and name the branch you want folded in — Git replays that branch's commits on top of main and, in the common case, does it automatically with no input from you.

The case that isn't automatic is a merge conflict: it happens when the branch you're merging and main both changed the exact same lines of the exact same file, and Git has no way to guess which version you want. When that happens, Git stops and marks the disputed section directly inside the file with <<<<<<<, =======, and >>>>>>> lines separating "your version" from "their version." Resolving it means opening the file, deciding what the final content should actually be, deleting those marker lines once you've decided, then git add and git commit to finish the merge like any other change.

That's the whole everyday rhythm: pull before you start, commit in small, meaningful chunks, push often, and reach for a branch whenever you're about to do something you wouldn't want to hit main if it goes sideways. Everything else — GitHub's pull request reviews, tags, rebasing — is a refinement on top of these same five commands, not a replacement for them.

Git Bash — the daily loop
git pull

# ...make your edits...

git add .
git commit -m "Describe what changed"
git push

git pull first brings your local copy up to date. git add . stages every changed file, git commit saves the snapshot, and git push sends it to GitHub.

Git Bash — branch, then merge it back
git checkout -b new-feature

# ...commit your work on the branch as usual, then push it...
git push -u origin new-feature

# once the branch is ready to fold back in:
git checkout main
git pull
git merge new-feature
git push

git checkout -b creates and switches to a new branch in one step. Committing and pushing while on it works exactly like on main. Merging happens from main: check it out, pull the latest, then git merge brings the branch's commits in.

Continue reading: Git Branching Strategies →