git push: refs/heads/my/subbranch exists, cannot create

Git

Git Problem Overview


Is this not possible to create somme sub-sub-folder in a repo on a server?

if i do:

git push origin dev/master 

everything work find

but if i do

git push origin dev/sub/master

i got this:

error: 'refs/heads/dev/sub' exists; cannot create 'refs/heads/dev/sub/master'

i checked with git branch -r and directly with ssh, there isn't dev/sub folder already created.

what's wrong?

Git Solutions


Solution 1 - Git

It's not a folder that exists, it's a branch. (Well, there may be a folder/directory involved somewhere—or maybe not, as references get "packed" and stop existing as files within directories.)

  • If branch b exists, no branch named b/anything can be created.
  • Likewise, if branch dev/b exists, dev/b/c cannot be created.

This is a git internal limitation. In this particular case, remote origin has a branch named dev/sub (regardless of whether you have it or not, the important thing is whether the remote has it). In order to create, on origin, a branch named dev/sub/master, you must first delete the branch named dev/sub on origin:

git push origin :dev/sub

(Of course, deleting this branch may delete something important over there, so be sure you know what you are doing. Generally, you might want to git fetch origin first, capturing their dev/sub as your origin/dev/sub. You can then make a local branch named dev/renamed-sub pointing to the same commit, create dev/renamed-sub on the remote, delete the remote dev/sub, and then create dev/sub/master on the remote.)


