59

I'm trying to create a branch on the current branch on my Ubuntu guest. Unfortunately I keep getting this error:

git checkout -b origin/feature/IF-53-change-validation-window/Tommaso
fatal: cannot lock ref 'refs/heads/origin/feature/IF-53-change-validation-window/Tommaso': 
'refs/heads/origin/branch' exists; 
cannot create 'refs/heads/origin/branch/Tommaso'

I tried git gc --prune=now as suggested here link, but keep getting the same error.

Braiam
  • 1
  • 11
  • 47
  • 78
Tommaso Guerrini
  • 1,499
  • 5
  • 17
  • 33
  • 3
    It also happened to me because remote had two branches with different case like `Branch` and `branch`. And on Windows file-system it just could not fetch properly – kan Jul 29 '22 at 10:17
  • Could be something like this (walk through and answer): https://stackoverflow.com/questions/47703709/git-push-error-cannot-lock-ref-reference-already-exists/76012255#76012255 – NeilG Apr 14 '23 at 07:59

9 Answers9

69

It looks like the problem here was a branch X existed locally, and you tried to create a new branch X/Y. This won't work, because git creates a file at .git/refs/heads/X, so it can't create the folder X to contain the file Y.

However, it's worth adding that including "origin" in your branch name points to some confusion - origin is usually the name of the remote repository. If you run git branch I expect you will see local branches with origin in the name.

The format git checkout X is shorthand for:

  • look for a local branch X and check that out if it exists
  • otherwise look for a remote branch X and check that out locally (git checkout -b X origin/X)

To fix your current state, you can likely do this (see here):

git update-ref -d refs/heads/origin/branch
cmbuckley
  • 40,217
  • 9
  • 77
  • 91
  • Thank you! Actually I was creating the branch by giving the whole directory once I already was on the branch and not on origin – Tommaso Guerrini Jul 17 '17 at 11:27
  • @cmbuckley If [branch] exists on origin why can't the op just do `git fetch ; git checkout [branch]`? – jacknad Aug 27 '19 at 11:47
  • Yep - the first code block is a simple checkout. The rest of the answer explains the different modes of the checkout command, and how to recover and clean up the local refs. – cmbuckley Aug 27 '19 at 12:47
  • I'm confused. Was the problem with what OP did was that the name of the new branch started with "origin/"? – bob Mar 11 '20 at 18:38
  • The actual problem was probably conflicting branch names (e.g. differing only in case), and an earlier attempt to clean-up manually. There is nothing inherently wrong with naming a branch beginning with "origin/", but it certainly points to a misunderstanding of local and remote branches. – cmbuckley Mar 11 '20 at 21:14
  • thank you..I tried many solutions but your answer did the trick – Ahmed Nabil Apr 19 '23 at 10:51
44

This worked for me :

git --no-optional-locks fetch --prune origin 
MaTriXy
  • 1,659
  • 1
  • 20
  • 27
  • 3
    prune sounds evil; would you mind elaborating on what exactly this command does? – ddruganov Oct 28 '21 at 07:31
  • 1
    https://git-scm.com/docs/git-prune removes all unreachable objects from the object database – MaTriXy Nov 08 '21 at 07:47
  • 2
    this one helped me to resolve the problem when `git update-ref` from the accepted answer didn't do the trick – Szymon Sadło Feb 13 '23 at 15:39
  • Use `git ls-remote` and `git branch -r` to get an idea of your local and remote branches. Then you can try some pruning. Mine was fixed with `git fetch --prune origin` which I think removed a local reference to a no-longer-existent remote branch that was blocking (because it was called `feature`, yeah, great name for a branch). – NeilG Apr 13 '23 at 23:45
23

Sometimes this can happen if the name of the branch you create doesn't match git naming conventions or those set by you projects git administrator. Changing the name to one that does, can can fix this issue.

Deepak
  • 3,648
  • 1
  • 22
  • 17
18

I was looking for answer here, but actually my problem was simpler, yet unresolvable.

  • fresh clone of repo
  • git checkout foo/bar
  • git checkout -b foo/bar/baz
  • got similiar error message.

As described here, you cannot use foo/bar both as a branch and directory. I had to change proposed naming convention.

kiciek
  • 347
  • 3
  • 9
  • 2
    This was my issue. Thanks – Chuck Le Butt Nov 05 '21 at 18:42
  • 2
    An actual command that helps someone getting this error is always a good idea in Stack Overflow answers. In this case, for instance, moving the "root" branch to a new name (`git branch -M foo/bar foo/bar/main`) will free up `foo/bar`, and allow it to be created as a dirctory, which leads to the success of `git checkout -b foo/bar/baz`. – ELLIOTTCABLE Apr 05 '22 at 21:59
  • If you have lots of git branches with the same naming pattern, it's possible to batch rename git branches https://stackoverflow.com/a/44570815/3281978 – tgrrr Apr 18 '22 at 05:08
11

After trying some of the above solutions with no luck, this worked for me:

git gc --prune=now
General Mac
  • 1,846
  • 1
  • 11
  • 15
  • 1
    Worked for me, but would love some more information on what's going on here. For instance: `git-gc - Cleanup unnecessary files and optimize the local repository` from [https://git-scm.com/docs/git-gc](https://git-scm.com/docs/git-gc) – Kent Robin May 31 '22 at 13:50
9

This happened with me too. The reason was, I was checking out a branch named feature, but in my local I already had a branch called feature/new-feature.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Ishan jain
  • 151
  • 1
  • 6
  • I want to create branches in my local with this protocol {username}/featureName but since my username is the same for all branches I want to create , I am unable to create a branch. What should I do? – etotientz Jun 17 '21 at 16:02
1

This happend to me, too. The reason was that I tried to create a branch with a too deep directory. The deepest directory to successfully create was: origin/titleA/titleB/nameOfTheNewBranch and I first tried to create it one step deeper in origin/titleA/titleB/titleC/nameOfTheNewBranch which seemed to be too deep 'cause it does not work.

Vanessa
  • 29
  • 1
  • This is likely not because of the *depth*, but because of the *existence of a parent*. Refs (like branches) are files on the filesystem; and if git tries to create a branch named `a/b/c`, it has to create directories named `a` and `a/b`. If you *then* try and create `a/b/c/d`, it's going to fail — `a/b/c` exists, as a file, and cannot be re-created as a dirctory to hold `d` as a file. – ELLIOTTCABLE Apr 05 '22 at 21:57
1

refs/heads The HEAD file is usually a symbolic reference to the current branch. The so-called symbolic reference means that it is a pointer to another reference.

every branch you make(such as s/a/b/c/d) will create a path in refs/heads. A file named 'd' which save a SHA-1 values would be touch in the path: refs/heads/s/a/b/c/d

so the problem is, you made a branch named "origin/branch" already, so you can't make any branch named "origin/branch/xxxx" any more, why? because if u do so, git have to create a path named "origin/branch/xxxx" which would create a folder named 'branch', but u have a file named 'branch' already right? SO.

Peter
  • 29
  • 2
0

I just go a similar problem and the reason is, because of deleting the branch on the repo I couldn't access it to local so , what I do is delete the local branch and pull the new branch from the repo then create the feature branch and it did work

  • if you delete the branch in the repo it is still available in local
Fasika Walle
  • 117
  • 1
  • 4
  • Sometimes the local branch could be deleted but Git still has a local reference to a remote branch, even if that no longer exists, that doesn't appear in the normal branch list. Still easy to fix if you know what you've got: https://stackoverflow.com/questions/47703709/git-push-error-cannot-lock-ref-reference-already-exists/76012255#76012255 – NeilG Apr 14 '23 at 08:00