threads / discuss / 22995

How do you switch branches in a bare repo?

Subject: How do you switch branches in a bare repo?

## tl;dr

8 messages between Mar 12, 2010 and Mar 14, 2010.

replies: 7people: 5as markdown or json

Adam Nielsen· Mar 12, 2010, 06:26 UTC · lore
Hi all,

I want to remove some commits (with git reset) from a bare repo, but they're not in the master branch and I can't figure out how to change branches:

$ git checkout newbranch fatal: This operation must be run in a work tree

I've tried running the reset locally and pushing the change (with -f) but that doesn't work either, and Google isn't being much help.

How do you switch between branches in a bare repo?

Many thanks, Adam.

(Please CC)
Johannes Sixt· Mar 12, 2010, 06:57 UTC · re: Adam Nielsen · lore

Re: How do you switch branches in a bare repo?

Adam Nielsen schrieb:
Show 11 quoted lines
> I want to remove some commits (with git reset) from a bare repo, but
> they're not in the master branch and I can't figure out how to change
> branches:
> 
> $ git checkout newbranch
> fatal: This operation must be run in a work tree
> 
> I've tried running the reset locally and pushing the change (with -f)
> but that doesn't work either, and Google isn't being much help.
> 
> How do you switch between branches in a bare repo?
You don't have to. This should work:
   git push -f . newbranch~2:newbranch
will remove the last two commits at the tip of 'newbranch'.

Of course, you can do the push from any other repository as long as you are allowed to do non-fast-forward pushes into the bare repository.

-- Hannes
Adam Nielsen· Mar 12, 2010, 07:12 UTC · re: Johannes Sixt · lore

Re: How do you switch branches in a bare repo?

Show 10 quoted lines
>> How do you switch between branches in a bare repo?
> 
> You don't have to. This should work:
> 
>    git push -f . newbranch~2:newbranch
> 
> will remove the last two commits at the tip of 'newbranch'.
> 
> Of course, you can do the push from any other repository as long as you
> are allowed to do non-fast-forward pushes into the bare repository.

Thanks for the suggestion! Unfortunately it looks like I'm not allowed to do non-fast-forward pushes into my own repository because I keep getting this error:

error: denying non-fast-forward refs/heads/newbranch (you should pull first)
  ! [remote rejected] newbranch~2 -> newbranch (non-fast-forward)

I tried using a + in front of the branch name as recommended by the manpage but it didn't change anything :-(

Any further suggestions?

Thanks again, Adam.

Johannes Sixt· Mar 12, 2010, 07:34 UTC · re: Adam Nielsen · lore

Re: How do you switch branches in a bare repo?

Adam Nielsen schrieb:
Show 7 quoted lines
> Thanks for the suggestion!  Unfortunately it looks like I'm not allowed
> to do non-fast-forward pushes into my own repository because I keep
> getting this error:
> 
> error: denying non-fast-forward refs/heads/newbranch (you should pull
> first)
>  ! [remote rejected] newbranch~2 -> newbranch (non-fast-forward)
Perhaps non-fast-forwards are denied for a reason?

If not, then you can enable them by setting receive.denynonfastforwards to false in the bare repository.

-- Hannes
Adam Nielsen· Mar 12, 2010, 07:38 UTC · re: Johannes Sixt · lore

Re: How do you switch branches in a bare repo?

> Perhaps non-fast-forwards are denied for a reason?
> 
> If not, then you can enable them by setting receive.denynonfastforwards to
> false in the bare repository.

Ah, that did the trick! Although it was actually receive.denyNonFastforwards for me (adding the lowercase option had no effect, I had to edit the fancy-case version.)

But that allowed the push to work and I have gotten rid of my unwanted commits, so thanks a lot for your help!

Cheers, Adam.

Michael Witten· Mar 12, 2010, 08:09 UTC · re: Adam Nielsen · lore

Re: [Improvement?] How do you switch branches in a bare repo?

On Fri, Mar 12, 2010 at 00:26, Adam Nielsen <adam.nielsen@uq.edu.au> wrote:
Show 7 quoted lines
> Hi all,
>
> I want to remove some commits (with git reset) from a bare repo, but they're
> not in the master branch and I can't figure out how to change branches:
>
> $ git checkout newbranch
> fatal: This operation must be run in a work tree

Commands like "git checkout" and "git reset" essentially operate on 2 aspects of a repository:

    (1) The repository's state.
    (2) The repository's working tree.

Is there any reason why these commands can't just operate on (1) in a bare repository, thereby allowing users to use familiar commands to get their work done?

The "git checkout" command in a bare repository should serve to select on which branch other commands (like "git reset") operate, etc.

Michael Witten
Jonathan Nieder· Mar 12, 2010, 16:48 UTC · re: Michael Witten · lore

Re: [Improvement?] How do you switch branches in a bare repo?

Michael Witten wrote:
Show 9 quoted lines
> Commands like "git checkout" and "git reset" essentially operate on 2
> aspects of a repository:
> 
>     (1) The repository's state.
>     (2) The repository's working tree.
> 
> Is there any reason why these commands can't just operate on (1) in a
> bare repository, thereby allowing users to use familiar commands to
> get their work done?

Not that I can think of. I’d say go for it. (I’ll be glad to help in any way I can. Not sure I’ll have much time soon, but I can answer questions, look over patches, and so on.)

> The "git checkout" command in a bare repository should serve to select
> on which branch other commands (like "git reset") operate, etc.

My only worry would be low-level scripts that want to be able to use a separate index or work tree with a bare repository. Maybe the index file could be in a special "bare" state to request the semantics you’re describing.

Jonathan
Junio C Hamano· Mar 14, 2010, 06:52 UTC · re: Michael Witten · lore

Re: [Improvement?] How do you switch branches in a bare repo?

Michael Witten <mfwitten@gmail.com> writes:
> The "git checkout" command in a bare repository should serve to select
> on which branch other commands (like "git reset") operate, etc.
I am not so sure about the "should" part.

The verb "checkout" is to move/copy something that is stored in somewhere to some other place, and in the context of git, you are copying out the contents that is stored in the repository (either the index or the tree of a commit) to the working tree. It is true that "git checkout branch" also switches HEAD while doing so, but that is done primarily so that the result of further working on the checked out files in the working tree will be recorded in that branch, but I tend to see that as secondary. "git checkout file" and "git checkout branch file" do not even touch the HEAD.

I am more interested in the reason why you need to switch HEAD in a bare repository to begin with, though. If it is a one-shot thing, then I don't think it is too unreasonable to ask for people to learn symbolic-ref; if some valid workflow requires to flip the HEAD regularly, on the other hand, we might want to give the command to do so a shorter-to-type name than symbolic-ref, and that short name could be "checkout".

← back to recent threads