# How do you switch branches in a bare repo?

8 messages from 2010-03-12 to 2010-03-14. Participants: Adam Nielsen, Johannes Sixt, Michael Witten, Jonathan Nieder, Junio C Hamano.
Thread: https://gitlist.dev/t/22995

## Adam Nielsen, 2010-03-12 06:26

Subject: How do you switch branches in a bare repo?
Message-ID: <4B99DEA2.6050104@uq.edu.au>
URL: https://gitlist.dev/e/4B99DEA2.6050104%40uq.edu.au

```
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, 2010-03-12 06:57

Subject: Re: How do you switch branches in a bare repo?
Message-ID: <4B99E5DD.3020005@viscovery.net>
URL: https://gitlist.dev/e/4B99E5DD.3020005%40viscovery.net
In-Reply-To: <4B99DEA2.6050104@uq.edu.au>

```
Adam Nielsen schrieb:
> 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, 2010-03-12 07:12

Subject: Re: How do you switch branches in a bare repo?
Message-ID: <4B99E957.60905@uq.edu.au>
URL: https://gitlist.dev/e/4B99E957.60905%40uq.edu.au
In-Reply-To: <4B99E5DD.3020005@viscovery.net>

```
>> 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, 2010-03-12 07:34

Subject: Re: How do you switch branches in a bare repo?
Message-ID: <4B99EE7C.4060902@viscovery.net>
URL: https://gitlist.dev/e/4B99EE7C.4060902%40viscovery.net
In-Reply-To: <4B99E957.60905@uq.edu.au>

```
Adam Nielsen schrieb:
> 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, 2010-03-12 07:38

Subject: Re: How do you switch branches in a bare repo?
Message-ID: <4B99EF6F.90207@uq.edu.au>
URL: https://gitlist.dev/e/4B99EF6F.90207%40uq.edu.au
In-Reply-To: <4B99EE7C.4060902@viscovery.net>

```
> 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, 2010-03-12 08:09

Subject: Re: [Improvement?] How do you switch branches in a bare repo?
Message-ID: <b4087cc51003120009o7bd99609w996de02b732fbbd9@mail.gmail.com>
URL: https://gitlist.dev/e/b4087cc51003120009o7bd99609w996de02b732fbbd9%40mail.gmail.com
In-Reply-To: <4B99DEA2.6050104@uq.edu.au>

```
On Fri, Mar 12, 2010 at 00:26, Adam Nielsen <adam.nielsen@uq.edu.au> wrote:
> 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, 2010-03-12 16:48

Subject: Re: [Improvement?] How do you switch branches in a bare repo?
Message-ID: <20100312164835.GA2303@progeny.tock>
URL: https://gitlist.dev/e/20100312164835.GA2303%40progeny.tock
In-Reply-To: <b4087cc51003120009o7bd99609w996de02b732fbbd9@mail.gmail.com>

```
Michael Witten wrote:

> 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, 2010-03-14 06:52

Subject: Re: [Improvement?] How do you switch branches in a bare repo?
Message-ID: <7v7hpfs8cc.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v7hpfs8cc.fsf%40alter.siamese.dyndns.org
In-Reply-To: <b4087cc51003120009o7bd99609w996de02b732fbbd9@mail.gmail.com>

```
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".

```
