TL;DR Remember, all git branches are themselves used for tracking the history of a set of files. Therefore, isn't every branch actually a "tracking branch", because that's what these branches are used for: to track the history of files over time?
Thus we should probably be calling normal git "branches", "tracking-branches", but we don't. Instead we shorten their name to just "branches".
So that's partly why the term "tracking-branches" is so terribly confusing: to the uninitiated it can easily mean 2 different things.
In git the term "Tracking-branch" is a short name for the more complete term: "Remote-tracking-branch".
It's probably better at first if you substitute the more formal terms until you get more comfortable with these concepts.
Let's rephrase your question to this:
What is a "Remote-tracking-branch?"
The key word here is 'Remote', so skip down to where you get confused and I'll describe what a Remote Tracking branch is and how it's used.
To better understand git terminology, including branches and tracking, which can initially be very confusing, I think it's easiest if you first get crystal clear on what git is and the basic structure of how it works. Without a solid understand like this I promise you'll get lost in the many details, as git has lots of complexity; (translation: lots of people use it for very important things).
The following is an introduction/overview, but you might find this excellent article also informative.
WHAT GIT IS, AND WHAT IT'S FOR
A git repository is like a family photo album: It holds historical snapshots showing how things were in past times. A "snapshot" being a recording of something, at a given moment in time.
A git repository is not limited to holding human family photos. It, rather can be used to record and organize anything that is evolving or changing over time.
The basic idea is to create a book so we can easily look backwards in time,
- to compare past times, with now, or other moments in time, and
- to re-create the past.
When you get mired down in the complexity and terminology, try to remember that a git repository is first and foremost, a repository of snapshots, and just like a photo album, it's used to both store and organize these snapshots.
SNAPSHOTS AND TRACKING
tracked - to follow a person or animal by looking for proof that they have been somewhere (dictionary.cambridge.org)
In git, "your project" refers to a directory tree of files (one or more, possibly organized into a tree structure using sub-directories), which you wish to keep a history of.
Git, via a 3 step process, records a "snapshot" of your project's directory tree at a given moment in time.
Each git snapshot of your project, is then organized by "links" pointing to previous snapshots of your project.
One by one, link-by-link, we can look backwards in time to find any previous snapshot of you, or your heritage.
For example, we can start with today's most recent snapshot of you, and then using a link, seek backwards in time, for a photo of you taken perhaps yesterday or last week, or when you were a baby, or even who your mother was, etc.
This is refereed to as "tracking; in this example it is tracking your life, or seeing where you have left a footprint, and where you have come from.
COMMITS
A commit is similar to one page in your photo album with a single snapshot, in that its not just the snapshot contained there, but also has the associated meta information about that snapshot. It includes:
- an address or fixed place where we can find this commit, similar to its page number,
- one snapshot of your project (of your file directory tree) at a given moment in time,
- a caption or comment saying what the snapshot is of, or for,
- the date and time of that snapshot,
- who took the snapshot, and finally,
- one, or more, links backwards in time to previous, related snapshots like to yesterday's snapshot, or to our parent or parents. In other words "links" are similar to pointers to the page numbers of other, older photos of myself, or when I am born to my immediate parents.
A commit is the most important part of a well organized photo album.
THE FAMILY TREE OVER TIME, WITH BRANCHES AND MERGES
Disambiguation: "Tree" here refers not to a file directory tree, as used above, but rather to a family tree of related parent and child commits over time.
The git family tree structure is modeled on our own, human family trees.
In what follows to help understand links in a simple way, I'll refer to:
- a parent-commit as simply a "parent", and
- a child-commit as simply a "child" or "children" if plural.
You should understand this instinctively, as it is based on the tree of life:
- A parent might have one or more children pointing back in time at them, and
- children always have one or more parents they point to.
Thus all commits except brand new commits, (you could say "juvenile commits"), have one or more children pointing back at them.
With no children are pointing to a parent, then this commit is only a "growing tip", or where the next child will be born from.
With just one child pointing at a parent, this is just a simple, single parent <-- child relationship.
Line diagram of a simple, single parent chain linking backwards in time:
(older) ... <--link1-- Commit1 <--link2-- Commit2 <--link3-- Commit3 (newest)
BRANCHES
branch - A "branch" is an active line of development. The most recent commit on a branch is referred to as the tip of that branch.
The tip of the branch is referenced by a branch head, which moves
forward as additional development is done on the branch. A single Git
repository can track an arbitrary number of branches, but your
working tree is associated with just one of them (the "current" or
"checked out" branch), and HEAD points to that branch. (gitglossary)
A git branch also refers to two things:
- a name given to a growing tip, (an identifier), and
- the actual branch in the graph of links between commits.
More than one child pointing --at a--> parent, is what git calls "branching".
NOTE: In reality any child, of any parent, weather first, second, or third, etc., can be seen as their own little branch, with their own growing tip. So a branch is not necessarily a long thing with many nodes, rather it is a little thing, created with just one or more commits from a given parent.
The first child of a parent might be said to be part of that same branch, whereas the successive children of that parent are what are normally called "branches".
In actuality, all children (not just the first) branch from it's parent, or you could say link, but I would argue that each link is actually the core part of a branch.
Formally, a git "branch" is just a name, like 'foo' for example, given to a specific growing tip of a family hierarchy. It's one type of what they call a "ref". (Tags and remotes which I'll explain later are also refs.)
ref - A name that begins with refs/ (e.g. refs/heads/master) that points to an object name or another ref (the latter is called a
symbolic ref). For convenience, a ref can sometimes be abbreviated
when used as an argument to a Git command; see gitrevisions(7) for
details. Refs are stored in the repository.
The ref namespace is hierarchical. Different subhierarchies are used
for different purposes (e.g. the refs/heads/ hierarchy is used to
represent local branches). There are a few special-purpose refs that
do not begin with refs/. The most notable example is HEAD. (gitglossary)
(You should take a look at the file tree inside your .git
directory. It's where the structure of git is saved.)
So for example, if your name is Tom, then commits linked together that only include snapshots of you, might be the branch we name "Tom".
So while you might think of a tree branch as all of it's wood, in git a branch is just a name given to it's growing tips, not to the whole stick of wood leading up to it.
The special growing tip and it's branch which an arborist (a guy who prunes fruit trees) would call the "central leader" is what git calls "master".
The master branch always exists.
Line diagram of: Commit1 with 2 children (or what we call a git "branch"):
parent children
+-- Commit <-- Commit <-- Commit (Branch named 'Tom')
/
v
(older) ... <-- Commit1 <-- Commit (Branch named 'master')
Remember, a link only points from child to parent.
There is no link pointing the other way, i.e. from old to new, that is from parent to child.
So a parent-commit has no direct way to list it's children-commits, or in other words, what was derived from it.
MERGING
Children have one or more parents.
With just one parent this is just a simple parent <-- child commit.
With more than one parent this is what git calls "merging".
Each child can point back to more than one parent at the same time, just as in having both a mother AND father, not just a mother.
Line diagram of: Commit2 with 2 parents (or what we call a git "merge", i.e. Procreation from multiple parents):
parents child
... <-- Commit
v
\
(older) ... <-- Commit1 <-- Commit2
REMOTE
This word is also used to mean 2 different things:
- a remote repository, and
- the local alias name for a remote repository, i.e. a name which points using a URL to a remote repository.
remote repository - A repository which is used to track the same project but resides somewhere else. To communicate with remotes, see
fetch or push. (gitglossary)
(The remote repository can even be another git repository on our own computer.)
Actually there are two URLS for each remote name, one for pushing (i.e. uploading commits) and one for pulling (i.e. downloading commits) from that remote git repository.
A "remote" is a name (an identifier) which has an associated URL which points to a remote git repository. (It's been described as an alias for a URL, although it's more than that.)
You can setup multiple remotes if you want to pull or push to multiple remote repositories.
Though often you have just one, and it's default name is "origin" (meaning the upstream origin from where you cloned).
origin - The default upstream repository. Most projects have at least one upstream project which they track. By default origin is used
for that purpose. New upstream updates will be fetched into
remote-tracking branches named origin/name-of-upstream-branch, which you can see using git branch -r. (gitglossary)
Origin represents where you cloned the repository from.
That remote repository is called the "upstream" repository, and your cloned repository is called the "downstream" repository.
upstream - In software development, upstream refers to a direction toward the original authors or maintainers of software that is distributed as source code wikipedia
upstream branch - The default branch that is merged into the branch in question (or the branch in question is rebased onto).
It is configured via branch..remote and branch..merge. If the upstream branch of A is origin/B sometimes we say "A is tracking origin/B". (gitglossary)
This is because most of the water generally flows down to you.
From time to time you might push some software back up to the upstream repository, so it can then flow down to all who have cloned it.
REMOTE TRACKING BRANCH
A remote-tracking-branch is first, just a branch name, like any other branch name.
It points at a local growing tip, i.e. a recent commit in your local git repository.
But note that it effectively also points to the same commit in the remote repository that you cloned the commit from.
remote-tracking branch - A ref that is used to follow changes from another repository. It typically looks like refs/remotes/foo/bar
(indicating that it tracks a branch named bar in a remote named foo),
and matches the right-hand-side of a configured fetch refspec. A remote-tracking branch should not contain direct modifications or have
local commits made to it. (gitglossary)
Say the remote you cloned just has 2 commits, like this: parent4 <== child-of-4
, and you clone it and now your local git repository has the same exact two commits: parent4 <== child-of-4
.
Your remote tracking branch named origin now points to child-of-4
.
Now say that a commit is added to the remote, so it looks like this: parent4 <== child-of-4 <== new-baby
. To update your local, downstream repository you'll need to fetch new-baby, and add it to your local git repository. Now your local remote-tracking-branch points to new-baby. You get the idea, the concept of a remote-tracking-branch is simply to keep track of what had previously been the tip of a remote branch that you care about.
TRACKING IN ACTION
First we begin tracking a file with git.

Here are the basic commands involved with file tracking:
$ mkdir mydir && cd mydir && git init # create a new git repository
$ git branch # this initially reports no branches
# (IMHO this is a bug!)
$ git status -bs # -b = branch; -s = short # master branch is empty
## No commits yet on master
# ...
$ touch foo # create a new file
$ vim foo # modify it (OPTIONAL)
$ git add foo; commit -m 'your description' # start tracking foo
$ git rm --index foo; commit -m 'your description' # stop tracking foo
$ git rm foo; commit -m 'your description' # stop tracking foo
# & also delete foo
REMOTE TRACKING IN ACTION
$ git pull # Essentially does: get fetch; git merge # to update our clone
There is much more to learn about fetch, merge, etc, but this should get you off in the right direction I hope.