threads / patch / 8049

patchcheckout: allow full refnames for local branches

Subject: [PATCH] checkout: allow full refnames for local branches

## tl;dr

9 messages between May 9, 2007 and May 9, 2007. Diffs are folded; open one to read it.

replies: 8people: 3as markdown or json

Lars Hjemli· May 9, 2007, 08:40 UTC · lore

This teaches git-checkout to strip the prefix 'refs/heads/' from the supplied <branch> argument, to make

	git-checkout refs/heads/master
behave like
	git-checkout master
The former command would detach HEAD.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---

I'm undecided on wheter this is a bugfix or a new feature. It certainly introduces new behaviour, but it passes all the tests.

 git-checkout.sh |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
Show changes to git-checkout.sh +1 −0
diff --git a/git-checkout.sh b/git-checkout.sh
index ed7c2c5..6ff7b6e 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -63,6 +63,7 @@ while [ "$#" != "0" ]; do
 				echo "unknown flag $arg"
 				exit 1
 			fi
+			arg=$(echo "$arg" | sed -e "s|^refs/heads/||")
 			new="$rev"
 			new_name="$arg"
 			if git-show-ref --verify --quiet -- "refs/heads/$arg"
-- 
1.5.2.rc2.21.g3082a
Junio C Hamano· May 9, 2007, 08:48 UTC · re: Lars Hjemli · lore

Re: [PATCH] checkout: allow full refnames for local branches

Lars Hjemli <hjemli@gmail.com> writes:
Show 16 quoted lines
> This teaches git-checkout to strip the prefix 'refs/heads/' from the
> supplied <branch> argument, to make
>
> 	git-checkout refs/heads/master
>
> behave like
>
> 	git-checkout master
>
> The former command would detach HEAD.
>
> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
> ---
>
> I'm undecided on wheter this is a bugfix or a new feature. It certainly
> introduces new behaviour, but it passes all the tests.
Why is this necessary, may I ask?
Lars Hjemli· May 9, 2007, 09:07 UTC · re: Junio C Hamano · lore

Re: [PATCH] checkout: allow full refnames for local branches

On 5/9/07, Junio C Hamano <junkio@cox.net> wrote:
Show 7 quoted lines
> Lars Hjemli <hjemli@gmail.com> writes:
>
> > This teaches git-checkout to strip the prefix 'refs/heads/' from the
> > supplied <branch> argument
>
> Why is this necessary, may I ask?
>

I'm playing around with a gui frontend, and there I use git-for-each-ref to obtain possible arguments for git-checkout. That's how I discovered the 'problem', and solved it by stripping 'refs/heads/' in my frontend. But then I thought it would be nice if 'git-checkout' did the stripping on my behalf, since this might bite others too :)

-- 
larsh
Shawn O. Pearce· May 9, 2007, 18:54 UTC · re: Lars Hjemli · lore

Re: [PATCH] checkout: allow full refnames for local branches

Lars Hjemli <hjemli@gmail.com> wrote:
Show 6 quoted lines
> I'm playing around with a gui frontend, and there I use
> git-for-each-ref to obtain possible arguments for git-checkout. That's
> how I discovered the 'problem', and solved it by stripping
> 'refs/heads/' in my frontend. But then I thought it would be nice if
> 'git-checkout' did the stripping on my behalf, since this might bite
> others too :)

If you are building "porcelain" to sit over Git and offer up a pretty view of things, I would encourage you to avoid the stock porcelain. Don't use git-checkout, its stock porcelain. Instead go right to the plumbing. The plumbing doesn't really change behavior as often (if ever).

You can see in git-checkout.sh what actions you need to perform, but its really quite simple if there's no file-level merge involved. Here's the relevent bits from git-gui:

    set cmd [list git read-tree]
    lappend cmd -m
    lappend cmd -u
    lappend cmd --exclude-per-directory=.gitignore
    lappend cmd $HEAD
    lappend cmd $new_branch
    set fd_rt [open "| $cmd" r]
    fconfigure $fd_rt -blocking 0 -translation binary
    fileevent $fd_rt readable \
        [list switch_branch_readtree_wait $fd_rt $new_branch]
    ...
    git symbolic-ref HEAD "refs/heads/$new_branch"

