FirstHack Learn
Log in Sign up free
Lessons in this course 0/6 All courses Git and GitHub for Students

First year

Progress0 / 6 lessons
  1. 1. What version control actually solves
  2. 2. init, add, commit: what a commit really is
  3. 3. Branches and merging
  4. 4. Remotes, push, pull and the rejected-push error
  5. 5. Merge conflicts, resolved step by step
  6. 6. Pull requests, .gitignore and a good README

Courses › Git and GitHub for Students

Branches and merging

Try risky changes safely, then fold them back into the main line.

11 min read · Lesson 3 of 6 · Free

The problem branches solve

Your project works. The demo is Friday. You want to try a completely different login screen, but if it goes wrong you must be able to get the working version back in seconds.

Copying the folder is what students do. Then the two copies drift apart and merging them by hand takes an evening.

A branch is Git's answer: a second line of history that can be thrown away or merged back with one command.

A branch is a pointer

This is the whole secret. A branch is not a copy of your files. It is a 41-byte file containing the hash of one commit. main is a pointer. login-redesign is another pointer. When you commit, the pointer you are on moves forward.

That is why creating a branch is instant, even in a project with ten thousand files.

HEAD is another pointer. It points at the branch you are currently on.

Create and switch

BASH
git branch
git switch -c login-redesign
git branch

git switch -c creates the branch and moves onto it. The star in git branch output marks where you are.

You may see git checkout -b login-redesign in older tutorials. It does the same thing. switch is newer and clearer, because checkout also does several unrelated jobs.

Now work normally:

BASH
echo "// new login screen" > login.js
git add login.js
git commit -m "Start new login screen"

Switch back and look:

BASH
git switch main
ls

login.js is gone from the folder. It is not lost. It lives on the other branch, and it comes back when you switch there. Git rewrites the files in your folder to match whichever branch you moved to.

Merging

Get onto the branch that should receive the changes, then merge.

BASH
git switch main
git merge login-redesign

Two things can happen.

Fast-forward. If main has no new commits since you branched, Git just slides the main pointer forward. No merge commit is created. The message says Fast-forward.

Three-way merge. If main moved on too, Git builds a new commit with two parents, joining both lines. The message says Merge branch 'login-redesign'.

If both branches changed the same lines of the same file, Git stops and asks you to decide. That is a merge conflict, and it gets a whole lesson.

Delete the branch after merging

BASH
git branch -d login-redesign

Lowercase -d refuses if the branch is not merged, which protects you. Uppercase -D deletes anyway and loses those commits. Use -D only when you are sure the experiment failed.

See the shape of your history

BASH
git log --oneline --graph --all --decorate

Output looks like this:

Code
*   9f3c2a1 (HEAD -> main) Merge branch 'login-redesign'
|\
| * 7b21d40 (login-redesign) Style the login form
| * 4c88e19 Start new login screen
* | 2ad91f7 Fix attendance count bug
|/
* 1e40b3a Add students array

Read it bottom to top. One line split into two, then joined. Once you can read this graph, Git stops feeling mysterious.

A branch naming habit

Code
feature/attendance-export
fix/login-crash
docs/readme-setup

Names that say what and why. In a four-person project this saves real time.

⚠️

Commit or stash before you switch branches. If you have uncommitted changes that clash with the target branch, Git refuses and prints "Your local changes would be overwritten by checkout". Do not try to force past it. Either commit the work, or park it:

BASH
git stash
git switch main
git switch -
git stash pop

git switch - goes back to the previous branch.

When to branch

Honest answer for a student project: one branch per feature, one branch per person, or both. Keep main in a state that always runs. If someone asks for a demo, you should be able to show main without fear.

💡

Practise merging in a throwaway folder before you need it for real. Make a repo, two branches, edit different files, merge. Then do it again editing the same file, and watch the conflict appear. Ten minutes of practice removes the panic when it happens the night before submission.

Next: putting all of this on GitHub, and fixing the rejected push.