Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The meaning of tracking in git

Tags:

git

In an article that has been cited in StackOverflow a few times (e.g. 1) , the author discusses the asymmetry between git push and git pull, and mentions the following:

Update: Thanks to David Ongaro, who points out below that since git 1.7.4.2, the recommended value for the push.default option is upstream rather than tracking, although tracking can still be used as a deprecated synonym. The commit message that describes that change is nice, since it suggests that there is an effort underway to deprecate the term “track” in the context of setting this association with the upstream branch in a remote repository. (The totally different meanings of “track” in git branch --track and “remote-tracking branches” has long irritated me when trying to introduce git to people.)

What is exactly the difference that he is referring to with:

  • The notion of "tracking" in git branch --track
  • The notion of "tracking" in remote-tracking branches

in the last sentence?

like image 619
Amelio Vazquez-Reina Avatar asked Oct 02 '12 21:10

Amelio Vazquez-Reina


People also ask

How does git keep track of branches?

Git stores all references under the . git/refs folder and branches are stored in the directory . git/refs/heads. Since branch is a simple text file we can just create a file with the contents of a commit hash.

What does git checkout -- track do?

We will use the Git Checkout command with the --track option to create a new local branch based on the remote-tracking branch that we fetched. This local branch will have the same name and the commit history as the remote branch. We can view these commits and even add new ones.

What is upstream tracking git?

--set-upstream is used to map a branch in your local to a branch on remote so that you can just do git push or git pull and it will know which branch to push/pull from. For adding a remote repo I use these commands. First, check your remote repositories with git remote -v.


1 Answers

I can't be sure, because I am not the author of that sentence. I'll take a shot that the confusion the author is describing is the common confusion between "tracking" and "remote tracking" branches. gitguys has a great article on this, so really, you should just read that. They have nice pictures and everything.

Here's my take on it...

The Setting

As an example, let's assume we have a very simple git repository on github that has a single master branch with a few commits (C1 and C2, where C2 is the current commit). When you clone that repository...

git clone [email protected]:example/repo.git

...two things happen:

  1. You copy all of the commits (C1 and C2) to your local computer.
  2. You also create a new branch on your local computer called master. This branch is a "tracking branch", and its HEAD is on C2. This branch is referred to as the "tracking branch".

A New Commit

So far, nothing special. But in the time you read these explanations, someone committed another commit (C3) and push it to the remote repository. Now imagine you hear about this new amazing commit, and decide to retrieve it yourself.

git fetch

This does two things:

  1. Copies the new commits that are needed (C3) to your local computer.
  2. Updates the local system somehow to let them know that origin's master branch is on now on C3.

But here's the question: how does the local system know that the origin's master branch is on C3? Surely git has some way of storing that information locally? But where? We can't actually make a change to the local master branch since we might have our own commits or other changes on that local branch that we need to merge. Is it just stored in some other, unknown blob?

The Answer

It turns out, git just uses a third branch. Right now, we knew about two branches:

  1. The branch physically located on github.
  2. The "tracking branch", located on your computer (what you would call master).

It turns out there is a third. You've probably seen it before: it's called origin/master. And it's not the same as either of these two branches. It is what is known as a "remote-tracking branch".

You can think of it as the branch that sits between your local master branch and the origin's master branch. It is an actual git branch on your computer (just like master) and as such you can play with it similarly to how you can jump around your other branches. However, there there are limitations.

For example, you can check it out...

git checkout origin/master

However, you'd get a funny looking message...

Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 12dbe6a... My awesome commit!

This message is displayed is because "remote tracking branches" are READ-ONLY. The user cannot manipulate them like they can master, only the git system itself is allowed to make changes to it (which it will do during fetches). As such, from an implementation standpoint, you can think of them as just any other branch. However, because of their read-only nature, you don't typically use them like any other branch.

So, really, we have three branches in the mix:

  1. The branch physically located on github.
  2. The origin/master branch physically located on your machine ("remote tracking branch").
  3. The master branch physically located on your machine ("tracking branch").

To Answer The Question...

Therefore, my assumption is that really the confusion could lie between "tracking" and "remote tracking" branches. It would make sense that someone would confuse master as a "remote tracking branch" (after all, it does get commits from origin/master!), but in reality, it is not. It is a "tracking branch", and the branch it tracks is origin/master. origin/master is the "remote tracking branch".

When someone talks about "tracking" in terms of git branch --track, they are talking about the "tracking" branch that you can modify.

When someone talks about "remote-tracking branches", they are talking about the read-only branch that tracks a remote's branch.

like image 103
Mark Hildreth Avatar answered Nov 02 '22 08:11

Mark Hildreth