Really all I'm doing is building up an argument list for git read-tree, passing it the commit that is currently in HEAD and the commit I want to switch to ($new_branch), and then I wait for it to finish its job. When its done, I run git symbolic-ref to update the current branch name.

-- 
Shawn.
Lars Hjemli· May 9, 2007, 20:01 UTC · re: Shawn O. Pearce · lore

Re: [PATCH] checkout: allow full refnames for local branches

On 5/9/07, Shawn O. Pearce <spearce@spearce.org> wrote:
Show 13 quoted lines
> Lars Hjemli <hjemli@gmail.com> wrote:
> > I'm playing around with a gui frontend, and there I use
> > git-for-each-ref to obtain possible arguments for git-checkout. That's
> > how I discovered the 'problem', and solved it by stripping
> > 'refs/heads/' in my frontend. But then I thought it would be nice if
> > 'git-checkout' did the stripping on my behalf, since this might bite
> > others too :)
>
> If you are building "porcelain" to sit over Git and offer up a pretty
> view of things, I would encourage you to avoid the stock porcelain.
> Don't use git-checkout, its stock porcelain.  Instead go right to
> the plumbing.  The plumbing doesn't really change behavior as often
> (if ever).

Thanks, I probably will (also to avoid the shell scripts, since my porcelain is aimed at my co-workers who are stuck on windows)

-- 
larsh
Shawn O. Pearce· May 9, 2007, 20:11 UTC · re: Lars Hjemli · lore

Re: [PATCH] checkout: allow full refnames for local branches

Lars Hjemli <hjemli@gmail.com> wrote:
Show 9 quoted lines
> On 5/9/07, Shawn O. Pearce <spearce@spearce.org> wrote:
> >If you are building "porcelain" to sit over Git and offer up a pretty
> >view of things, I would encourage you to avoid the stock porcelain.
> >Don't use git-checkout, its stock porcelain.  Instead go right to
> >the plumbing.  The plumbing doesn't really change behavior as often
> >(if ever).
> 
> Thanks, I probably will (also to avoid the shell scripts, since my
> porcelain is aimed at my co-workers who are stuck on windows)