If you can log in on the remote (the system that origin is hosted on), you can go into the repository over there and simply rename the local dev/sub branch. (Based on comments below, I suspect that there's a broken auto-deploy script over there as well, which probably should be fixed to only deploy "deployable" branches, rather than everything that gets pushed. But I am just guessing here.)

Solution 2 - Git

I was in a state when I couldn't even fetch because my repo had info about non-existing remote branches I didn't even had checked out. I solved it by running combination (thanks @torek) of:

  • git branch -r list local copies of remote branches
  • git ls-remote list remote branches
  • git fetch --prune origin update local copies of remote branches (this actually didn't help me)
  • git remote prune origin remove info about removed remote branches (this did)

Solution 3 - Git

For me -->

Error =

fatal: cannot lock ref 'refs/heads/release/wl/2.3': 'refs/heads/release/wl' 
exists; cannot create 'refs/heads/release/wl/2.3'

Solution =

$~ git update-ref -d refs/heads/release/wl
$~ git checkout release/wl/2.3

Solution 4 - Git

The currently accepted answer didn't help me because I didn't have a ref on the remote repo to delete - it was purely on my local! So if you're in that situation, here's what to do:

This is the issue I was facing:

$ git fetch origin
error: cannot lock ref 'refs/remotes/origin/fix/sub-branch': 
'refs/remotes/origin/fix' exists; cannot create 
'refs/remotes/origin/fix/sub-branch'
From <repo URL>
 ! [new branch]      fix/sub-branch          -> origin/fix/sub-branch
 (unable to update local ref)

I tried the accepted answer's suggestion but got this:

$ git push origin :fix
error: unable to delete 'fix': remote ref does not exist
error: failed to push some refs to <repo URL>

So the ref didn't even exist on origin - it was clearly just hanging around somewhere on my local repo. So I ran $ git remote show me, which produced:

Remote branches:
...
refs/remotes/origin/fix             stale (use 'git remote prune' to remove)
...

Which then made the solution clear:

$ git remote prune origin
Pruning origin
URL: <redacted>
 * [pruned] origin/fix

With this, the problem disappeared:

$ git fetch origin
remote: Counting objects: 5, done.
remote: Total 5 (delta 2), reused 2 (delta 2), pack-reused 3
Unpacking objects: 100% (5/5), done.
From <repo URL>
 * [new branch]      fix/sub-branch          -> origin/fix/sub-branch

Solution 5 - Git

Try this command to fix it:

git gc

to run a number of housekeeping tasks within the current repository and remove unreachable objects (by invoking git prune and git fsck --unreachable).

Read more: git help gc and git help prune

Solution 6 - Git

If all else fails, check that your repo system does not have limitations for branch names. In my case, you could only create branches that start with SD-<number>. Any other naming would give you just a generic:

remote: error: cannot lock ref 'refs/heads/mybranch': 'refs/heads/mybranch/environment-variables' exists; cannot create 'refs/heads/mybranch'
To git.example.com:project/repository.git
 ! [remote rejected] mybranch -> mybranch (failed to update ref)
error: failed to push some refs to '[email protected]:project/repository.git'

Solution 7 - Git

Rename dev/sub to dev/sub/something, then you can create branch dev/sub/master.

Solution 8 - Git

#!/usr/bin/env bash
echo "update-ref delete refs/tags"
log="git-update-ref-errors.log"
script="./git-update-ref-exist-tags-delete.sh"
git_command="git update-ref -d refs/tags"

echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors to ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}

echo fetch
log="git-fetch-errors.log"
script="./git-fetch-exist-tags-delete.sh"
git_command="git fetch"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git fetch

echo pull
log="git-pull-errors.log"
script="./git-pull-exist-tags-delete.sh"
git_command="git pull"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git pull

echo push
log="git-push-errors.log"
script="./git-push-exist-tags-delete.sh"
git_command="git push"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git push

The script above will log errors to XXX-errors.log and fix them by generating and running a XXX-exist-tags-delete.sh automatically from the XXX-errors.log using the following commands:

  1. git update-ref -d refs/tags
  2. git fetch
  3. git pull
  4. git push

Solution 9 - Git

As a windows user, none of the solutions thus far solved the problem for me. The reason I was seeing this error was because (using the OP's branch names) I was trying to create a branch dev/sub but someone else had created a branch called Dev and as we all know, windows has a case insensitive file system.

So when windows tried to pull down dev/sub it was first trying to create the folder dev, but it couldn't because Dev already existed.

The solution was to delete the Dev branch locally and remotely with git branch -d Dev && git push origin :Dev. A git pull after this ran fine.

Another lesson going forward, branch names should always be lowercase to avoid this kind of gotcha's.

Solution 10 - Git

I understand this is already answered, but it did not worked for me. I did not cared for local changes as it was already pushed up but having issues pulling back. In my case, we changed halfway between having "hotfix" as branch to folder system having parent folder as "hotfix".

-- hotfix ----hotfix/1234_bug ----hotfix/3456_bug

So I was getting following error:

Fetching from origin Error: cannot lock ref 'refs/remotes/origin/hotfix/1234_bug': 'refs/remotes/origin/hotfix' exists; cannot create 'refs/remotes/origin/hotfix'

After searching for similar errors finally I found solution on a discussion thread here.

git remote prune origin

Solution 11 - Git

git remote prune origin fixed the issue for me

Solution 12 - Git

git checkout -b hotfix/my-new-branch

ga
gm "my commit"

gp --set-upstream origin hotfix/subscribers-function

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSnyfView Question on Stackoverflow
Solution 1 - GittorekView Answer on Stackoverflow
Solution 2 - GitmeridiusView Answer on Stackoverflow
Solution 3 - GitMEZIDI HamzaView Answer on Stackoverflow
Solution 4 - GitawreccanView Answer on Stackoverflow
Solution 5 - GitkenorbView Answer on Stackoverflow
Solution 6 - GitJuha UntinenView Answer on Stackoverflow
Solution 7 - GitDisplay NameView Answer on Stackoverflow
Solution 8 - GitTomer Bar-ShlomoView Answer on Stackoverflow
Solution 9 - GitalexkbView Answer on Stackoverflow
Solution 10 - GitSanjay ZalkeView Answer on Stackoverflow
Solution 11 - GitAndrea GherardiView Answer on Stackoverflow
Solution 12 - GitDazzleView Answer on Stackoverflow