Merging branches
25 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)Showing steps for Windows. They are marked “On Windows” below.
When the work on a branch is finished, you merge it: Git brings its commits into the branch you are on, usually main. If main has not moved, the merge is a simple fast-forward; if both branches moved, Git makes a new merge commit.
Merge a branch into main
Merging is joining the work of one branch into another. git merge <branch> brings the commits of that branch into the branch you are on; the merged branch itself does not change.
A merge always goes into the branch you are on. So first git switch main, check that git status is clean, then run git merge add-stapler.
Example 1 · Before the merge: main is behind
Runs in: Your terminal
PS C:\Users\Priya\price-list> git log --oneline --all --graph* 9eff46c (HEAD -> add-stapler) Add stapler to the price list * d504b31 (main) Add README * 9d23448 Add price list
What this code does
add-staplerhas one new commit,9eff46c.mainstill points tod504b31and has nothing new of its own.- HEAD is on
add-stapler, so the first step of the merge is to switch tomain.
After every merge, check the result. Git joins lines of text; only opening the file or running the project proves the result still works.
Fast-forward merge
A fast-forward merge happens when the current branch has no new commits of its own. Git simply moves the branch label forward to the other branch's latest commit; no new commit is made and the history stays a straight line.
main is still at d504b31, and add-stapler is that same history plus one commit. Git has nothing to combine, so it slides the main label forward.
Example 2 · A fast-forward merge
Runs in: Your terminal
PS C:\Users\Priya\price-list> git switch mainPS C:\Users\Priya\price-list> git merge add-staplerPS C:\Users\Priya\price-list> git log --oneline --graphOutputSwitched to branch 'main' Updating d504b31..9eff46c Fast-forward prices.txt | 1 + 1 file changed, 1 insertion(+) * 9eff46c (HEAD -> main, add-stapler) Add stapler to the price list * d504b31 Add README * 9d23448 Add price list
What this code does
Updating d504b31..9eff46candFast-forward:mainmoved from its old commit to the branch's latest commit.- No new commit was made. The history is still one straight line, and
mainandadd-staplernow point to the same commit.
Run git merge add-stapler a second time and Git prints Already up to date.: that branch has nothing new for main.
Three-way merge
A three-way merge is used when both branches have new commits. Git compares three snapshots: the latest commit of each branch and the merge base, the commit where they split. It combines the changes from both sides in a new commit.
Priya made add-ruler for ruler. Meanwhile, on main, she added the opening hours to the README. Both branches moved after 9eff46c, so a label cannot just slide forward.
Example 3 · Both branches moved: a three-way merge
Runs in: Your terminal
PS C:\Users\Priya\price-list> git merge add-rulerPS C:\Users\Priya\price-list> git log --oneline --graphOutputMerge made by the 'ort' strategy. prices.txt | 1 + 1 file changed, 1 insertion(+) * fe972ae (HEAD -> main) Merge branch 'add-ruler' |\ | * 8870326 (add-ruler) Add ruler * | 59193dc Add opening hours to README |/ * 9eff46c (add-stapler) Add stapler to the price list * d504b31 Add README * 9d23448 Add price list
What this code does
- Before printing anything, Git opened Notepad (or VS Code) with the message
Merge branch 'add-ruler'. Priya closed it to accept the message. ortis the name of Git's default merge method. The new commitfe972aejoins the two lines of the graph.add-rulerchangedprices.txtandmainchangedREADME.md, so Git combined both without any help.
If both branches changed the same lines, Git cannot combine them by itself. That is a merge conflict, the topic of Merge conflicts (opens in a new tab).
The merge commit
A merge commit is the commit a three-way merge creates. Unlike a normal commit it has two parents, the latest commit of each branch, and its default message is Merge branch '<name>'.
Git needs a message for the merge commit, so it opens your Git editor with Merge branch 'add-ruler' already written. Accept it, and the merge finishes. git log -1 then shows the two parents on the Merge: line.
On Windows
On Windows the editor is the one you picked when you installed Git: Notepad or VS Code. In Notepad, close the window (save if it asks). In VS Code, close the tab with Ctrl + W. PowerShell waits until you do, then finishes the merge.
PS C:\Users\Priya\price-list> git log -1commit fe972ae957eee82add6843bce16f6311d776228f (HEAD -> main) Merge: 59193dc 8870326 Author: Priya Sharma <priya@example.com> Date: Mon Oct 12 10:18:00 2026 +0530 Merge branch 'add-ruler'
Merge: 59193dc 8870326lists the two parents:main's last commit andadd-ruler's last commit.git merge --no-edit add-ruleraccepts the message without opening the editor.
git merge --no-ff <branch> makes one anyway.Delete a merged branch
After the merge, the label add-stapler has done its job. git branch -d deletes it; the commits stay, because main contains them. git branch --merged lists the branches that are safe to delete.
On Windows
In PowerShell, on main:
PS C:\Users\Priya\price-list> git branch --mergedPS C:\Users\Priya\price-list> git branch -d add-stapler add-rulerOutput add-stapler add-ruler * main Deleted branch add-stapler (was 9eff46c). Deleted branch add-ruler (was 8870326).
- Only the labels are gone. The stapler and ruler commits are still in
main's history. - For a branch that was never merged,
-drefuses:error: the branch 'try-discount' is not fully merged.git branch -D try-discountdeletes it anyway and its commits are lost from view, so use-Donly for experiments you want to throw away.
main moved while you worked, run git merge main on your feature branch first and test there; then the merge into main is easy.Next step
Check your understanding
10 quick questions