Are you building a strictly Win32 native GUI? Or something else? Can I ask what sort of features you are going after? (And if there's a git repository available, feel free to just point me at it and ignore my questions.)

I'm just curious. We seem to have a lot of user interface projects going on at once right now (Eclipse plugin, git-gui, gitk, qgit, tig, gitweb, blameview) and everyone's been learning from each other. I think the competition is good, there's no clear right way to do things here. As the primary author of git-gui, I do want to try and keep current with what the others are up to. ;-)

-- 
Shawn.
Lars Hjemli· May 9, 2007, 20:38 UTC · re: Shawn O. Pearce · lore

Re: [PATCH] checkout: allow full refnames for local branches

On 5/9/07, Shawn O. Pearce <spearce@spearce.org> wrote:
Show 12 quoted lines
> Lars Hjemli <hjemli@gmail.com> wrote:
> > On 5/9/07, Shawn O. Pearce <spearce@spearce.org> wrote:
> > >If you are building "porcelain" to sit over Git and offer up a pretty
> > >view of things, I would encourage you to avoid the stock porcelain.
> > >Don't use git-checkout, its stock porcelain.  Instead go right to
> > >the plumbing.  The plumbing doesn't really change behavior as often
> > >(if ever).
> >
> > Thanks, I probably will (also to avoid the shell scripts, since my
> > porcelain is aimed at my co-workers who are stuck on windows)
>
> Are you building a strictly Win32 native GUI?  Or something else?

It's mono/.net, so I can test it on my linux box and push the binary directly to the poor souls on windows :)

> Can I ask what sort of features you are going after?  (And if
> there's a git repository available, feel free to just point me at
> it and ignore my questions.)

The features I'm focusing on are mostly trivial day-to-day operations of your average coder: status, diff, commit, push, fetch, merge, checkout, log. This should be enough to support our (planned) workflow of one public repo per developer + a shared integration repo with restricted push access + active use of topic-branches.

We currently use subversion, so real branches + real merges are killer arguments for a switch to git. But we also use tortoisesvn, and the "simplicity" of the gui must be met by some tool. Hence me playing around....

If/when it becomes useful, I'll put it up on http://hjemli.net/git/
> I'm just curious.  We seem to have a lot of user interface projects
> going on at once right now (Eclipse plugin, git-gui, gitk, qgit, tig,
> gitweb, blameview) and everyone's been learning from each other.
Heh, I actually considered calling it yagg (but it doesn't deserve a name yet)
> I think the competition is good, there's no clear right way to do
> things here.  As the primary author of git-gui, I do want to try
> and keep current with what the others are up to.  ;-)
Absolutely, nice work btw.
-- 
larsh
Junio C Hamano· May 9, 2007, 19:37 UTC · re: Lars Hjemli · lore

Re: [PATCH] checkout: allow full refnames for local branches

"Lars Hjemli" <hjemli@gmail.com> writes:
Show 13 quoted lines
> On 5/9/07, Junio C Hamano <junkio@cox.net> wrote:
>> Lars Hjemli <hjemli@gmail.com> writes:
>>
>> > This teaches git-checkout to strip the prefix 'refs/heads/' from the
>> > supplied <branch> argument
>>
>> Why is this necessary, may I ask?
>>
>
> I'm playing around with a gui frontend, and there I use
> git-for-each-ref to obtain possible arguments for git-checkout. That's
> how I discovered the 'problem', and solved it by stripping
> 'refs/heads/' in my frontend.

Pathspec-less variant of "git checkout" takes two kinds of parameters and has two flavours in its behaviour:

 (1) an exact branch name, in which case it switches to the
     branch; otherwise
 (2) any arbitrary commit object name, in whch case it checks
     out and detaches HEAD.

A tricky part is that an exact branch name is often a perfectly valid commit object name, so rule (1) trumps the rule (2). You just discovered a way to have a detached HEAD at a commit that happens to be at an existing branch -- by naming that commit without using its exact branch name.

An easier way to spell that would be:
	$ git checkout master^0
but
	master^0
        heads/master
        refs/heads/master

are all perfectly good ways to talk about the commit at the tip of the 'master' branch without spelling it as an exact branch name (which is 'master').

Lars Hjemli· May 9, 2007, 19:55 UTC · re: Junio C Hamano · lore

Re: [PATCH] checkout: allow full refnames for local branches

On 5/9/07, Junio C Hamano <junkio@cox.net> wrote:
Show 30 quoted lines
> "Lars Hjemli" <hjemli@gmail.com> writes:
>
> > On 5/9/07, Junio C Hamano <junkio@cox.net> wrote:
> >> Lars Hjemli <hjemli@gmail.com> writes:
> >>
> >> > This teaches git-checkout to strip the prefix 'refs/heads/' from the
> >> > supplied <branch> argument
> >>
> >> Why is this necessary, may I ask?
> >>
> >
> > I'm playing around with a gui frontend, and there I use
> > git-for-each-ref to obtain possible arguments for git-checkout. That's
> > how I discovered the 'problem', and solved it by stripping
> > 'refs/heads/' in my frontend.
>
> Pathspec-less variant of "git checkout" takes two kinds of
> parameters and has two flavours in its behaviour:
>
>  (1) an exact branch name, in which case it switches to the
>      branch; otherwise
>
>  (2) any arbitrary commit object name, in whch case it checks
>      out and detaches HEAD.
>
> A tricky part is that an exact branch name is often a perfectly
> valid commit object name, so rule (1) trumps the rule (2).  You
> just discovered a way to have a detached HEAD at a commit that
> happens to be at an existing branch -- by naming that commit
> without using its exact branch name.

Ok. But if this is intended behaviour, maybe we would want do change the detach-message in this case:

[~/src/git] next$ git checkout refs/heads/master
Note: moving to "refs/heads/master" which isn't a local branch

(sorry for stealing your time with this unimportant stuff, it just surprised me that refs/heads/$branch wasn't treated as a local branch name)

-- 
larsh

← back to recent threads