Felipe Contreras [off-list ref] writes:
The 'base' branch will be set each time you create a branch from another;
'git checkout -b foobar master' sets 'master' as the 'base' of 'foobar'.
"git checkout -t -b foobar mastee" would instead set 'upstream' of
'foobar' to the branch 'master' of remote '.' (the current one).
This 'base' is a new mechanism to explicitly say "The upstream of
this branch lives locally" by not setting "branch.foobar.remote".
Then you can do 'git rebase foobar@{base}' or simply 'git rebase', and Git will
pick the right branch to rebase unto, even if you have no 'upstream'
configured.
Surely you can teach rebase to pay attention to 'base' and achieve
that. But you can already do so with upstream, so this is not an
advertisement of a 'plus', but rather a lack of 'minus' (which is
not a bad thing at all).
This way 'git fetch' will keep picking 'origin', and other commands that make
use of 'upstrem' would be undisturbed.
And this is the true plus, because 'git fetch' with the current
"setting a local base using the same upstream mechanism to point at
a branch of _this_ repository, indirectly setting the upstream
_repository_ for this branch to the current repository" will end up
making you fetch from yourself, which is not very interesting.
So I think I understand your itch and I agree that it is a valid
one.
I however am not yet convinced if that direction is what you really
want go in, though. What should your 'git pull' on that branch do,
for example?
When you are on foobar and want to integrate with the branch you
based your work on (i.e. local 'master'), you can do one of these:
$ git pull
$ git pull --rebase
to "fetch the upstream branch and integrate with it", without having
to even care if that upstream branch is from the remote, or happens
to be truly local. By making 'git fetch' to go to the remote origin
site, what will you be merging (or rebasing on) when you do the
above two?
Incidentally, I suspect you can do exactly the same thing without
introducing a new concept "base" and instead special casing a remote
whose URL is "."; you essentially declare that "The upstream of this
branch whose branch.$name.remote is set to '.' lives locally", which
is not all that different from saying "The upstream of this branch
whose branch.$name.base exists lives locally", which is what you
seem to be proposing. One of the things this alternative approach
would "special case" such remote is probably to cause "git fetch" to
ignore such a branch.$name.remote setting and instead go fetch from
'origin', just like your "if there is branch.$name.base, but no
branch.$name.remote, fetch will go to 'origin'" does.
But it has exactly the same "what happens when you do 'git pull'"
problem, so even though it is conceptually a lot simpler, it has the
same brokenness.
On Wed, May 15, 2013 at 5:20 PM, Junio C Hamano [off-list ref] wrote:
Felipe Contreras [off-list ref] writes:
quoted
The 'base' branch will be set each time you create a branch from another;
'git checkout -b foobar master' sets 'master' as the 'base' of 'foobar'.
"git checkout -t -b foobar mastee" would instead set 'upstream' of
'foobar' to the branch 'master' of remote '.' (the current one).
Yeah, but I don't to set an upstream, because 'master' is not the
upstream of 'foobar'.
This 'base' is a new mechanism to explicitly say "The upstream of
this branch lives locally" by not setting "branch.foobar.remote".
No, 'base' can point to a remote tracking branch.
quoted
Then you can do 'git rebase foobar@{base}' or simply 'git rebase', and Git will
pick the right branch to rebase unto, even if you have no 'upstream'
configured.
Surely you can teach rebase to pay attention to 'base' and achieve
that. But you can already do so with upstream, so this is not an
advertisement of a 'plus', but rather a lack of 'minus' (which is
not a bad thing at all).
Only if there's an upstream configured, which many times is not the
case, and many times causes side-effects the user doesn't want to.
The purpose of 'upstream' is completely different.
quoted
This way 'git fetch' will keep picking 'origin', and other commands that make
use of 'upstrem' would be undisturbed.
And this is the true plus, because 'git fetch' with the current
"setting a local base using the same upstream mechanism to point at
a branch of _this_ repository, indirectly setting the upstream
_repository_ for this branch to the current repository" will end up
making you fetch from yourself, which is not very interesting.
So I think I understand your itch and I agree that it is a valid
one.
I however am not yet convinced if that direction is what you really
want go in, though. What should your 'git pull' on that branch do,
for example?
Exactly the same as 'git pull' does right now.
'base' has absolutely nothing to do with pulling or pushing.
When you are on foobar and want to integrate with the branch you
based your work on (i.e. local 'master'), you can do one of these:
$ git pull
$ git pull --rebase
to "fetch the upstream branch and integrate with it", without having
to even care if that upstream branch is from the remote, or happens
to be truly local. By making 'git fetch' to go to the remote origin
site, what will you be merging (or rebasing on) when you do the
above two?
The same as we do now.
Incidentally, I suspect you can do exactly the same thing without
introducing a new concept "base" and instead special casing a remote
whose URL is "."; you essentially declare that "The upstream of this
branch whose branch.$name.remote is set to '.' lives locally", which
is not all that different from saying "The upstream of this branch
whose branch.$name.base exists lives locally", which is what you
seem to be proposing.
That would be good, but it doesn't have the same benefits:
If I have set an 'upstream' branch, say 'github/master', and I have
'base' branch, say 'origin/master'. I would expect 'git rebase' to
rebase onto 'origin/master'. When I do 'git push', I expect to push to
'github/master'. Moreover, I would expect 'git fetch' to fetch from
'origin', but that can be discussed later.
Right now I'm forced to choose a single branch and set it to
'upstream'. If I choose 'origin/master' (which is not really the
upstream), the rebase would do what I want, but not the push, unless I
have configured a remote.pushdefault, but that would only work if I
the real upstream is the common one. If I choose 'github/master', then
rebase would not do what I want (and neither would fetch).
One of the things this alternative approach
would "special case" such remote is probably to cause "git fetch" to
ignore such a branch.$name.remote setting and instead go fetch from
'origin', just like your "if there is branch.$name.base, but no
branch.$name.remote, fetch will go to 'origin'" does.
But it has exactly the same "what happens when you do 'git pull'"
problem, so even though it is conceptually a lot simpler, it has the
same brokenness.
There is no brokenness; 'git pull' does different things depending on
the configuration. With my proposal nothing would change.
--
Felipe Contreras