Branching & Merging
Advanced · 17 min read · ▶ live playground · ✦ checkpoint
A branch lets you try the risky idea without making main wobble. Branching is working on a separate named line of Git history, and merging is bringing commits from one branch into another when the work is ready.
This is the daily shape of professional Git: keep main steady, do focused work somewhere else, inspect it, then merge it back.
Create and Switch Branches
A branch is a named line of commits, like a side road that starts from the current point in history. In Git, main is not special because it has magic powers; it is special because your team treats it as the reliable line.
Before branching, start clean. Then Maya creates a branch, edits menu.py in her editor, and commits on that branch:
$ git status --short
$ git branch
* main
$ git switch -c add-sandwich
Switched to a new branch 'add-sandwich'
$ git status --short
M menu.py
$ git add menu.py
$ git commit -m "Add sandwich option"
[add-sandwich 17be6bd] Add sandwich option
1 file changed, 1 insertion(+)
$ git switch main
Switched to branch 'main'git branch lists local branches. The * marks the current branch, which is the branch new commits will attach to. git switch -c add-sandwich creates a new branch and switches to it in one move.
The status, add, commit loop stays the same. That commit belongs to add-sandwich, not main. Think of the branch name as a movable bookmark. Each commit moves the bookmark forward on that line.
If your editor shows the sandwich line disappearing, that is not Git losing work. You changed which branch's snapshot your workbench is showing. Switch back to add-sandwich, and the line returns.
Merge Clean Work
A merge is Git combining the commits from one branch into the branch you currently have checked out. The direction matters: switch to the branch that should receive the work, then merge the branch that contains the work.
Here main should receive the sandwich change:
$ git merge add-sandwich
Updating 8fc6f06..17be6bd
Fast-forward
menu.py | 1 +
1 file changed, 1 insertion(+)
$ git log --oneline --graph --all -3
* 17be6bd Add sandwich option
* 8fc6f06 Start lunch menu
$ git branch -d add-sandwich
Deleted branch add-sandwich (was 17be6bd).A fast-forward merge is a merge where the receiving branch has no extra commits of its own, so Git just moves its bookmark forward. No extra merge commit is needed because history is still one straight line.
Deleting the branch name with git branch -d add-sandwich does not delete the commit. It removes the side-road label after the work is already part of main.
A merge commit is a commit that joins two lines of history when both branches have moved. You will see those when Git needs a visible "these lines came together here" checkpoint, especially after conflicts.
Resolve Conflicts
A merge conflict is Git stopping because two branches changed the same part of a file and Git cannot safely choose one version. This is not a disaster. It is Git refusing to guess.
Maya creates a branch called rename-title and changes the first line to print("Team lunch menu"). Meanwhile, main changes that same line to print("Friday lunch menu"). When she tries to merge, Git stops:
$ git merge rename-title
Auto-merging menu.py
CONFLICT (content): Merge conflict in menu.py
Automatic merge failed; fix conflicts and then commit the result.
$ git status --short
UU menu.pyUU means both branches changed the file and the file is unresolved. Open the file and Git has inserted conflict markers, which are special lines showing the current branch version, the incoming branch version, and the divider between them:
<<<<<<< HEAD
print("Friday lunch menu")
=======
print("Team lunch menu")
>>>>>>> rename-title
print("Soup")
print("Sandwich")<<<<<<< HEAD starts the version from the branch you had checked out, usually main. ======= separates the two versions. >>>>>>> rename-title ends the incoming branch's version.
Resolving means editing the file into the final text you actually want and removing every marker line. Maya wants both ideas:
print("Friday team lunch menu")
print("Soup")
print("Sandwich")After saving the resolved file, stage it and commit:
$ git add menu.py
$ git status --short
M menu.py
$ git commit -m "Merge lunch title changes"
[main 65498ae] Merge lunch title changes
$ git log --oneline --graph --all -4
* 65498ae Merge lunch title changes
|\
| * 1c1f78b Rename menu title for team
* | de94a75 Rename menu title for Friday
|/
* 17be6bd Add sandwich optionThe little graph is Git showing the two lines joining. The merge commit is the knot where they meet.
Use a Feature-Branch Workflow
A feature branch is a short-lived branch for one focused task, such as add-login-form, fix-tax-rounding, or refactor-menu-pricing. The branch name should say the job, not the mood.
Use this loop for solo work today and team work later:
- Start clean on
main:git switch main, thengit status --short. - Create the branch:
git switch -c add-weekly-special. - Edit files, run tests, and inspect with
git diff. - Commit the focused work:
git add menu.py, thengit commit -m "Add weekly special". - Return and merge:
git switch main, thengit merge add-weekly-special. - Clean up the label:
git branch -d add-weekly-special.
Keep branches small. One branch for "add weekly special" is easy to review and merge. One branch for "rewrite menu, rename files, fix tests, change formatting, and update docs" is a traffic jam.
Branches are cheap, but attention is not. Create a branch when the work has a clear purpose, commit in small checkpoints, merge when the branch is complete, then delete the branch label.
Checkpoint
Answer all three to mark this lesson complete
You can now keep risky or unfinished work off main and bring it back deliberately. Next you'll move that same workflow onto GitHub with remotes, pushes, pulls, and pull requests.