I was trying to deploy a hotfix to my staging server (DigitalOcean) but got a "cannot lock ref" error. I stumbled on this error before. I had a branch 'hotfix' and then I created 'hotfix/some-hotfix' branch and when I tried to push it to origin I got the error. I fixed it by deleting branch 'hotfix' in my repository (BitBucket). But now I am getting it while deploying on staging server.
Stack trace:
SSHKit::Command::Failed: git exit status: 1
git stdout: Fetching origin
error: cannot lock ref 'refs/heads/hotfix/my-hotfix-branch-name': 'refs/heads/hotfix' exists; cannot create 'refs/heads/hotfix/my-hotfix-branch-name'
From bitbucket.org:username/repo-name
! [new branch] hotfix/my-hotfix-branch-name -> hotfix/my-hotfix-branch-name (unable to update local ref)
error: some local refs could not be updated; try running
'git remote prune origin' to remove any old, conflicting branches
error: Could not fetch origin
git stderr: Nothing written
I tried running git remote prune origin
but it didn't help.
I'm stuck with no ideas here
While branch names are mostly just strings—so hotfix
and hotfix/my-hotfix-branch-name
are just the obvious, i.e., two different names—parts of Git insist (for reasons both good and bad) on treating them like directory and file name components.
(Note: if you are on Windows, you can mentally substitute /
with \
here. Or, just realize that a/b
works just as well on Windows as a\b
, for almost all purposes.)
If you have a file named README
, your OS won't let you create another file named README/TOO
. That is, the entity-slot README
is taken up by "file entity". You must first remove or rename README
, then create a directory (or folder, if you prefer that term) named README
. Inside this directory (or folder) you can now create more files, or move the original README
file into that directory.
Git imposes the exact same restrictions on branch names, and on remote-tracking names. If there is an existing branch named hotfix
you cannot create one named hotfix/my-hotfix-branch-name
. You fixed this in your repository by first deleting hotfix
. You must do the same thing in every other Git repository you intend to use: if it has a hotfix
, delete it. Then you can have that other Git repository create hotfix/my-hotfix-branch-name
.
It looks like your staging server has a hotfix
branch in it. You may have to log in to your staging server directly, or you may be able to use a git push --delete
to send a delete request to it. Either way, you must get that Git to delete that branch name. Operations done on your own repository don't help because every repository is independent.
When the problem occurs in a local repository, but due to remote-tracking names like origin/dir/file
, running git fetch -p origin
or git remote prune origin
should fix the problem. Both the -p
option to fetch
—which can be spelled --prune
—and the prune
subcommand for git remote
tell your Git to remove remote-tracking names, such as origin/dir
, that existed because the server had (emphasis on past tense here) a branch named dir
, but since then, someone deleted that branch. Your remote-tracking names are your Git's way of remembering what their branches were the last time you talked to them. So they had a dir
branch, but they no longer have one; now they have a dir/file
branch. You must have your Git delete your origin/dir
before your Git can create an origin/dir/file
remote-tracking name.
I was able to fix this issue doing this:
ssh
to your server.
- Find
/repo/
folder (I got mine in my deployed application folder ~/apps/app-name/repo
) and cd
into it.
- Run
git remote prune origin
.
After making this steps I was able to deploy to my server.
I had the similar issue when I do git pulll
> $ git pull
> error: cannot lock ref
> 'refs/remotes/origin/release/thing_15': 'refs/remotes/origin/release'
> exists; cannot create 'refs/remotes/origin/release/thing_15' From
> https://git.mycompany.com/projects/myproject
The git fetch fixed it with -p option (which exists in the newer versions of git) , please see the doc here https://git-scm.com/docs/fetch-options/2.20.0#fetch-options--p
git fetch -p