I am trying to dig through man-pages and user manual and trying to
match them with reality. I seem to have a hard time. My current
understanding (which definitely differs from the documented state) is
that there are two types of branches, local and remote branches, and
both types of branches can be remote-tracking (it may not be possible
to have a non-remote-tracking remote branch, though).A local branch is one with a local branch head. In contrast, checking
out a remote branch, while possible, leaves one with a detached head."remote-tracking" basically means that git-pull will update the branch
according to changes in the remote repository.Creating a branch using git-branch or git-checkout will always create
a local branch which may or may not be remote-tracking according to
the --no-track or --track options.So there are basically three types of branches in a repository that I
can see:local branch, not remote-tracking
local branch, remote-tracking
remote branch, remote-trackingThe way to add a remote branch basically is not via git-branch or
git-checkout -b (those always create local branches), but by editing
.git/config.Is this understanding correct or did I get things completely wrong?
Because there is little sense in myself working on changing the
documentation if I have not understood the situation.Also, the documentation currently uses "remote-tracking"
interchangeably for "local branch, remote-tracking" and "remote
branch, remote-tracking", at some times claiming that one can locally
switch to a "remote-tracking" branch, at other times not.So the terminology seems fuzzy at the moment, and my attempt to clear
it up might not be the preferred way of doing it.Thanks,
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
I think we have a brief discussion on #git before you brought
this up ;-)- local branches -- we know what they are.
- remote tracking branches -- refs that appear in refs/remotes/
in the current world order; they are updated only by copying
the corresponding local branches at the remote site, and are
meant to "keep track of what _they_ are doing". In olden
days before 1.5.0 with non separate remote layout,
'refs/heads/origin' branch, and all the non default branches,
were treated this way as well. You were not supposed to make
commit on them (because of the above "keep track of" reason),
and having them under refs/heads were too confusing, which
was the reason the separate remote layout was invented.You can have a local branch that is created by forking off of a
remote tracking branch, with the intention to "build on top" of
the corresponding remote tracking brach. You can create such a
branch and mark it as such with --track option introduced in
v1.5.1 timeperiod. This is a relatively new concept, but many
people find it useful. We do not have the official term to call
this concept, and some people have misused the term "remote
tracking branches" to describe this, which made things very
confusing.We would need an official terminology for it.
-
Following was mentioned earlier in this thread ... could we use that?
tracking branch:
ref always points at a commit from the remote repo branchfollowing branch:
ref either points at a commit from the remote repo branch, or a
local commit with a commit from the remote repo branch in the historyperhaps?
--
Julian---
An optimist is a man who looks forward to marriage.
A pessimist is a married optimist.
-
An auto-merging branch? The term is somewhat more technical so that
people are less likely to think it just a colloquial alternative
expression for "tracking".--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
Personally I don't like auto-merging as it doesn't have any connotations
of _what_ is auto-merged ... and it's not really an automatic merge
anyway, you have to ask for it (by running pull).--
Julian---
Don't look back, the lemmings are gaining on you.
-
The current user manual defines this case in the glossary as
'tracking branch' (without remote), but mostly uses
'remote-tracking branch' at other places. Tracking branch
and remote-tracking branch seem to be equivalent. And I thinkSomething like 'automerging branch', and replace options with
'--automerge/--no-automerge'?I'm not fully convinced of this idea because it may be
technically correct but doesn't really reflect the intention of
'building on top' of the remote tracking branch.Steffen
-
On Sat, 04 Aug 2007 12:55:43 +0200
To be clear, it's the job of git-fetch to update remote-tracking branches
with any changes found in the remote repository. Git-pull runs git-fetch
and then runs a git-merge to update the currently-checked-out branch.When this happens, git-merge must decide which remote-tracking-branch
to merge into the currently checked out local branch. You can set which
remote-tracking-branch will be selected in this situation with
the --track option.So assuming a remote-repo has two branches "master" and "branchX":
git clone remote-repo
will give us two remote-branch (AKA remote-tracking-branches) of
"origin/master" and "origin/branchX". So:git branch --track mylocalbranch origin/branchX
git checkout mylocalbranchCreates a local branch named "mylocalbranch" that by default will
merge in any changes found in the remote-tracking branch
"origin/branchX". Thus:git pull
First runs git fetch which will update all remote-tracking branches
such as origin/master and origin/branchX. Then it runs git merge.
Git merge has to decide whether to merge in the changes from
origin/master or origin/branchX. Because of the --track option usedNo, a local branch is never a remote-tracking branch; even when created
with a --track option. The --track option has muddied the terminology
waters a bit and you're not the first to be confused by it. TheFunctionally, your understanding is correct. But it helps when you
understand that remote-branches are the "real" remote-tracking-branches.
You don't commit to them locally, they are essentially read-only copies
of exactly what is happening in a remote repository.A local --track branch, is one that merges changes from the proper
remote-tracking-branch, and is also a place where you can commit yourA remote branch and a remote-tracking branch are the same thing.
Strictly speaking a local branch is never a remote-tracking-branchYeah, the documentation could use some fine tuning.
Se...
So --track does not set up a tracking branch, but makes a local
_following_ branch _refer_ to a tracking branch.What happens with
git checkout origin/branchX
git branch --track mylocalbranch
git checkout mylocalbranch? What if after the checkout (which leads to a detached head) I check
in a few things, and then decide to name the branch and set it up as
following a remote tracking branch? Instead of using git-branch for
setting up the following, do I have to explicitly add the respective
"remote" line (which does not specify a remote, but a remote trackingWell, GOOD. I have already come to the conclusion that the "--track"
option, like the "remote" configuration recorded by it have the main
purpose of confusing people and should not be confused with setting upIt is much too fine-tuned already. I think that first option names
and config file options need to get some coarse-tuning where one does
not have to split hairs and ignore the meaning of terms in order to
understand them.I have now "following" or "automerge" local branches which are set up
to follow a "remote tracking" branch. Presumably, if I dogit-branch -b new-branch --track remote-branch
then I get a following branch set up which follows/automerges a remote
tracking branch. So far so good. What do I get withgit-branch -b another-new-branch --track new-branch
Does this follow/automerges with new-branch? Does this
follow/automerge with remote-branch?What if I do
git-checkout remote-branch
git-branch -b new-branch --trackDoes this follow anything?
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
A minor nit, but --track sets up a local following branch to refer to a
remote's branch, _not_ to the tracking branch. In other words, if you
look at the config:[branch "master"]
remote = origin
merge = refs/heads/masterIt does _not_ reference the tracking branch
"refs/remotes/origin/master", but rather the remote's name for the
branch "refs/heads/master".There was much discussion of this topic, but the general idea was not to
require remote tracking branches for this feature to be used (a position
I somewhat disagree with, but then I'm not the maintainer).-Peff
-
Interesting. I didn't even recognize this detail up to know. It was
somewhat
beyond my imagination that I could have a local following/automerging
branch that is directly referring to a branch in a remote repo, without
have a remote-tracking branch.How could I create such a setup in the first place?
git branch --track something origin/something
git checkout --track -b something origin/somethingare obvious, but what to say if I don't have origin/something?
Steffen
-
I believe the --track setup uses the tracking branches to figure out
which remote/branch combo to track. To do it without a remote tracking
branch, you would have to add the lines to your .git/config manually.-Peff
-
On Sat, 04 Aug 2007 16:01:55 +0200
Sure, that's one way to describe it; perhaps it would be best if
This is easy to test, and the answer is that no tracking is set up.
You must supply the remote-tracking-branch on the command line with
the --track option to git branch. Actually I realized that with aIt's not a problem, you could just add an appropriate [branch...] section
in your .git/config. Actually looking at a typical branch section
is even more confusing to me:$ git branch fudge origin/fix1
adds this to the .git/config:
[branch "fudge"]
remote = origin
merge = refs/heads/fix1The config file does not record the remote-tracking-branch, instead
it explicitly records the remote repository information. So it sure
appears that if you add the --track option, it _does_ make the local
branch track a remote directly. Thus it's hard to call it anything
but what you labelled it, a local tracking-branch.While I thought i had a handle on this, i'm now officially more
confused than you; hopefully someone with knowledge of the guts
of Git will speak up. Junio Help!Sean
-
There is some discussion in this thread:
http://thread.gmane.org/gmane.comp.version-control.git/35090/focus=35265
-Peff
-
Not according to my current understanding, but that can, of course,
change again in the next few hours. As far as I understand right now,
such a branch indeed tracks a remote branch (and not a remote tracking
branch), it just does not track it recklessly: it has a head of itsYes, it seems --track does track after all. Just more cautiously than
Good. It means that I may not be a complete idiot. It may also mean
that the documentation can be improved in places. With a lot of
"grep" and fine-combing I realized that quite a bit of the information
_is_ "available" (and some conflicting information as well).This is one reason why I would prefer to have something like a typical
Texinfo manual, at least on the organisational level: a manual is
supposed to present a single connected view to the available
documentation. And the information for git is scattered through a
bunch of mostly disconnected files.If you want to see a more staggering example of this approach, take a
look at the "guilt" documentation. It consists only of the man pages
for the individual commands, and then some few README-like files which
mostly say something like "guilt is just like quilt, or like
Mercurial's patch sets". That's rather extreme as far as
user-accessible information goes. git has a few more generally useful
files explaining underlying concepts, but they still are basicallyI think I am slowly getting it, thanks to Lars and others.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
A "remote tracking branch" is a branch in refs/remotes/* that is updated
by _git-fetch_ (which is in turn called by git-pull) to track a remote's
position of a branch.A local branch which tracks a remote branch (I don't recall seeing the
phrase "remote-tracking" -- where did this come from?) has the correct
magic in .git/config to pull from a specific remote branch whenYes, although again, I think calling it a "remote-tracking branch" to
mean "a local branch that tracks a remote branch" is confusingly similar
to the more common "remote tracking branch" to mean "a branch inNo, the remote branch is not remote-tracking in the sense that you
defined above; it is not meant to be pulled into.I think you are confused by two uses of the word "track". In one case,
we mean that git-fetch will remember the remote's idea of a branch in
refs/remotes/<remote>/<branch>. In another, we mean that a local branchYes, it is very fuzzy. Using "track" for the concept of a local branch
defaulting to a particular (remote,branch) pair for git-pull is, I
think, more recent and less used. If there were another term for this,
it might be more clear.-Peff
-
Jeff, I actually have no _clue_ what I "mean" with respect to the
established git terminology because I can't reconcile the
documentation's use of words with my meagre understanding of the
technical processes involved.So I can't even tell you whether "by remote branch I mean a remote
Well, of _course_ it is confusingly similar. After all, I am posting
this question because I _am_ confused! And I am trying to both clear
up my confusion as well as get an idea how to fix the documentation toSigh. But it is cached and updated locally in some manner when
It is not just git-pull. I don't get the fine lines between "remote",
"remote tracking" and the respective details in either the user manual
or the manual pages of branch-related commands.And it's actually worse after your explanations. Previously I
imagined to have a chance to figure this out on my own, by trying to
abstract from what I see happening when using the various commands.Now I think that I basically have no chance figuring this out on my
own sufficiently well to be able to improve the documentation.--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
I see that Lars and others have provided some explanations in my
absence, but let me try to lay it out from basics, and hopefully between
all of our writing it will make sense. I'm going to try to be as basic
as possible, so if I am telling you something you already know, it's not
because I think you're stupid, but because I'm trying to be thorough.Git history is a directed graph of commit objects, with each commit
object pointing to its parent (or parents if it is a merge). We have
human-readable names pointing into the history as well, which we call
refs, and generally store under the "refs/" hierarchy (with a few
exceptions, which I will mention in a minute).There are a few different types of pointers (refs) that are useful to
us. They are differentiated by the types of things we want to do with
them.1. refs that track our ongoing commits. This process involves making
a new commit object whose parent is the previous value of the ref,
and then pointing the ref at the new commit. We generally call
these refs "heads", "local branches", or just "branches", and they
are stored in "refs/heads/".2. refs that point to a single commit and aren't changed. These refs
are "tags", and we store them in "refs/tags/".3. refs that represent a remote repository's local branch. These are
updated by git-fetch, which simply writes the new value of the
pointer into our local copy, throwing out the old value. These are
called "remote tracking branches" and are stored in
"refs/remotes/<remote>/<branch>".4. Temporary pointers to help out some multi-step operation that we're
in the middle of. These include FETCH_HEAD and MERGE_HEAD.There is an order of ref lookup which goes like:
.git/<name>
.git/refs/<name>
.git/refs/tags/<name>
.git/refs/heads/<name>
.git/refs/remotes/<name>It used to be the case (prior to git 1.5) that remote tracking branches
and local branches we...
Jeff King <peff@peff.net> writes:
The main question is why I can't find this explained in this manner in
the documentation. Are you going to put it in yourself, or should I
attempt doing it?--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
I guess because nobody complained it wasn't there before. :) Some of the
information is a bit under-the-hood for most end-users, but obviously in
your case the lack of information was creating confusion about the
terms.Why don't you take a stab at updating the documentation (since you are
the one who knows which parts were confusing you), and I will be more
than happy to help with making sure the changes are accurate.-Peff
-
Well, one problem is that there simply _is_ no part of the
documentation where such an explanation would have a place. It does
not fit in the man pages of git-branch/git-commit, it has some passing
relation to the repository layout explanation (even though the latter
should not be something that the user has to read and understand for
basic operation), it may have some place in the user manual, but may
be a bit technical/long for that. Or one places it into another
isolated file and hopes that a user will stumble across it when in
need of the information.Hm. Probably the usermanual is the best option in the current scheme
Thanks.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
I'm not too familiar with the usermanual, it having come about long
after I started with git. But I wonder if a subsection on "refs" under
the "Git internals" section might make sense.-Peff
-
Remote-tracking branch:
A local copy of a branch in another repository. This kind of branch
cannot be updated by 'git-commit' but only by 'git-fetch' (hence
indirectly by 'git-pull' and 'git-remote update'). If you try to
'git-checkout' a remote-tracking branch, you will get a detached HEAD.Local branch:
A branch to which you may commit changes. Optionally, the branch can be
configured to "follow" one of your remote-tracking branches. This means
that a 'git-pull' without arguments (when your local branch is checked
out), will automatically 'git-fetch' and then 'git-merge' the remote-
tracking branch.Example:
Your local branch 'master' is setup to "follow" 'refs/remotes/origin/master'.
So if you do this:$ git checkout master
$ git pullThen the 'git pull'-command will do this:
$ git fetch -f origin master:remotes/origin/master
$ git merge remotes/origin/masterThe magic setup that makes this happen is the following lines in .git/config:
[remote "origin"]
url = git://git.kernel.org/pub/scm/git/git.git
fetch = +refs/heads/*:refs/remotes/origin/*[branch "master"]
remote = origin
merge = refs/heads/masterWas this helpful?
--
larsh
-
It would be helpful. Except that nothing whatsoever can be found in
.git/config concerning my local and my remote tracking branches. So
where is that information _really_ hidden away?.git/FETCH_HEAD maybe?
It also appears that doing
git-checkout --track -b mybranch origin
on a git.git clone does _not_ create a tracking branch. I can't
figure out what I could specify as an origin to create a tracking
branch that would get reflected in .git/FETCH_HEAD.What gives?
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
It really is in .git/config, _provided_ that your repo was created by
1.5.0 or newer. Older versions had a more distributed setup using filesNope, that's just information about what got fetched last. A purely
With pre 1.5 you didn't get remote tracking branches in a separate
namespace. The default was to have a local branch called origin which was
the "remote tracking branch" for the master branch - but this wasn't
enforced. So with your repo the origin branch _is_ the remote trackingIt would appear that your repo was created with an old version of git.
Which also explains why you were talking about origin as a branch - which
it used to be (a real local branch too ...), rather than as a remote -
which it is now.The whole remotes/tracking mechanism changed in 1.5.0 - now it's much more
flexible (and probably more complicated too).--
Julian---
Ever notice that even the busiest people are never too busy to tell you
just how busy they are?
-
I think I am going to cry. So I need to rebase my branches, pull out
the resulting patch sets, scrap my repository, clone it new from
upstream, reapply my branches, in order to have a system where the
documentation is somewhat in synch with the actual behavior?[...]
No, it would seem that I can just
git-clone -l
my repository and be set up in the new order of things. Nice.However, it would appear from my experiments up to now that the
--track option _can't_ be made to work with a 1.4 repository. I think
that is worth mentioning in the docs.--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
... or you can you use "git remote" to create the remote tracking
branches. The important thing to realize is that 99% of what "git
remote" does is purely by editing the config file. (The last 1% is
running "git fetch" if you specify the -f option.) So understanding
what gets placed in the .git/config file after doing an initial clone
from a URL for a pre-1.5 git and what gets placed in .git/config file
and how the branches are set up post 1.5 is key to understanding whatBe careful, not really. A git-clone -l will set up a new repository
where origin/master is your original repository, i.e.:[remote "origin"]
url = /usr/projects/e2fsprogs/base
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/masterIn contrast, if you had done a git-clone of remote repository, you
might see something like this instead:[remote "origin"]
url = git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/masterIn contrast, if you are using git 1.4, after a clone, "origin" and
"master" are by default set to the "master" branch in the source
repository, and in git 1.4 (and in git 1.5 if you don't have any of
the above configuration opions in your .git/config file), the "origin"
branch is magical and works like the remote tracking branch of
origin/master of git 1.5 for the purposes of "git fetch", and then the
implied merge done by "git pull" merges from "origin" branch to theWell, there really is no such thing as a "1.4 repository". The only
real difference is the default configuration which is dropped into the
.config file when you do a "git clone", and whether the head of the
master branch created after the "git clone" is called "origin", with
some magic special casing so that works like a remote tracking branch
of the remote repo's master branch, or whether it is called
"origin/...
Yes, I noticed. I can do a
git-clone -l --reference /my/local/rep git://the/remote/repoAn error message might be nice, though. I find git hard to understand
at times.--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
Does that mean that specifying "--track" to git-checkout or git-branch
So --track/--no-track are actually supposed to be --follow and
So we have remote tracking branches, and we have local branches
following remote tracking branches, and "--track" and "--no-track"
create local branches following or not following a remote tracking
branch? And have nothing whatsoever to do with tracking or not
tracking a remove branch?Talk about misleading option names here.
Then in man git-branch we have:
In its second form, a new branch named <branchname> will be
created. It will start out with a head equal to the one
given as <start-point>. If no <start-point> is given, the
branch will be created with a head equal to that of the
currently checked out branch.When a local branch is started off a remote branch, git can
setup the branch so that git-pull(1) will appropriately
merge from that remote branch. If this behavior is desired,
it is possible to make it the default using the global
branch.autosetupmerge configuration flag. Otherwise, it can
be chosen per-branch using the --track and --no-track
options.What does "remote branch" in this context mean? A local branch
following a remote tracked branch? A remote tracked branch (which by
definition can't be checked out as a branch, since that leads to a
detached head)? What does "start off" mean in this context? If I
can't check out a remote branch, I can't start off on it, can I?Does "--track" mean that the new branch will copy any "remote" lines
which incidentally don't point to remote branches as their name would
suggest, but rather to remote tracking branches? And we want to have
the relation to the remote tracking branch preserved, not to the
actual remote branch?I don't get it. Really. No chance. There are fine distinction lines
in the git terminology, it would appear, and those lines are freely
ignored in naming options and configuration parameters. And the
manual pages the...
Yes. The "--track" option just adds some extra info in .git/config:
[branch "master"]
remote = origin
merge = refs/heads/masterThis info is then used by "git-pull" to
1. fetch updates from the remote repository "origin"Maybe ;-)
I just tried to avoid using the word "track" in more than one context,
Yes, this is the part that downloads objects from the remote
repository and updates refs/remotes/origin/master to refer to the sameNo. A remote repository: the name 'origin' can be used as an alias for
And this is the info added by "git branch --track" which enables the
automatic merging of refs/remotes/origin/master (since
refs/remotes/origin/master is your local copy of refs/heads/master inTalking to myself: obviously not
--
larsh
-
Disagree. "Does this answer all questions and makes git's behavior
perfectly transparent" -- no. But let's not confuse "magical" with
"helpful" here.--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
Ok, let's have another go. Maybe I have understood more as compared
with last time.git-branch/git-commit -b creates and manages local branches, nothing
else. Local branches' defining feature is that they have a branch
head I can move around myself.Then there are non-local branches. Their defining feature is that
they have no locally moving branch head and _must_ track a remote
branch.But local branches _also_ can track the progress/head of a remote
branch. Since they have a locally moving branch head, this will often
lead to merge conflicts which must be resolved.So this is more or less what I understand now. There really is no
difference between "tracking" and "following" as I thought previously.
It is just that a local branch which happens to track a remote branch
is basically a remote tracking branch with a head of its own.Which means it can get merge conflicts. Can we get merge conflicts
with a remote tracking branch, too? Namely when the remote branch
messed with its history, rebased/reverted stuff?So that the real difference between a local and a remote tracking
branch is not that the latter tracks a remote branch (the former can
do that as well), but that the latter has no local branch head and
that saves us a lot (but not necessary all) merge conflicts?--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
Well, sort of - they are not really merge conflicts as there is no merging
involved. Fetching is strictly an updating process, either we update the
branch or we don't.When updating a remote tracking branch there are two possible scenarios:
1) the new head is a superset of the old head (i.e. the old head forms
part of the history of the new)
2) the new head is not a superset of the old head (i.e. the old head does
not form part of the history of the new)The normal case is 1), and we simply update the branch to point at the
new commit. However what happens in case 2) depends on the configuration.
If we have told git to force an update (indicated by the '+' on the
beginning of the fetch line in the config) then we simply accept the new
head as with case 1), otherwise we complain to the user and don't updateYes. A remote tracking branch is basically a read-only local cache of
something that exists in some other repository.--
Julian---
If you're going to do something tonight that you'll be sorry for tomorrow
morning, sleep late.
-- Henny Youngman
-
No, since the "fetch" line in .git/config is prefixed by '+', which
gets translated to the '-f' option for 'git-fetch'.And this was probably the primary reason for refs/remotes/* in the
first place: you have a namespace in which there is no chance for
'git-fetch' to overwrite local changes (ancient git had no such
namespace).--
larsh
-
Ok, so a remote tracking branch is a forcefully merged branch, so we
put it into a separate category where we won't get tempted to have a
branch head which will get overwritten.This whole "remote tracking" appears to be more a matter of _policy_
rather than inherent design. It would appear that local and remote
tracking branches have no fundamental differences, they just get
different defaults which make it less likely for the first to lose
local changes, and less likely for the second to miss remote changes
(in particular where those involve messing up the history).But it would be easy to create chimeras when working outside of the
porcelain, right?--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
-
I would hesitate to use the word "merge" here at all. You really are
just throwing away the old value, and overwriting it with the new value.Sure, but then you are responsible for the mess it creates. :)
-Peff
-
I'd say they have no differences at all, it's just that
'git-checkout.sh' will refuse to update HEAD to point at something
outside of refs/heads.--
larsh
-
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| Tarkan Erimer | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Amit K. Arora | [RFC] Heads up on sys_fallocate() |
| Chuck Ebbert | Why do so many machines need "noapic"? |
git: | |
| Jarek Poplawski | [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| David Miller | [GIT]: Networking |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
| Natalie Protasevich | [BUG] New Kernel Bugs |
