The full error is:
remote: error: cannot lock ref 'refs/heads/fix/add_overlay': reference already exists
I'm using SourceTree, but that should not matter I don't think. I keep trying to push and I keep getting this error, how can I resolve it?
The full error is:
remote: error: cannot lock ref 'refs/heads/fix/add_overlay': reference already exists
I'm using SourceTree, but that should not matter I don't think. I keep trying to push and I keep getting this error, how can I resolve it?
TL;DR: try removing their branch fix
, i.e., their refs/heads/fix
, which I suspect is in the way. (Be sure they don't care if you remove it!)
The error message is very odd. If the reference refs/heads/fix/add_overlay
exists, that's not a problem! Git should be able to lock it, and if it can't, the reason it can't is not "because it exists".
I suspect that this may be a misleading error message: it may be that the reference refs/heads/fix
—not refs/heads/fix/add_overlay
—exists, so it's impossible to create a directory refs/heads/fix/
in which to hold the sub-reference refs/heads/fix/add_overlay
because the existing reference refs/heads/fix
is in the way.
You can tell whether this is the case by examining the set of references that exist (by using git ls-remote
, or after a git fetch -p
, by looking at your own set of remote-tracking names that are based on their branch names). And, if it is the case, you should convince them—whoever they are—to rename or remove their branch fix
so that you can have them create a directory named fix/
containing branch names like fix/add_overlay
.
Fix
in uppercase in your comment here. Is it possible there is a case sensitive fix
vs Fix
and some sort of case folding issue on the server? –
Rosannarosanne a/b
and A/b
and a/B
and A/B
name four different files; Windows and Mac file systems tend to do case-folding and you cannot store all four of those. This makes life miserable. The solution is to avoid the situation entirely. :-) –
Rosannarosanne To remove that error, navigate to your project directory and run git remote
and then remove the origin by running git remote rm origin
.Create a new repository,
[assuming you use GitHub] by running git remote add origin https://github.com/your_user_name/your_repository_name.git
, and push the changes to the remote server,git push -u origin master
.This should work.
Reference already exists
error Overleaf was throwing. –
Paleolithic This error can occur when attempting to push to a folder with the same name as an existing branch.
https://mcmap.net/q/12211/-git-push-refs-heads-my-subbranch-exists-cannot-create
Another possible cause is about "Case Sensitive" of branch.
This is repeatable (with git bash on windows platform ) by:- (may cause loss of work in local repository. don't play with your working copy)
To fix:-
git merge <commit id>
Note:
This is an answer to this question, and, I hope, a range of similar questions, definitely with common elements in the Git error message, and possibly with some variations. This is the full error I'm using as an example (anonymised), but read on if your situation is a bit different. The answer may still help.
$ git push
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 13.43 KiB | 2.69 MiB/s, done.
Total 7 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 2 local objects.
To https://github.com/theaccount/therepo.git
92bc4d8..37c3af9 feature/the-branch -> feature/the-branch
error: update_ref failed for ref 'refs/remotes/origin/feature/the-branch': cannot lock ref 'refs/remotes/origin/feature/the-branch': 'refs/remotes/origin/feature' exists; cannot create 'refs/remotes/origin/feature/the-branch'
This question tends to repeat with variations which tends to attract a variety of answers, often of the "I tried this and it worked" sort, which then attracts comments such as "didn't work for me but this did". There's a proliferation of similar questions and answers which are not necessarily aligned, and not very explanatory:
I want to try to go a bit deeper and reveal more of the problem inside git
. Often with Git I don't want to know. Explanations are usually counter-intuitive, consisting of unhelpful diagrams of arrows pointing the wrong way with insufficient foundational context. This time I hope I can make something a bit clearer. I believe the addition of some underlying concepts can help when problem solving and make it easier to remember and apply in future situations.
I'm trying to keep it short, but remember:
.git
directory of your local repofeature/the-branch
Git will
.git/refs/heads/feature/
(if it doesn't exist).git/refs/heads/feature/the-branch
(this is just the way the initial Git implementation decided to do it)origin
) Git creates the path .git/refs/remotes/origin/feature/the-branch
including all those directories on the way (there can be multiple remotes)feature
(don't do that) then Git will have created a file .git/refs/heads/feature
and when it's pushed it will also create another file .git/refs/remotes/origin/feature
.git/refs/heads/feature/
directory and all branches named starting feature/
are blocked(Using the rsync
terminology of trailing slash to indicate a directory.)
All this content is in your local .git
directory, in your local repo - even when it's to record something about the remote repo, such as .git/refs/remotes/origin/feature/the-branch
.
Sometimes you can fix a problem just by cloning again from the remote, but that's cheating. And it takes time. And doing manual copying may introduce difficult to locate errors when you have content in your local that needs to be pushed to origin.
In this case we did have a branch called feature
, which apart from being very uncomfortable every time you took a look at the repo, also prevented the creation of feature
branches, that were required to work with other parts of the CI/CD toolchain.
For this (old) question (with no accepted answer) it looks very much like someone once-upon-a-time created a branch called fix
(genius). If a whole genre of Git questions isn't an argument for thinking about your naming conventions then I don't know what is. I've always hated bad naming, but now I've got reasoning why I can be indignant about it.
So the error message here looks like it's saying refs/heads/fix/add_overlay
already exists. TBH, it actually is saying that (thanks again, Git; good to see you're maintaining your reputation), but it seems likely that the reference that already exists is refs/heads/fix
. That means there's a local file .git/refs/heads/fix
, and Git cannot create .git/refs/head/fix/
like it needs to, because the path, or reference, already exists.
This situation can still remain even if you have deleted the offending (fix
or in my case, feature
) branch. Or you may have cleaned up the origin properly but still have the reference locally. A push can even seem to succeed even though it reports errors, and subsequent operations nevertheless fail.
There do seem to be a range of problems and error messages that can eventuate from this, and presumably similar situations. Bearing in mind the need for a local reference path including the right directories and filename, the following messages all make a lot more sense in retrospect:
In my situation I had somehow managed to push to the branch already. It existed on the remote, but now, after another push inexplicably failed I could no longer connect. Git told me my upstream branch was "gone":
$ git branch -vv
develop f22092e [origin/develop] Update deploy.yml
* feature/the-branch 37c3af9 [origin/feature/the-branch: gone] Move old README.md into documentation
main 7bd2f45 [origin/main] Delete Deploytonon-prod.yml
release 3b90d28 [origin/release] Merge pull request #10 from theaccount/develop
On branch feature/the-branch
Your branch is based on 'origin/feature/the-branch', but the upstream is gone.
(use "git branch --unset-upstream" to fixup)
I tried to reset the upstream connection but the problem was obviously still there:
$ git branch --unset-upstream
$ git branch --set-upstream-to=origin/feature/the-branch feature/the-branch
error: the requested upstream branch 'origin/feature/the-branch' does not exist
I tried to update from the origin to re-align (or something) but Git had put itself into a dead end:
$ git fetch
error: cannot lock ref 'refs/remotes/origin/feature/the-branch': 'refs/remotes/origin/feature' exists; cannot create 'refs/remotes/origin/feature/the-branch'
From https://github.com/theaccount/therepo
! [new branch] feature/the-branch -> origin/feature/the-branch (unable to update local ref)
Before using the git
one-liner that will fix all this, I just want to demonstrate a couple of views that were not top of my mind in my git
repertoire.
git branch -vv
does not show the bad reference, so it's invisible otherwise.
At the end of the day, you can $cd .git
and start looking around: ls refs/heads
. That might even be quickest. But to summarise the situation remotely and locally, the following two commands reveal the problem immediately.
$ git ls-remote
From https://github.com/theaccount/therepo.git
7bd2f45d5a7a137c1058c2074183ff0dc4c523b7 HEAD
f22092ebd8f9c243efaf770f941cddf0f9b916c5 refs/heads/develop
37c3af9fe595c427eb1ff1d194e742e5273633c1 refs/heads/feature/the-branch
5317d3f80b94ab721ee2c51b87b70e950241fe01 refs/heads/features/notification
7bd2f45d5a7a137c1058c2074183ff0dc4c523b7 refs/heads/main
3b90d28ef5e5b1d4ad45b17bfa98d10cc70cdef5 refs/heads/release
9b169e74da97174d4877e7359c1772287faf03bb refs/pull/1/head
f22092ebd8f9c243efaf770f941cddf0f9b916c5 refs/pull/10/head
96a8240b0449dff6579629de6feede0d82120765 refs/pull/2/head
8d1e7d64f276b9927dfd1b664805b208a421c6c9 refs/pull/3/head
0d120fee6da456d2f953a4aaa57f577489f21501 refs/pull/4/head
4ab5cc4596f31b44f72e3a0d92c8143b0cf39b2c refs/pull/5/head
84ad3d7d7856d44fd45592d083e284964c19f1ef refs/pull/6/head
881bfa14baa0b2d15e013371415cb3bf912b2887 refs/pull/7/head
b89c797b4abe0676cfdbfcbb09ffb87897a06eef refs/pull/8/head
d40fdb24faea617f35c045a73e1884952e9283bf refs/pull/9/head
b345722255e495cdd8895e7d53357dd8a3de523c refs/tags/v0.0.0
28f027de3f6e8c8f541f22eea4fa25eba3ce15ce refs/tags/v0.0.0^{}
5317d3f80b94ab721ee2c51b87b70e950241fe01 refs/tags/v1.0.0
Looking at the origin there is no refs/heads/feature
. That problem was cleared up by another dev, and that's not the blocker. The branch we're trying to access is listed there as refs/heads/feature/the-branch
as it should be. We can even see why last year we had problems tagging v0.0.0
, because there seems to be a key bounce crept into one of the tag names in refs/tags/v0.0.0^{}
.
But what does the local Git think the remote branches are?
$ git branch -r
origin/HEAD -> origin/main
origin/develop
origin/feature
origin/features/notification
origin/main
origin/release
Locally, we can see that there is still a reference to the origin feature
branch, even though it's been deleted from the remote itself (and never existed on the local (remember, I said it wasn't me!)). Starting a new repo (cloning again from scratch) would avoid this problem (now that origin/feature
has been deleted) but as we said, it's arduous and error prone, you could even try rm origin/feature
, but there's a proper way.
Now we want to delete something; and as always with Git (or anything, but somehow it's always more complicated with Git), we want to be sure we don't delete the wrong thing. Hopefully this background has introduced a lot more confidence. If you still judge there is a probability that something irrevocably destructive may happen, you can always zip the repo and keep it on one hand to try again if you mess up; but that should not really be necessary now.
We have our local branch, with changes to push, but upstream is showing an error, so we can just clean it up:
$ git branch --unset-upstream
Now we have our local branch without any tracking:
$ git branch -vv
develop f22092e [origin/develop] Update deploy.yml
* feature/the-branch 37c3af9 Move old README.md into documentation
main 7bd2f45 [origin/main] Delete Deploytonon-prod.yml
release 3b90d28 [origin/release] Merge pull request #10 from theaccount/develop
We can now "prune" the "orphan" local reference to the remote branch that's since been deleted. This is a meta data delete. It's not going to delete any real content, since Git is just an object store.
So we use a fetch
to get the branch information from the origin
, but we add the --prune
option, to make the command strip out any references in our local that don't align with the origin. This removes the blocking feature
(file) and creates the remote references to feature/the-branch
:
$ git fetch --prune origin
From https://github.com/theaccount/therepo
- [deleted] (none) -> origin/feature
* [new branch] feature/the-branch -> origin/feature/the-branch
Now that the local Git has the right references we can easily set the upstream for our local branch to the branch on the origin. The file named feature
(or fix
for the OP) has been removed, and is replaced with a directory of the same name:
$ git branch -u origin/feature/the-branch
Branch 'feature/the-branch' set up to track remote branch 'feature/the-branch' from 'origin'.
Checking our branch status shows all branches tracking their remotes:
$ git branch -vv
develop f22092e [origin/develop] Update deploy.yml
* feature/the-branch 37c3af9 [origin/feature/the-branch] Move old README.md into documentation
main 7bd2f45 [origin/main] Delete Deploytonon-prod.yml
release 3b90d28 [origin/release] Merge pull request #10 from theaccount/develop
You should now be able to add
, commit
and push
. Hopefully.
As I said, I think there are a range of similar issues that can occur due to combinations of faults on remote and origin. If your situation doesn't quite match the fetch --prune
doesn't work, then follow up on the list of questions at the beginning of this answer and research this command that may cover inverse situations:
git remote prune origin
© 2022 - 2024 — McMap. All rights reserved.