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
andhotfix/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 thata/b
works just as well on Windows asa\b
, for almost all purposes.)If you have a file named
README
, your OS won't let you create another file namedREADME/TOO
. That is, the entity-slotREADME
is taken up by "file entity". You must first remove or renameREADME
, then create a directory (or folder, if you prefer that term) namedREADME
. Inside this directory (or folder) you can now create more files, or move the originalREADME
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 namedhotfix/my-hotfix-branch-name
. You fixed this in your repository by first deletinghotfix
. You must do the same thing in every other Git repository you intend to use: if it has ahotfix
, delete it. Then you can have that other Git repository createhotfix/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 agit 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
, runninggit fetch -p origin
orgit remote prune origin
should fix the problem. Both the-p
option tofetch
—which can be spelled--prune
—and theprune
subcommand forgit remote
tell your Git to remove remote-tracking names, such asorigin/dir
, that existed because the server had (emphasis on past tense here) a branch nameddir
, 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 adir
branch, but they no longer have one; now they have adir/file
branch. You must have your Git delete yourorigin/dir
before your Git can create anorigin/dir/file
remote-tracking name.I was able to fix this issue doing this:
ssh
to your server./repo/
folder (I got mine in my deployed application folder~/apps/app-name/repo
) andcd
into it.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
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