3

I type

git checkout staging

and a local branch staging is created, and in command prompt, it said

Branch 'staging' set up to track remote branch 'staging' from 'origin'.

but I feel some ambiguous about the term remote branch 'staging' from 'origin'....in fact the so-called remote branch is also in my local repository, just it track the remote git server branch name 'staging'? then that branch should call "track remote branch 'staging' from 'origin', not my just checkouted branch?

in git, when said remote branch, it usually mean remote tracking branch in local repository, not the branch really reside in remote (another location) git server?

then how to call (how to describle) the branch really in remote (another location) git server?

enter image description here

user1169587
  • 1,104
  • 2
  • 17
  • 34
  • A remote branch only refers to a branch in a remote repository. A remote *tracking* branch is the branch in your local repository that tracks the remote branch. – Erwin Bolwidt Jan 16 '21 at 11:35

3 Answers3

4

Git's own documentation and terminology usage is not entirely consistent here. It does, however, all make sense once you understand each of the pieces that Git is using.

First, there is the remote, which is a short name like origin.1 This name provides a couple of items, the most important of which is a URL. This URL lets your Git (your Git software operating on your Git repository) contact some other Git (the same or different version of the Git software, operating on some other Git repository).

Next, there are branch names like master or main and any other names you create. Each one of these names also provides a couple of items, the most important of which is to give you the hash ID of some particular commit. The commit hash ID found in a branch name is, by definition, the last commit in some chain of commits. Being "last" makes it your most recent, usually; Git calls this commit the tip commit of the branch.

Since your Git talks to some other Git, that other Git—the "remote Git", or whatever phrase you'd like to use—has its own branch names. When your Git calls up that Git, your Git can see their branch names. The logical term for the branch names on some remote is a remote branch. Sometimes, that's what people who say "remote branch" mean.

But after your Git gets in touch with that Git and brings over any of their commits they have that you don't yet (so now you have them), your Git will create, in your repository, some similar names. If they have a branch named main, and your Git calls their Git origin, your Git will create origin/main. If they have a branch named develop, your Git will create origin/develop.2

I call these origin/* style names remote-tracking names. Parts of Git call them remote-tracking branch names. Other parts of Git, and other people, sometimes call them remote branches.

Obviously, then, the term remote branches is ambiguous. Sometimes it means a branch name as seen on the remote, and sometimes it means a remote-tracking name as seen in your own repository. By using the phrase branch name as seen on the remote named _____ (fill in the blank), you can be clear about what you mean here, for instance.

It turns out the term branch is ambiguous, too: see What exactly do we mean by "branch"? I try to use the phrase branch name to be more specific whenever necessary.


1Since you control the name, you can use a really long name here. That would be counterproductive, so I'll just assume you use a short one. :-)

2This is really create or update, and you can instruct your Git not to bother with all of their branch names—but this is the default. Note that there's a minor flaw here by default: if they delete one of their branch names after your own Git has copied their name to your remote-tracking name, your Git won't delete your remote-tracking name. So over time, your Git will build up "stale" remote-tracking names.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I think a lot of the inconsistencies come from "leaky abstractions": _logically_, the pointers managed by `git fetch` and the pointers managed by `git commit` are different things, but they're both _implemented_ the same way, so they end up being sort-of interchangeable. – IMSoP Jan 16 '21 at 12:28
3

It is true that git is not known for being precisely consistent in terminology.

However, in this case the perceived ambiguity comes from conflating what git is doing with how git is doing it.

The ref you have locally called origin/staging is not the remote branch. It is not a branch at all. It is a separate thing; it is a remote tracking ref (sometimes called a "remote tracking branch", which is unfortunate and confusing). It is a tool your local repo uses to track the remote branch.

And git does not mean that it's setting the new local branch up to track this remote tracking ref. It means that it's setting the new local branch up to track the remote branch (the actual branch that lives in the actual other repo), and it just so happens that it does that using the remote tracking ref origin/staging that exists locally (because it has to use local things, and of all the local things the remote tracking ref is what most accurately tells us where the remote branch is).

That means the tracking of the remote branch is only as accurate as your most recent fetch, but that's really all it means. A hunter doesn't track an animal's footprints, and you wouldn't say it's ambiguous when a hunter tells you he's tracking the animal.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
1

I think the way to think of this is that when you run git fetch , the contents of some remote repository are cached for future use, but git doesn't think of the fetched branches as "belonging" to your repository. The "real" remote branches are still "out there" on whatever URL the remote has configured.

Similarly, when you tell git to "track" a remote branch, it records it as tracking a branch that exists in some other place that it knows the URL for. The main operations that use that association are git pull and git push, both of which actively talk to the remote repository, not just your local cache.

Some commands just use the local cache of the remote repository, e.g. you can run git log origin/foo or git merge origin/foo and they won't fetch any new data. But that aren't "remote-tracking" branches, they're just caches that might be out of date.

The final piece of the puzzle is that git checkout has some convenience functionality that lets you, in one command:

  • Check out a remote branch, based on your current cache of it
  • Create a local branch with the same name
  • Set the "tracking" information to point to the remote branch, by name, so it doesn't matter if your cache is out of date or not
IMSoP
  • 89,526
  • 13
  • 117
  • 169