Branches
On This Lesson 11 topics
Lesson Overview
So far your history is one straight line of commits. Real work is not that tidy. You want to try a new feature while the working version stays safe. You want to fix an urgent bug while a half-finished feature sits in your files. You and a teammate each need your own space to work.
A branch solves this: it is a separate line of commits that starts from some point in the history. You can build and break things there, and the main line stays working. When the work is good, you combine it back (that is the next lesson).
In the album analogy, a branch is a parallel copy of the album where you can add new pages without touching the original. In this lesson you will create, list, switch, and delete branches, and learn the one thing that surprises beginners: what happens to your files when you switch.
You need a repository with at least one commit (lessons L02 and L03). Outputs below come from Git 2.44; hashes will differ for you.
Learning Objectives
By the end of this lesson you will be able to:
- Explain what a branch is and why teams keep
mainworking. - List branches with
git branchand see which one you are on. - Create and switch to a branch with
git switch -c, and switch back withgit switch. - Predict what your files look like after switching branches.
- Draw a history with two diverging branches and read it with
git log --graph. - Delete a branch with
git branch -dand explain why Git sometimes refuses. - Choose a small, descriptive branch name.
Written Explanation
What a branch is
A branch is a named line of development. Technically, Git stores a branch as a small pointer to a commit. When you commit while "on" a branch, that pointer moves forward to the new commit. Creating a branch is therefore cheap and fast: Git does not copy your project, it just adds another pointer. That is why teams create branches freely, often one per task.
HEAD is Git's marker for "where you are now": it points at the branch you are on. In git log --oneline --decorate, you see it as (HEAD -> main).
The default branch of a project is usually called main (older repositories often use master; lesson L02 explained why). By convention, main holds code that works. New work happens on other branches and is brought into main once it is ready.
Listing branches
git branch* mainThe * marks the branch you are on. With one branch, that is all you see. git branch -v adds each branch's latest commit.
Creating and switching: git switch
Create a branch and move to it in one step:
git switch -c add-interestSwitched to a new branch 'add-interest'git branch* add-interest
main-c stands for "create". To go back to an existing branch, leave -c off:
git switch mainSwitched to branch 'main'Older tutorials use git checkout -b name and git checkout name for the same two jobs. They still work; git switch is the newer, clearer command for moving between branches, and the one this course uses. If you are on a very old Git that does not know switch, update Git or use checkout.
What happens to your files when you switch
This is the key surprise. Your working folder always shows the files of the branch you are on. When you switch, Git rewrites the files in your folder to match the other branch.
Suppose on add-interest you create and commit Interest.java. Then:
ls *.javaAccount.java
Interest.javagit switch main
ls *.javaAccount.javaInterest.java is gone from the folder. It is not deleted: it lives safely in the commits of add-interest. Switch back and it reappears. If your editor or IDE has the file open, it will update or ask you to reload; the exact behaviour depends on the tool.
Uncommitted changes. Git is careful with edits you have not committed. If your uncommitted changes do not clash with the other branch, Git carries them along to the new branch. If they would be overwritten, Git refuses to switch and tells you. The safest habit: commit (or deliberately set aside) your work before switching, so you always know which branch owns which change.
Diverging histories
Create a branch, commit on it, switch to main, and commit there too. Now the histories have diverged. git log --oneline --graph --all --decorate draws them:
* 4b9cb47 (feature) Add B on feature
| * 38db0ef (HEAD -> main) Edit A on main
|/
* 42d209f Add ARead it from the bottom: both branches share the commit Add A, then each has its own commit. The * marks commits and | and / show the lines splitting. --all shows every branch, not only the current one; --decorate labels where each branch points. This picture is the starting point of the next lesson, where the two lines are joined.
Deleting a branch
After the work of a branch is merged, the branch name is no longer needed:
git branch -d add-interestIf the branch has commits that are not in your current branch, Git refuses:
error: the branch 'add-interest' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D add-interest'That refusal is a safety net: deleting would leave commits that nothing points to. -D (capital) forces the deletion. Use it only when you are sure the work is not needed.
Good branch names and habits
- Name by purpose:
add-interest,fix-negative-balance. Avoidtest,new,stuff. - Use lowercase and hyphens; avoid spaces.
- One purpose per branch keeps changes easy to review and easy to merge.
- Keep branches short-lived. A branch open for weeks drifts far from
main, which makes the later merge harder.
Examples
Example 1: Your first branch (simple)
git switch -c greetingEdit Hello.java, then:
git add Hello.java
git commit -m "Print a full greeting"
git switch mainOpen Hello.java: it shows the old text, because main has not got the change yet. Switch back with git switch greeting and the new text returns. Nothing was lost; you were looking at two different pages of the album.
Example 2: A feature branch for the bank (practical)
You want to add interest to the Bank Accounts project, but main should keep compiling at all times.
git switch -c add-interestYou create Interest.java and commit it:
git add Interest.java
git commit -m "Add Interest class with yearly interest"An hour later you find that a typo in the account number check needs an urgent fix. Switch to main, fix it there, commit, and switch back to add-interest to continue. Each task has its own place, and neither disturbs the other.
Example 3: Uncommitted changes meet a switch (realistic)
You edit Account.java on main and forget to commit. You run:
git switch -c wip
git status -s M Account.javaBecause the new branch starts at the same commit, your edit comes along and shows as modified on wip. You commit it there, switch back to main, and the edit is not on main any more: it belongs to wip. The lesson: an uncommitted change is not owned by any branch yet, and it moves with you. To avoid surprises, commit before you switch, or create the branch first, then edit.
Backend Insight
Backend teams are rarely alone in a repository, and the code on main is often what gets built and deployed. A rule seen in many teams is "never commit unfinished work directly to main": each task gets a branch, is reviewed, and only then joins main. This is the basis of the pull-request workflow you will meet in BEG-047 and JNR-053.
Branches are also how you work on two things at once without risk: an urgent production bug fix goes on its own short branch from main, while your long feature stays on another. Small branches with one purpose are easy to read, test, and, if needed, discard, which reduces the risk of every release.
Common Mistakes
Mistake 1: Working on main by habit
- Incorrect: editing and committing straight on
mainwhile a feature is half done. - Correct:
git switch -c feature-namefirst, then edit.
How to avoid it: run git status or git branch at the start of a session to check where you are. git status prints On branch ... on its first line.
Mistake 2: Thinking switching deletes your files
When a file disappears after git switch, it is just not part of that branch. Switch back and it returns. Panic is not needed.
Mistake 3: Forgetting where you are
Beginners often commit on the wrong branch. Always check the branch name before committing. Many terminals and IDEs can show it in the prompt or status bar; the setup varies by tool.
Mistake 4: Using -D to silence a refusal
If git branch -d says "not fully merged", read why. Deleting with -D throws away commits you may need.
Exercises
Level A: Foundation
A1. What does the * mean in git branch output?
Show solution A1
A1. It marks the branch you are currently on.
A2. Write the command that creates a branch named fix-rounding and switches to it.
Show solution A2
A2. git switch -c fix-rounding.
A3. Write the command that moves you back to main.
Show solution A3
A3. git switch main.
Level B: Application
B1. In a repository, create a branch greeting, add a new file Bye.java, and commit it. Switch to main. Does Bye.java exist? Does it exist after you switch back? Explain.
Show solution B1
B1. After switching to main, Bye.java does not exist in the folder, because its commit is only on greeting. After git switch greeting it exists again. Switching rewrites the working files to match the branch; nothing was deleted.
B2. Create a branch, make one commit on it, switch to main, and make one commit there too. Which command draws both lines, and what does the output look like?
Show solution B2
B2. git log --oneline --graph --all --decorate. The output shows a shared commit at the bottom and two lines splitting from it, one commit each, with branch names beside the latest commits.
B3. Pick better names for these branches: test, new, my-branch. The work is: adding a deposit limit, fixing a crash on empty names, and renaming classes.
Show solution B3
B3. Examples: add-deposit-limit, fix-empty-name-crash, rename-account-classes. Any name describing the purpose is fine.
Level C: Challenge
C1. You are on main and you edit Account.java but have not committed. You then realise the change belongs on a new branch called add-limit. What do you run, and where does the change end up? Where will it not be?
Show solution C1
C1. Run git switch -c add-limit. The uncommitted change comes with you and is a modification on add-limit. Commit it there. It is not on main, because it was never committed there.
C2. git branch -d add-interest prints "not fully merged". Explain what that means, and describe two different choices you have.
Show solution C2
C2. The branch has commits that the current branch does not contain, so deleting it would leave them unreachable. Choice one: merge the branch first (next lesson), then delete with -d. Choice two: if you are certain the work is not needed, delete it anyway with git branch -D add-interest.
Mini Challenge
In a practice repository, create two branches from main with different purposes (for example add-farewell and fix-typo). Make one commit on each. Return to main and draw, on paper, the picture of the three lines of history you expect. Then run git log --oneline --graph --all --decorate and compare.
Check your work: your drawing and the real graph agree; each branch name describes its purpose; you checked git status before every commit to confirm the branch.
Summary & Next Lesson
Key takeaways
- A branch is a separate line of commits; creating one is cheap.
git switch -c namecreates and switches;git switch namemoves between branches;git branchlists them.- Switching rewrites your working files to match the branch; nothing is lost.
- Commit before you switch; uncommitted edits travel with you.
git branch -drefuses to delete unmerged work;-Dforces it.- Keep
mainworking and use short, purposeful branches.
Next lesson
Next is "Merging and conflicts": you will bring a branch's commits back into main, and learn what to do when both branches changed the same lines.
Self-check
- Which command creates and switches to a new branch?
- What does
HEADpoint at? - A file vanished after
git switch main. Is it deleted? - Why does
git branch -dsometimes refuse? - Why keep branches small?
Show answers
git switch -c name.- The branch (and so the commit) you are currently on.
- No. It is not part of
main; it is safe in the other branch. - The branch contains commits not yet in the current branch, so deleting would lose them.
- They are easier to review and merge, and drift less from
main.
References
- Pro Git book, "Basic Branching and Merging". It supports creating and switching branches, that
git branch -dremoves merged branches, and the divergent-history picture. The page usesgit checkout -b;git switch -cis the newer equivalent and I verified it by running it with Git 2.44. - Git documentation,
git log. It supports--onelineand--graph. I read only the first part of the page. - Not verified from an official page: the claim that a branch is stored as a pointer to a commit, the exact conditions under which uncommitted changes are carried across a switch, and "many teams" avoid direct commits to
main. These come from general Git knowledge and from running the commands.
Practice
Apply this lesson with the module's lab, exercises and quiz.
Marking a lesson complete is optional and you can undo it any time. Your progress stays in this browser.