âčïž Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell |
| Last Crawled | 2026-04-12 07:10:40 (15 hours ago) |
| First Indexed | 2014-10-27 12:00:30 (11 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Git - Branches in a Nutshell |
| Meta Description | null |
| Meta Canonical | null |
| Boilerpipe Text | Nearly every VCS has some form of branching support.
Branching means you diverge from the main line of development and continue to do work without messing with that main line.
In many VCS tools, this is a somewhat expensive process, often requiring you to create a new copy of your source code directory, which can take a long time for large projects.
Some people refer to Gitâs branching model as its âkiller feature,â and it certainly sets Git apart in the VCS community.
Why is it so special?
The way Git branches is incredibly lightweight, making branching operations nearly instantaneous, and switching back and forth between branches generally just as fast.
Unlike many other VCSs, Git encourages workflows that branch and merge often, even multiple times in a day.
Understanding and mastering this feature gives you a powerful and unique tool and can entirely change the way that you develop.
To really understand the way Git does branching, we need to take a step back and examine how Git stores its data.
As you may remember from
What is Git?
, Git doesnât store data as a series of changesets or differences, but instead as a series of
snapshots
.
When you make a commit, Git stores a commit object that contains a pointer to the snapshot of the content you staged.
This object also contains the authorâs name and email address, the message that you typed, and pointers to the commit or commits that directly came before this commit (its parent or parents): zero parents for the initial commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches.
To visualize this, letâs assume that you have a directory containing three files, and you stage them all and commit.
Staging the files computes a checksum for each one (the SHA-1 hash we mentioned in
What is Git?
), stores that version of the file in the Git repository (Git refers to them as
blobs
), and adds that checksum to the staging area:
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
When you create the commit by running
git commit
, Git checksums each subdirectory (in this case, just the root project directory) and stores them as a tree object in the Git repository.
Git then creates a commit object that has the metadata and a pointer to the root project tree so it can re-create that snapshot when needed.
Your Git repository now contains five objects: three
blobs
(each representing the contents of one of the three files), one
tree
that lists the contents of the directory and specifies which file names are stored as which blobs, and one
commit
with the pointer to that root tree and all the commit metadata.
Figure 9. A commit and its tree
If you make some changes and commit again, the next commit stores a pointer to the commit that came immediately before it.
Figure 10. Commits and their parents
A branch in Git is simply a lightweight movable pointer to one of these commits.
The default branch name in Git is
master
.
As you start making commits, youâre given a
master
branch that points to the last commit you made.
Every time you commit, the
master
branch pointer moves forward automatically.
Note
The âmasterâ branch in Git is not a special branch.
It is exactly like any other branch.
The only reason nearly every repository has one is that the
git init
command creates it by default and most people donât bother to change it.
Figure 11. A branch and its commit history
Creating a New Branch
What happens when you create a new branch?
Well, doing so creates a new pointer for you to move around.
Letâs say you want to create a new branch called
testing
.
You do this with the
git branch
command:
$ git branch testing
This creates a new pointer to the same commit youâre currently on.
Figure 12. Two branches pointing into the same series of commits
How does Git know what branch youâre currently on?
It keeps a special pointer called
HEAD
.
Note that this is a lot different than the concept of
HEAD
in other VCSs you may be used to, such as Subversion or CVS.
In Git, this is a pointer to the local branch youâre currently on.
In this case, youâre still on
master
.
The
git branch
command only
created
a new branchâââit didnât switch to that branch.
Figure 13. HEAD pointing to a branch
You can easily see this by running a simple
git log
command that shows you where the branch pointers are pointing.
This option is called
--decorate
.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
You can see the
master
and
testing
branches that are right there next to the
f30ab
commit.
Switching Branches
To switch to an existing branch, you run the
git checkout
command.
Letâs switch to the new
testing
branch:
$ git checkout testing
This moves
HEAD
to point to the
testing
branch.
Figure 14. HEAD points to the current branch
What is the significance of that?
Well, letâs do another commit:
$ vim test.rb
$ git commit -a -m 'Make a change'
Figure 15. The HEAD branch moves forward when a commit is made
This is interesting, because now your
testing
branch has moved forward, but your
master
branch still points to the commit you were on when you ran
git checkout
to switch branches.
Letâs switch back to the
master
branch:
$ git checkout master
Note
git log
doesnât show
all
the branches
all
the time
If you were to run
git log
right now, you might wonder where the "testing" branch you just created went, as it would not appear in the output.
The branch hasnât disappeared; Git just doesnât know that youâre interested in that branch and it is trying to show you what it thinks youâre interested in.
In other words, by default,
git log
will only show commit history below the branch youâve checked out.
To show commit history for the desired branch you have to explicitly specify it:
git log testing
.
To show all of the branches, add
--all
to your
git log
command.
Figure 16. HEAD moves when you checkout
That command did two things.
It moved the HEAD pointer back to point to the
master
branch, and it reverted the files in your working directory back to the snapshot that
master
points to.
This also means the changes you make from this point forward will diverge from an older version of the project.
It essentially rewinds the work youâve done in your
testing
branch so you can go in a different direction.
Note
Switching branches changes files in your working directory
Itâs important to note that when you switch branches in Git, files in your working directory will change.
If you switch to an older branch, your working directory will be reverted to look like it did the last time you committed on that branch.
If Git cannot do it cleanly, it will not let you switch at all.
Letâs make a few changes and commit again:
$ vim test.rb
$ git commit -a -m 'Make other changes'
Now your project history has diverged (see
Divergent history
).
You created and switched to a branch, did some work on it, and then switched back to your main branch and did other work.
Both of those changes are isolated in separate branches: you can switch back and forth between the branches and merge them together when youâre ready.
And you did all that with simple
branch
,
checkout
, and
commit
commands.
Figure 17. Divergent history
You can also see this easily with the
git log
command.
If you run
git log --oneline --decorate --graph --all
it will print out the history of your commits, showing where your branch pointers are and how your history has diverged.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Make other changes
| * 87ab2 (testing) Make a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commit of my project
Because a branch in Git is actually a simple file that contains the 40 character SHA-1 checksum of the commit it points to, branches are cheap to create and destroy.
Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline).
This is in sharp contrast to the way most older VCS tools branch, which involves copying all of the projectâs files into a second directory.
This can take several seconds or even minutes, depending on the size of the project, whereas in Git the process is always instantaneous.
Also, because weâre recording the parents when we commit, finding a proper merge base for merging is automatically done for us and is generally very easy to do.
These features help encourage developers to create and use branches often.
Letâs see why you should do so.
Note
Creating a new branch and switching to it at the same time
Itâs typical to create a new branch and want to switch to that new branch at the same timeâââthis can be done in one operation with
git checkout -b <newbranchname>
.
Note
From Git version 2.23 onwards you can use
git switch
instead of
git checkout
to:
Switch to an existing branch:
git switch testing-branch
.
Create a new branch and switch to it:
git switch -c new-branch
.
The
-c
flag stands for create, you can also use the full flag:
--create
.
Return to your previously checked out branch:
git switch -
. |
| Markdown | [](https://git-scm.com/) \--distributed-is-the-new-centralized

- [About](https://git-scm.com/about)
- [Trademark](https://git-scm.com/about/trademark)
- [Learn](https://git-scm.com/learn)
- [Book](https://git-scm.com/book)
- [Cheat Sheet](https://git-scm.com/cheat-sheet)
- [Videos](https://git-scm.com/videos)
- [External Links](https://git-scm.com/doc/ext)
- [Tools](https://git-scm.com/tools)
- [Command Line](https://git-scm.com/tools/command-line)
- [GUIs](https://git-scm.com/tools/guis)
- [Hosting](https://git-scm.com/tools/hosting)
- [Reference](https://git-scm.com/docs)
- [Install](https://git-scm.com/install/linux)
- [Community](https://git-scm.com/community)
***
This book is available in [English](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell).
Full translation available in
| |
|---|
| [azÉrbaycan dili](https://git-scm.com/book/az/v2/Git%E2%80%99d%C9%99-Branch-Nutshell%E2%80%99d%C9%99-Branch%E2%80%99lar), |
| [бŃлгаŃŃĐșĐž ДзОĐș](https://git-scm.com/book/bg/v2/%D0%9A%D0%BB%D0%BE%D0%BD%D0%BE%D0%B2%D0%B5-%D0%B2-Git-%D0%9D%D0%B0%D0%BA%D1%80%D0%B0%D1%82%D0%BA%D0%BE-%D0%B7%D0%B0-%D1%80%D0%B0%D0%B7%D0%BA%D0%BB%D0%BE%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F%D1%82%D0%B0), |
| [Deutsch](https://git-scm.com/book/de/v2/Git-Branching-Branches-auf-einen-Blick), |
| [Español](https://git-scm.com/book/es/v2/Ramificaciones-en-Git-%C2%BFQu%C3%A9-es-una-rama), |
| [Ùۧ۱۳Û](https://git-scm.com/book/fa/v2/%D8%A7%D9%86%D8%B4%D8%B9%D8%A7%D8%A8%E2%80%8C%DA%AF%DB%8C%D8%B1%DB%8C-%D8%AF%D8%B1-%DA%AF%DB%8C%D8%AA-Git-Branching-%D8%B4%D8%A7%D8%AE%D9%87%E2%80%8C%D9%87%D8%A7-%D8%AF%D8%B1-%DB%8C%DA%A9-%D9%86%DA%AF%D8%A7%D9%87-Branches-in-a-Nutshell), |
| [Français](https://git-scm.com/book/fr/v2/Les-branches-avec-Git-Les-branches-en-bref), |
| [ÎλληΜÎčÎșÎŹ](https://git-scm.com/book/gr/v2/%CE%94%CE%B9%CE%B1%CE%BA%CE%BB%CE%B1%CE%B4%CF%8E%CF%83%CE%B5%CE%B9%CF%82-%CF%83%CF%84%CE%BF-Git-%CE%9F%CE%B9-%CE%BA%CE%BB%CE%AC%CE%B4%CE%BF%CE%B9-%CE%BC%CE%B5-%CE%BB%CE%AF%CE%B3%CE%B1-%CE%BB%CF%8C%CE%B3%CE%B9%CE%B1), |
| [æ„æŹèȘ](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%A8%E3%81%AF), |
| [íê”ìŽ](https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80), |
| [Nederlands](https://git-scm.com/book/nl/v2/Branchen-in-Git-Branches-in-vogelvlucht), |
| [Đ ŃŃŃĐșĐžĐč](https://git-scm.com/book/ru/v2/%D0%92%D0%B5%D1%82%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B2-Git-%D0%9E-%D0%B2%D0%B5%D1%82%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B8-%D0%B2-%D0%B4%D0%B2%D1%83%D1%85-%D1%81%D0%BB%D0%BE%D0%B2%D0%B0%D1%85), |
| [SlovenĆĄÄina](https://git-scm.com/book/sl/v2/Veje-Git-Veje-na-kratko), |
| [ĐĄŃĐżŃĐșĐž](https://git-scm.com/book/sr/v2/%D0%93%D1%80%D0%B0%D0%BD%D0%B0%D1%9A%D0%B5-%D1%83-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D1%83-%D0%93%D0%B8%D1%82-%D0%A3%D0%BA%D1%80%D0%B0%D1%82%D0%BA%D0%BE-%D0%BE-%D0%B3%D1%80%D0%B0%D0%BD%D0%B0%D1%9A%D1%83), |
| [Svenska](https://git-scm.com/book/sv/v2/Git-grenar-Grenar-i-korthet), |
| [Tagalog](https://git-scm.com/book/tl/v2/Pag-branch-ng-Git-Mga-Branch-sa-Maikling-Salita), |
| [TĂŒrkçe](https://git-scm.com/book/tr/v2/Git-Dallar%C4%B1-Dallar). |
| [ĐŁĐșŃаŃĐœŃŃĐșа](https://git-scm.com/book/uk/v2/%D0%93%D0%B0%D0%BB%D1%83%D0%B6%D0%B5%D0%BD%D0%BD%D1%8F-%D0%B2-git-%D0%93%D1%96%D0%BB%D0%BA%D0%B8-%D1%83-%D0%BA%D1%96%D0%BB%D1%8C%D0%BA%D0%BE%D1%85-%D1%81%D0%BB%D0%BE%D0%B2%D0%B0%D1%85), |
| [çźäœäžæ](https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B), |
Partial translations available in
| |
|---|
| [ÄeĆĄtina](https://git-scm.com/book/cs/v2/V%C4%9Btve-v-syst%C3%A9mu-Git-V%C4%9Btve-v-kostce), |
| [ĐаĐșĐ”ĐŽĐŸĐœŃĐșĐž](https://git-scm.com/book/mk/v2/%D0%93%D1%80%D0%B0%D0%BD%D0%B5%D1%9A%D0%B5-%D0%B2%D0%BE-Git-%D0%93%D1%80%D0%B0%D0%BD%D0%B5%D1%9A%D0%B5-%D0%BE%D0%B1%D1%98%D0%B0%D1%81%D0%BD%D0%B5%D1%82%D0%BE), |
| [Polski](https://git-scm.com/book/pl/v2/Ga%C5%82%C4%99zie-Gita-Czym-jest-ga%C5%82%C4%85%C5%BA), |
| [PortuguĂȘs (Brasil)](https://git-scm.com/book/pt-br/v2/Branches-no-Git-Branches-em-poucas-palavras), |
| [ĐзбДĐșŃа](https://git-scm.com/book/uz/v2/Git-%D0%B4%D0%B0-%D1%82%D0%B0%D1%80%D0%BC%D0%BE%D2%9B%D0%BB%D0%B0%D0%BD%D0%B8%D1%88-%D0%A2%D0%B0%D1%80%D0%BC%D0%BE%D2%9B%D0%BB%D0%B0%D0%BD%D0%B8%D1%88-%D2%B3%D0%B0%D2%9B%D0%B8%D0%B4%D0%B0-%D0%B8%D0%BA%D0%BA%D0%B8-%D0%BE%D2%93%D0%B8%D0%B7-%D1%81%D1%9E%D0%B7), |
| [çčé«äžæ](https://git-scm.com/book/zh-tw/v2/%E4%BD%BF%E7%94%A8-Git-%E5%88%86%E6%94%AF-%E7%B0%A1%E8%BF%B0%E5%88%86%E6%94%AF), |
Translations started for
| |
|---|
| [ĐДлаŃŃŃĐșаŃ](https://git-scm.com/book/be/v2/Git-Branching-Branches-in-a-Nutshell), |
| [Indonesian](https://git-scm.com/book/id/v2/Git-Branching-Branches-in-a-Nutshell), |
| [Italiano](https://git-scm.com/book/it/v2/Git-Branching-Branches-in-a-Nutshell), |
| [Bahasa Melayu](https://git-scm.com/book/ms/v2/Git-Branching-Branches-in-a-Nutshell), |
| [PortuguĂȘs (Portugal)](https://git-scm.com/book/pt-pt/v2/Ramifica%C3%A7%C3%A3o-do-Git-Branches-in-a-Nutshell). |
***
The source of this book is [hosted on GitHub.](https://github.com/progit/progit2)
Patches, suggestions and comments are welcome.
[Chapters âŸ](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)
1. ## 1\. [Getting Started](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control)
1. 1\.1 [About Version Control](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control)
2. 1\.2 [A Short History of Git](https://git-scm.com/book/en/v2/Getting-Started-A-Short-History-of-Git)
3. 1\.3 [What is Git?](https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F)
4. 1\.4 [The Command Line](https://git-scm.com/book/en/v2/Getting-Started-The-Command-Line)
5. 1\.5 [Installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
6. 1\.6 [First-Time Git Setup](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)
7. 1\.7 [Getting Help](https://git-scm.com/book/en/v2/Getting-Started-Getting-Help)
8. 1\.8 [Summary](https://git-scm.com/book/en/v2/Getting-Started-Summary)
2. ## 2\. [Git Basics](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository)
1. 2\.1 [Getting a Git Repository](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository)
2. 2\.2 [Recording Changes to the Repository](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository)
3. 2\.3 [Viewing the Commit History](https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History)
4. 2\.4 [Undoing Things](https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things)
5. 2\.5 [Working with Remotes](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes)
6. 2\.6 [Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging)
7. 2\.7 [Git Aliases](https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases)
8. 2\.8 [Summary](https://git-scm.com/book/en/v2/Git-Basics-Summary)
3. ## 3\. [Git Branching](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)
1. 3\.1 [Branches in a Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)
2. 3\.2 [Basic Branching and Merging](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)
3. 3\.3 [Branch Management](https://git-scm.com/book/en/v2/Git-Branching-Branch-Management)
4. 3\.4 [Branching Workflows](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows)
5. 3\.5 [Remote Branches](https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches)
6. 3\.6 [Rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)
7. 3\.7 [Summary](https://git-scm.com/book/en/v2/Git-Branching-Summary)
4. ## 4\. [Git on the Server](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols)
1. 4\.1 [The Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols)
2. 4\.2 [Getting Git on a Server](https://git-scm.com/book/en/v2/Git-on-the-Server-Getting-Git-on-a-Server)
3. 4\.3 [Generating Your SSH Public Key](https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key)
4. 4\.4 [Setting Up the Server](https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server)
5. 4\.5 [Git Daemon](https://git-scm.com/book/en/v2/Git-on-the-Server-Git-Daemon)
6. 4\.6 [Smart HTTP](https://git-scm.com/book/en/v2/Git-on-the-Server-Smart-HTTP)
7. 4\.7 [GitWeb](https://git-scm.com/book/en/v2/Git-on-the-Server-GitWeb)
8. 4\.8 [GitLab](https://git-scm.com/book/en/v2/Git-on-the-Server-GitLab)
9. 4\.9 [Third Party Hosted Options](https://git-scm.com/book/en/v2/Git-on-the-Server-Third-Party-Hosted-Options)
10. 4\.10 [Summary](https://git-scm.com/book/en/v2/Git-on-the-Server-Summary)
5. ## 5\. [Distributed Git](https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows)
1. 5\.1 [Distributed Workflows](https://git-scm.com/book/en/v2/Distributed-Git-Distributed-Workflows)
2. 5\.2 [Contributing to a Project](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project)
3. 5\.3 [Maintaining a Project](https://git-scm.com/book/en/v2/Distributed-Git-Maintaining-a-Project)
4. 5\.4 [Summary](https://git-scm.com/book/en/v2/Distributed-Git-Summary)
1. ## 6\. [GitHub](https://git-scm.com/book/en/v2/GitHub-Account-Setup-and-Configuration)
1. 6\.1 [Account Setup and Configuration](https://git-scm.com/book/en/v2/GitHub-Account-Setup-and-Configuration)
2. 6\.2 [Contributing to a Project](https://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project)
3. 6\.3 [Maintaining a Project](https://git-scm.com/book/en/v2/GitHub-Maintaining-a-Project)
4. 6\.4 [Managing an organization](https://git-scm.com/book/en/v2/GitHub-Managing-an-organization)
5. 6\.5 [Scripting GitHub](https://git-scm.com/book/en/v2/GitHub-Scripting-GitHub)
6. 6\.6 [Summary](https://git-scm.com/book/en/v2/GitHub-Summary)
2. ## 7\. [Git Tools](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection)
1. 7\.1 [Revision Selection](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection)
2. 7\.2 [Interactive Staging](https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging)
3. 7\.3 [Stashing and Cleaning](https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning)
4. 7\.4 [Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)
5. 7\.5 [Searching](https://git-scm.com/book/en/v2/Git-Tools-Searching)
6. 7\.6 [Rewriting History](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)
7. 7\.7 [Reset Demystified](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified)
8. 7\.8 [Advanced Merging](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging)
9. 7\.9 [Rerere](https://git-scm.com/book/en/v2/Git-Tools-Rerere)
10. 7\.10 [Debugging with Git](https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git)
11. 7\.11 [Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
12. 7\.12 [Bundling](https://git-scm.com/book/en/v2/Git-Tools-Bundling)
13. 7\.13 [Replace](https://git-scm.com/book/en/v2/Git-Tools-Replace)
14. 7\.14 [Credential Storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage)
15. 7\.15 [Summary](https://git-scm.com/book/en/v2/Git-Tools-Summary)
3. ## 8\. [Customizing Git](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)
1. 8\.1 [Git Configuration](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)
2. 8\.2 [Git Attributes](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes)
3. 8\.3 [Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)
4. 8\.4 [An Example Git-Enforced Policy](https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy)
5. 8\.5 [Summary](https://git-scm.com/book/en/v2/Customizing-Git-Summary)
4. ## 9\. [Git and Other Systems](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Git-as-a-Client)
1. 9\.1 [Git as a Client](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Git-as-a-Client)
2. 9\.2 [Migrating to Git](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git)
3. 9\.3 [Summary](https://git-scm.com/book/en/v2/Git-and-Other-Systems-Summary)
5. ## 10\. [Git Internals](https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain)
1. 10\.1 [Plumbing and Porcelain](https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain)
2. 10\.2 [Git Objects](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects)
3. 10\.3 [Git References](https://git-scm.com/book/en/v2/Git-Internals-Git-References)
4. 10\.4 [Packfiles](https://git-scm.com/book/en/v2/Git-Internals-Packfiles)
5. 10\.5 [The Refspec](https://git-scm.com/book/en/v2/Git-Internals-The-Refspec)
6. 10\.6 [Transfer Protocols](https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols)
7. 10\.7 [Maintenance and Data Recovery](https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery)
8. 10\.8 [Environment Variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables)
9. 10\.9 [Summary](https://git-scm.com/book/en/v2/Git-Internals-Summary)
1. ## A1. [Appendix A: Git in Other Environments](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Graphical-Interfaces)
1. A1.1 [Graphical Interfaces](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Graphical-Interfaces)
2. A1.2 [Git in Visual Studio](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Visual-Studio)
3. A1.3 [Git in Visual Studio Code](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Visual-Studio-Code)
4. A1.4 [Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-IntelliJ-/-PyCharm-/-WebStorm-/-PhpStorm-/-RubyMine)
5. A1.5 [Git in Sublime Text](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Sublime-Text)
6. A1.6 [Git in Bash](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Bash)
7. A1.7 [Git in Zsh](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-Zsh)
8. A1.8 [Git in PowerShell](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Git-in-PowerShell)
9. A1.9 [Summary](https://git-scm.com/book/en/v2/Appendix-A:-Git-in-Other-Environments-Summary)
2. ## A2. [Appendix B: Embedding Git in your Applications](https://git-scm.com/book/en/v2/Appendix-B:-Embedding-Git-in-your-Applications-Command-line-Git)
1. A2.1 [Command-line Git](https://git-scm.com/book/en/v2/Appendix-B:-Embedding-Git-in-your-Applications-Command-line-Git)
2. A2.2 [Libgit2](https://git-scm.com/book/en/v2/Appendix-B:-Embedding-Git-in-your-Applications-Libgit2)
3. A2.3 [JGit](https://git-scm.com/book/en/v2/Appendix-B:-Embedding-Git-in-your-Applications-JGit)
4. A2.4 [go-git](https://git-scm.com/book/en/v2/Appendix-B:-Embedding-Git-in-your-Applications-go-git)
5. A2.5 [Dulwich](https://git-scm.com/book/en/v2/Appendix-B:-Embedding-Git-in-your-Applications-Dulwich)
3. ## A3. [Appendix C: Git Commands](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Setup-and-Config)
1. A3.1 [Setup and Config](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Setup-and-Config)
2. A3.2 [Getting and Creating Projects](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Getting-and-Creating-Projects)
3. A3.3 [Basic Snapshotting](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Basic-Snapshotting)
4. A3.4 [Branching and Merging](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Branching-and-Merging)
5. A3.5 [Sharing and Updating Projects](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Sharing-and-Updating-Projects)
6. A3.6 [Inspection and Comparison](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Inspection-and-Comparison)
7. A3.7 [Debugging](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Debugging)
8. A3.8 [Patching](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Patching)
9. A3.9 [Email](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Email)
10. A3.10 [External Systems](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-External-Systems)
11. A3.11 [Administration](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Administration)
12. A3.12 [Plumbing Commands](https://git-scm.com/book/en/v2/Appendix-C:-Git-Commands-Plumbing-Commands)
2nd Edition
# 3\.1 Git Branching - Branches in a Nutshell
Nearly every VCS has some form of branching support. Branching means you diverge from the main line of development and continue to do work without messing with that main line. In many VCS tools, this is a somewhat expensive process, often requiring you to create a new copy of your source code directory, which can take a long time for large projects.
Some people refer to Gitâs branching model as its âkiller feature,â and it certainly sets Git apart in the VCS community. Why is it so special? The way Git branches is incredibly lightweight, making branching operations nearly instantaneous, and switching back and forth between branches generally just as fast. Unlike many other VCSs, Git encourages workflows that branch and merge often, even multiple times in a day. Understanding and mastering this feature gives you a powerful and unique tool and can entirely change the way that you develop.
## Branches in a Nutshell
To really understand the way Git does branching, we need to take a step back and examine how Git stores its data.
As you may remember from [What is Git?](https://git-scm.com/book/en/v2/ch00/what_is_git_section), Git doesnât store data as a series of changesets or differences, but instead as a series of *snapshots*.
When you make a commit, Git stores a commit object that contains a pointer to the snapshot of the content you staged. This object also contains the authorâs name and email address, the message that you typed, and pointers to the commit or commits that directly came before this commit (its parent or parents): zero parents for the initial commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches.
To visualize this, letâs assume that you have a directory containing three files, and you stage them all and commit. Staging the files computes a checksum for each one (the SHA-1 hash we mentioned in [What is Git?](https://git-scm.com/book/en/v2/ch00/what_is_git_section)), stores that version of the file in the Git repository (Git refers to them as *blobs*), and adds that checksum to the staging area:
```
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
```
When you create the commit by running `git commit`, Git checksums each subdirectory (in this case, just the root project directory) and stores them as a tree object in the Git repository. Git then creates a commit object that has the metadata and a pointer to the root project tree so it can re-create that snapshot when needed.
Your Git repository now contains five objects: three *blobs* (each representing the contents of one of the three files), one *tree* that lists the contents of the directory and specifies which file names are stored as which blobs, and one *commit* with the pointer to that root tree and all the commit metadata.

Figure 9. A commit and its tree
If you make some changes and commit again, the next commit stores a pointer to the commit that came immediately before it.

Figure 10. Commits and their parents
A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is `master`. As you start making commits, youâre given a `master` branch that points to the last commit you made. Every time you commit, the `master` branch pointer moves forward automatically.
| | |
|---|---|
| Note | The âmasterâ branch in Git is not a special branch. It is exactly like any other branch. The only reason nearly every repository has one is that the `git init` command creates it by default and most people donât bother to change it. |

Figure 11. A branch and its commit history
### Creating a New Branch
What happens when you create a new branch? Well, doing so creates a new pointer for you to move around. Letâs say you want to create a new branch called `testing`. You do this with the `git branch` command:
```
$ git branch testing
```
This creates a new pointer to the same commit youâre currently on.

Figure 12. Two branches pointing into the same series of commits
How does Git know what branch youâre currently on? It keeps a special pointer called `HEAD`. Note that this is a lot different than the concept of `HEAD` in other VCSs you may be used to, such as Subversion or CVS. In Git, this is a pointer to the local branch youâre currently on. In this case, youâre still on `master`. The `git branch` command only *created* a new branch â it didnât switch to that branch.

Figure 13. HEAD pointing to a branch
You can easily see this by running a simple `git log` command that shows you where the branch pointers are pointing. This option is called `--decorate`.
```
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
```
You can see the `master` and `testing` branches that are right there next to the `f30ab` commit.
### Switching Branches
To switch to an existing branch, you run the `git checkout` command. Letâs switch to the new `testing` branch:
```
$ git checkout testing
```
This moves `HEAD` to point to the `testing` branch.

Figure 14. HEAD points to the current branch
What is the significance of that? Well, letâs do another commit:
```
$ vim test.rb
$ git commit -a -m 'Make a change'
```

Figure 15. The HEAD branch moves forward when a commit is made
This is interesting, because now your `testing` branch has moved forward, but your `master` branch still points to the commit you were on when you ran `git checkout` to switch branches. Letâs switch back to the `master` branch:
```
$ git checkout master
```
| | |
|---|---|
| Note | `git log` doesnât show *all* the branches *all* the time If you were to run `git log` right now, you might wonder where the "testing" branch you just created went, as it would not appear in the output. The branch hasnât disappeared; Git just doesnât know that youâre interested in that branch and it is trying to show you what it thinks youâre interested in. In other words, by default, `git log` will only show commit history below the branch youâve checked out. To show commit history for the desired branch you have to explicitly specify it: `git log testing`. To show all of the branches, add `--all` to your `git log` command. |

Figure 16. HEAD moves when you checkout
That command did two things. It moved the HEAD pointer back to point to the `master` branch, and it reverted the files in your working directory back to the snapshot that `master` points to. This also means the changes you make from this point forward will diverge from an older version of the project. It essentially rewinds the work youâve done in your `testing` branch so you can go in a different direction.
| | |
|---|---|
| Note | Switching branches changes files in your working directory Itâs important to note that when you switch branches in Git, files in your working directory will change. If you switch to an older branch, your working directory will be reverted to look like it did the last time you committed on that branch. If Git cannot do it cleanly, it will not let you switch at all. |
Letâs make a few changes and commit again:
```
$ vim test.rb
$ git commit -a -m 'Make other changes'
```
Now your project history has diverged (see [Divergent history](https://git-scm.com/book/en/v2/ch00/divergent_history)). You created and switched to a branch, did some work on it, and then switched back to your main branch and did other work. Both of those changes are isolated in separate branches: you can switch back and forth between the branches and merge them together when youâre ready. And you did all that with simple `branch`, `checkout`, and `commit` commands.

Figure 17. Divergent history
You can also see this easily with the `git log` command. If you run `git log --oneline --decorate --graph --all` it will print out the history of your commits, showing where your branch pointers are and how your history has diverged.
```
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Make other changes
| * 87ab2 (testing) Make a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commit of my project
```
Because a branch in Git is actually a simple file that contains the 40 character SHA-1 checksum of the commit it points to, branches are cheap to create and destroy. Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline).
This is in sharp contrast to the way most older VCS tools branch, which involves copying all of the projectâs files into a second directory. This can take several seconds or even minutes, depending on the size of the project, whereas in Git the process is always instantaneous. Also, because weâre recording the parents when we commit, finding a proper merge base for merging is automatically done for us and is generally very easy to do. These features help encourage developers to create and use branches often.
Letâs see why you should do so.
| | |
|---|---|
| Note | Creating a new branch and switching to it at the same time Itâs typical to create a new branch and want to switch to that new branch at the same time â this can be done in one operation with `git checkout -b <newbranchname>`. |
| | |
|---|---|
| Note | From Git version 2.23 onwards you can use `git switch` instead of `git checkout` to: Switch to an existing branch: `git switch testing-branch`. Create a new branch and switch to it: `git switch -c new-branch`. The `-c` flag stands for create, you can also use the full flag: `--create`. Return to your previously checked out branch: `git switch -`. |
[prev](https://git-scm.com/book/en/v2/Git-Basics-Summary) \| [next](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)
[About this site](https://git-scm.com/site)
Patches, suggestions, and comments are welcome.
Git is a member of [Software Freedom Conservancy](https://git-scm.com/sfc) |
| Readable Markdown | Nearly every VCS has some form of branching support. Branching means you diverge from the main line of development and continue to do work without messing with that main line. In many VCS tools, this is a somewhat expensive process, often requiring you to create a new copy of your source code directory, which can take a long time for large projects.
Some people refer to Gitâs branching model as its âkiller feature,â and it certainly sets Git apart in the VCS community. Why is it so special? The way Git branches is incredibly lightweight, making branching operations nearly instantaneous, and switching back and forth between branches generally just as fast. Unlike many other VCSs, Git encourages workflows that branch and merge often, even multiple times in a day. Understanding and mastering this feature gives you a powerful and unique tool and can entirely change the way that you develop.
To really understand the way Git does branching, we need to take a step back and examine how Git stores its data.
As you may remember from [What is Git?](https://git-scm.com/book/en/v2/ch00/what_is_git_section), Git doesnât store data as a series of changesets or differences, but instead as a series of *snapshots*.
When you make a commit, Git stores a commit object that contains a pointer to the snapshot of the content you staged. This object also contains the authorâs name and email address, the message that you typed, and pointers to the commit or commits that directly came before this commit (its parent or parents): zero parents for the initial commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches.
To visualize this, letâs assume that you have a directory containing three files, and you stage them all and commit. Staging the files computes a checksum for each one (the SHA-1 hash we mentioned in [What is Git?](https://git-scm.com/book/en/v2/ch00/what_is_git_section)), stores that version of the file in the Git repository (Git refers to them as *blobs*), and adds that checksum to the staging area:
```
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
```
When you create the commit by running `git commit`, Git checksums each subdirectory (in this case, just the root project directory) and stores them as a tree object in the Git repository. Git then creates a commit object that has the metadata and a pointer to the root project tree so it can re-create that snapshot when needed.
Your Git repository now contains five objects: three *blobs* (each representing the contents of one of the three files), one *tree* that lists the contents of the directory and specifies which file names are stored as which blobs, and one *commit* with the pointer to that root tree and all the commit metadata.

Figure 9. A commit and its tree
If you make some changes and commit again, the next commit stores a pointer to the commit that came immediately before it.

Figure 10. Commits and their parents
A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is `master`. As you start making commits, youâre given a `master` branch that points to the last commit you made. Every time you commit, the `master` branch pointer moves forward automatically.
| | |
|---|---|
| Note | The âmasterâ branch in Git is not a special branch. It is exactly like any other branch. The only reason nearly every repository has one is that the `git init` command creates it by default and most people donât bother to change it. |

Figure 11. A branch and its commit history
### Creating a New Branch
What happens when you create a new branch? Well, doing so creates a new pointer for you to move around. Letâs say you want to create a new branch called `testing`. You do this with the `git branch` command:
```
$ git branch testing
```
This creates a new pointer to the same commit youâre currently on.

Figure 12. Two branches pointing into the same series of commits
How does Git know what branch youâre currently on? It keeps a special pointer called `HEAD`. Note that this is a lot different than the concept of `HEAD` in other VCSs you may be used to, such as Subversion or CVS. In Git, this is a pointer to the local branch youâre currently on. In this case, youâre still on `master`. The `git branch` command only *created* a new branch â it didnât switch to that branch.

Figure 13. HEAD pointing to a branch
You can easily see this by running a simple `git log` command that shows you where the branch pointers are pointing. This option is called `--decorate`.
```
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
```
You can see the `master` and `testing` branches that are right there next to the `f30ab` commit.
### Switching Branches
To switch to an existing branch, you run the `git checkout` command. Letâs switch to the new `testing` branch:
```
$ git checkout testing
```
This moves `HEAD` to point to the `testing` branch.

Figure 14. HEAD points to the current branch
What is the significance of that? Well, letâs do another commit:
```
$ vim test.rb
$ git commit -a -m 'Make a change'
```

Figure 15. The HEAD branch moves forward when a commit is made
This is interesting, because now your `testing` branch has moved forward, but your `master` branch still points to the commit you were on when you ran `git checkout` to switch branches. Letâs switch back to the `master` branch:
```
$ git checkout master
```
| | |
|---|---|
| Note | `git log` doesnât show *all* the branches *all* the time If you were to run `git log` right now, you might wonder where the "testing" branch you just created went, as it would not appear in the output. The branch hasnât disappeared; Git just doesnât know that youâre interested in that branch and it is trying to show you what it thinks youâre interested in. In other words, by default, `git log` will only show commit history below the branch youâve checked out. To show commit history for the desired branch you have to explicitly specify it: `git log testing`. To show all of the branches, add `--all` to your `git log` command. |

Figure 16. HEAD moves when you checkout
That command did two things. It moved the HEAD pointer back to point to the `master` branch, and it reverted the files in your working directory back to the snapshot that `master` points to. This also means the changes you make from this point forward will diverge from an older version of the project. It essentially rewinds the work youâve done in your `testing` branch so you can go in a different direction.
| | |
|---|---|
| Note | Switching branches changes files in your working directory Itâs important to note that when you switch branches in Git, files in your working directory will change. If you switch to an older branch, your working directory will be reverted to look like it did the last time you committed on that branch. If Git cannot do it cleanly, it will not let you switch at all. |
Letâs make a few changes and commit again:
```
$ vim test.rb
$ git commit -a -m 'Make other changes'
```
Now your project history has diverged (see [Divergent history](https://git-scm.com/book/en/v2/ch00/divergent_history)). You created and switched to a branch, did some work on it, and then switched back to your main branch and did other work. Both of those changes are isolated in separate branches: you can switch back and forth between the branches and merge them together when youâre ready. And you did all that with simple `branch`, `checkout`, and `commit` commands.

Figure 17. Divergent history
You can also see this easily with the `git log` command. If you run `git log --oneline --decorate --graph --all` it will print out the history of your commits, showing where your branch pointers are and how your history has diverged.
```
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Make other changes
| * 87ab2 (testing) Make a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commit of my project
```
Because a branch in Git is actually a simple file that contains the 40 character SHA-1 checksum of the commit it points to, branches are cheap to create and destroy. Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline).
This is in sharp contrast to the way most older VCS tools branch, which involves copying all of the projectâs files into a second directory. This can take several seconds or even minutes, depending on the size of the project, whereas in Git the process is always instantaneous. Also, because weâre recording the parents when we commit, finding a proper merge base for merging is automatically done for us and is generally very easy to do. These features help encourage developers to create and use branches often.
Letâs see why you should do so.
| | |
|---|---|
| Note | Creating a new branch and switching to it at the same time Itâs typical to create a new branch and want to switch to that new branch at the same time â this can be done in one operation with `git checkout -b <newbranchname>`. |
| | |
|---|---|
| Note | From Git version 2.23 onwards you can use `git switch` instead of `git checkout` to: Switch to an existing branch: `git switch testing-branch`. Create a new branch and switch to it: `git switch -c new-branch`. The `-c` flag stands for create, you can also use the full flag: `--create`. Return to your previously checked out branch: `git switch -`. | |
| Shard | 54 (laksa) |
| Root Hash | 7104038400628677254 |
| Unparsed URL | com,git-scm!/book/en/v2/Git-Branching-Branches-in-a-Nutshell s443 |