From: Junio C Hamano <hidden> Date: 2016-08-11 20:32:15
Josef Weidendorfer [off-list ref] writes:
Example to hack on git's next branch:
git-clone --use-separate-remote http://www.kernel.org/pub/scm/git/git.git
cd git
git-checkout origin/next
<hack on next>
git pull (to merge patches from remote 'next')
The checkout creates local branch 'next' to checkout read-only
remote branch 'remotes/origin/next'. Additionally, it sets up
'remotes/origin/next' from remote repository 'origin' as
default merge source for the new development branch.
I am disturbed by an inconsistency here.
+ if git-show-ref --verify --quiet -- "refs/heads/$newbranch"
+ then
+ echo "Proposed new branch '$newbranch' to checkout...
+ echo "To checkout, specify a new branch name with -b"
+ exit 1
+ fi
This logic is guarding against already having a local branch
that is called 'next', and that is why the "Proposed new branch"
message needs to be there. One explanation of why 'next' exists
in the local branch namespace in the first place is probably
there are other remote branches than origin that have 'next' and
the user previously checked it out. Or perhaps the user has
already done this "checkout origin/next" once already.
I wonder if it is more consistent and easy to use to just make
this:
git checkout origin/next
a synonym to:
git checkout -b origin/next remotes/origin/next
when remotes/origin/next exists and heads/origin/next does not.
Then "git checkout origin/next" would always mean "I want to
switch to the branch I use to hack on the branch 'next' Junio
has". Do it once and you will get exactly my tip, hack on it,
switch out of it and then do it again and you won't lose your
previous work but just switch to that branch.
That is, something like this...
---
@@ -4,6 +4,16 @@ USAGE='[-f] [-b <new_branch>] [-m] [<braSUBDIRECTORY_OK=Sometimes .git-sh-setup+# Automatic forking of local branch based on remote+iftest$#=1&&+gitshow-ref--verify--quiet--"refs/remotes/$1"&&+!gitshow-ref--verify--quiet--"refs/heads/$1"+then+setx-b"$1""remotes/$1"+echo>&2"* Forking local branch $1 off of remotes/$1..."+shift+fi+old_name=HEADold=$(git-rev-parse--verify$old_name2>/dev/null)new=
From: Josef Weidendorfer <hidden> Date: 2016-08-11 19:24:25
On Tuesday 07 November 2006 14:56, you wrote:
But what happens when an unexperienced user gets this conflict for the
first time (having for the first time used two different remotes)?
Your scheme forces her to learn two new things instead of one,
creating the artificial barrier I mentioned above.
I give the user a warning that she has to specify a branch
name herself. This does not force her to rename all her branches
and go with the new naming <remote>/<remote branch>, but probably
makes her do
repo developer1, branch next => next (magic behavior)
repo developer2, branch next => next2 (manual specification)
and perhaps rename next to next1 afterwards.
At least I do not want to type long branch names; most of the
cloned repos I have do have only one remote. So I would rename
the branches names created with the complex magic scheme.
Of course, another way is to be more smart with branch name parsing.
Currently, a given name is searched in
.git/
.git/refs/
.git/refs/tags/
.git/refs/heads/
.git/refs/remotes/
.git/refs/remotes/*/HEAD
What about adding before remotes
.git/refs/heads/<first-part-of-current-branchname>/
and at the end
.git/refs/remotes/<first-part-of-current-branchname>/
Ie. when on branch "origin/next", a given name "master" is
parsed as "refs/heads/origin/master" when existing?
So the parsing rule is: "With current branch X and given name Y,
search for a branch as near as possible to X which has Y as
last name component".
This would match current UI, where you have simple branch names
like "master" or "next".
With above rule, you can use "master" to refer
to "refs/heads/origin/master" in the complex model,
and for a read-only remote head "refs/heads/remotes/origin/next",
it is enough to say
git-checkout next
to get a new local branch "refs/heads/origin/next" created
to work on.
You keep the simple UI and still get the perfect overview with
eg. with "gitk --all" even in the case where you work on
10s of remote branches from multiple repository.
From: Josef Weidendorfer <hidden> Date: 2016-08-11 19:30:03
On Tuesday 07 November 2006 07:54, you wrote:
quoted
IMHO this kind of aliasing is awkward. When you want to start
another topic branch on the remote branch, or want to reference the
remote branch for diffs, you have to explicitly specify
"remotes/origin/next", making for more typing.
Having more than one local branch for a remote branch is advanced
enough that the user should know how to create branches with any name
they choose.
But such an advanced szenario is exactly the reason to introduce
these long branch names like "origin/next", isn't it?
When a newbie probably never is confronted with this szenario, then
why give him longer branch names per default?
Do you see the contradiction in this argument?
IMHO it should be the other way around: when an advanced user
gets this conflict, he knows how to rename the branches by using
this more elaborated scheme.
I understand that these long branch names implicity give you information
about the upstream (by including the remote shortcut in front),
but this information (like all branch attributes) should also be
easy available with "git branch --info" or similar. Especially,
when we introduce shortcuts like "@up" (i.e. git-show-ref @up).
But I do agree that calling it "origin/next" the first time you
branch, and "remotes/origin/next" subsequent times, is nonintuitive.
However, this could be solved by the following message being printed
the first time:
$ git checkout origin/next
No local branch "origin/next" exists. Creating new local branch
"origin/next" off of remote branch "remotes/origin/next".
From: Josef Weidendorfer <hidden> Date: 2016-08-11 19:50:03
On Tuesday 07 November 2006 01:13, Junio C Hamano wrote:
I wonder if it is more consistent and easy to use to just make
this:
git checkout origin/next
a synonym to:
git checkout -b origin/next remotes/origin/next
when remotes/origin/next exists and heads/origin/next does not.
Interesting.
I wonder how often there is a real need for that long branch names.
IMHO this convenience behavior of git-checkout should target
the majority of possible use cases. Is it really better to default
to long branch names instead of asking for explicit branch name
in the rare case of conflict (ie. multiple remote repositories with
same branch names and you want to develop on both these branches
locally)?
Suppose developer2 uses this scheme, and has a local development
branch "junio/next", which is based on your "next" branch.
Now I want to work on the "next" branch of developer2, getting
a local branch name "developer2/junio/next".
Then "git checkout origin/next" would always mean "I want to
switch to the branch I use to hack on the branch 'next' Junio
has". Do it once and you will get exactly my tip, hack on it,
switch out of it and then do it again and you won't lose your
previous work but just switch to that branch.
Ah, now I understand your thinking.
I admit it has a compelling elegance.
However.
Would it not be confusing for newbies (and not only for them) to
first reference the remote branch with "origin/next", and afterwards, you
get your own development branch by using the exactly same name?
IMHO this kind of aliasing is awkward. When you want to start another
topic branch on the remote branch, or want to reference the remote
branch for diffs, you have to explicitly specify "remotes/origin/next",
making for more typing.
@@ -4,6 +4,16 @@ USAGE='[-f] [-b <new_branch>] [-m] [<braSUBDIRECTORY_OK=Sometimes .git-sh-setup+# Automatic forking of local branch based on remote+iftest$#=1&&+gitshow-ref--verify--quiet--"refs/remotes/$1"&&+!gitshow-ref--verify--quiet--"refs/heads/$1"+then+setx-b"$1""remotes/$1"+echo>&2"* Forking local branch $1 off of remotes/$1..."+shift+fi
I didn't know about "set x" before.
Thanks, you never end learning :-)
"git-checkout remotes/origin/next" does not work as expected,
and if fixed, it still should guard against an existing
local branch "origin/next", don't you think?
(Ok, it does not work in my patch, too.)
What do you think about the setup of the default for "git-pull"?
From: Karl Hasselström <hidden> Date: 2016-08-11 20:14:33
On 2006-11-07 11:53:32 +0100, Josef Weidendorfer wrote:
On Tuesday 07 November 2006 07:54, you wrote:
quoted
Having more than one local branch for a remote branch is advanced
enough that the user should know how to create branches with any
name they choose.
But such an advanced szenario is exactly the reason to introduce
these long branch names like "origin/next", isn't it? When a newbie
probably never is confronted with this szenario, then why give him
longer branch names per default? Do you see the contradiction in
this argument?
Well, I see your point. However, forcing users to have to unlearn and
relearn when they want to use more of git's power feels wrong. It
would present an artificial barrier for users wishing to proceed from
the newbie stage.
It's more important to have simple rules than to make these rules
generate short names. Long names are not conceptually difficult, just
a bit cumbersome at times.
IMHO it should be the other way around: when an advanced user gets
this conflict, he knows how to rename the branches by using this
more elaborated scheme.
But what happens when an unexperienced user gets this conflict for the
first time (having for the first time used two different remotes)?
Your scheme forces her to learn two new things instead of one,
creating the artificial barrier I mentioned above.
--
Karl Hasselström, kha@treskal.com
From: Karl Hasselström <hidden> Date: 2016-08-11 20:26:40
On 2006-11-07 02:25:24 +0100, Josef Weidendorfer wrote:
On Tuesday 07 November 2006 01:13, Junio C Hamano wrote:
quoted
Then "git checkout origin/next" would always mean "I want to
switch to the branch I use to hack on the branch 'next' Junio
has". Do it once and you will get exactly my tip, hack on it,
switch out of it and then do it again and you won't lose your
previous work but just switch to that branch.
Ah, now I understand your thinking. I admit it has a compelling
elegance.
I agree. The name is slightly longer than necessary in the common case
of only one remote repository, but the reduction of newbie confusion
will be worth it. (Non-newbies know how to give the branch any name
they want.)
However. Would it not be confusing for newbies (and not only for
them) to first reference the remote branch with "origin/next", and
afterwards, you get your own development branch by using the exactly
same name?
Not necessarily. As long as they know that there are two kinds of
branches, remote and local, it should be perfectly obvious. You check
out and modify your local copy of a remote branch, and occasionally
pull updates from the remote branch. If there is no local branch
corresponding to a certain remote branch, git will make one for you.
IMHO this kind of aliasing is awkward. When you want to start
another topic branch on the remote branch, or want to reference the
remote branch for diffs, you have to explicitly specify
"remotes/origin/next", making for more typing.
Having more than one local branch for a remote branch is advanced
enough that the user should know how to create branches with any name
they choose.
But I do agree that calling it "origin/next" the first time you
branch, and "remotes/origin/next" subsequent times, is nonintuitive.
However, this could be solved by the following message being printed
the first time:
$ git checkout origin/next
No local branch "origin/next" exists. Creating new local branch
"origin/next" off of remote branch "remotes/origin/next".
--
Karl Hasselström, kha@treskal.com