git push:refs / heads / my / subbranchが存在し、作成できません


88

サーバー上のリポジトリにsommeサブサブフォルダーを作成することはできませんか?

私が行った場合:

git push origin dev/master 

すべての仕事が見つかります

しかし、私がそうするなら

git push origin dev/sub/master

私はこれを得た:

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

「gitbranch-r」で直接sshで確認したところ、dev / subフォルダーはまだ作成されていません。

どうしましたか?


1
git ls-remote originは何を返しますか?
ikke 2014年

回答:


156

存在するフォルダではなく、ブランチです。(まあ、どこかにフォルダ/ディレクトリが含まれている可能性があります。参照が「パック」されてディレクトリ内のファイルとして存在しなくなるため、そうでない場合もあります。)

  • ブランチbが存在する場合、という名前のブランチb/anythingは作成できません。
  • 同様に、ブランチdev/bが存在する場合、dev/b/c作成することはできません。

これはgitの内部制限です。この特定のケースでは、remoteにoriginはという名前のブランチがありdev/subます(持っているかどうかに関係なく、重要なのはリモートにあるかどうかです)。にoriginという名前のブランチを作成するには、dev/sub/master最初dev/suborigin:という名前のブランチを削除する必要があります。

git push origin :dev/sub

(もちろん、このブランチを削除すると、そこにある重要なものが削除される可能性があるため、何をしているのかを確認してください。通常、git fetch origin最初にそれらを自分のものdev/subとしてキャプチャすることをお勧めしますorigin/dev/sub。次にdev/renamed-sub、同じコミットを指す名前のローカルブランチを作成できます。、dev/renamed-subリモートで作成し、リモートを削除してから、リモートdev/subで作成dev/sub/masterします。)


リモート(originホストされているシステム)にログインできる場合は、そこのリポジトリに移動して、ローカルdev/subブランチの名前を変更するだけです。(以下のコメントに基づいて、そこにも壊れた自動展開スクリプトがあると思われます。これは、プッシュされるすべてのものではなく、「展開可能な」ブランチのみを展開するように修正する必要があります。しかし、私はここで推測しています。)


1
ここでは用語をめちゃくちゃにしているだけだと思います。「内部制限」とは、誰もgitを使用する方法を変更せずに、gitが克服できるものであることを意味します。修飾されていない制限は、誰かがSHA1を壊した場合など、はるかに基本的なものになります。これでも克服できますが(たとえば、SHA256に移動)、40文字のSHA-1の詳細は、たとえば、ほとんどのフックで公開されます。したがって、この制限は外部に漏れます。
torek 2014年

2
&などrelease/1.1を使用release/1.2したい場合があることを考えると、これは奇妙なイライラする制限です。エラーメッセージは、制限を示すのではなく、ここに1つを導きます(ありがとう)。でも、わかりやすく説明してくれてありがとう。release/1.1/hofix/prevent-upload-borkrelease/1.1/hotfix/assure-user-of-competence
ベンジョン2016

2
「これはgitの内部制限です。」 - いいけどなんで?この方法で実装するのが簡単なロジックはありましたか?またはいくつかのツリートラバーサル?または何?
D.コバチ

2
@D.Kovács:その場合を禁止することで、Gitは参照をパス名として扱うことで名前が生成されたファイルに参照ハッシュを書き込むことができます。たとえば、Gitがとの両方refs/tags/fooを許可refs/tags/foo/2した場合、これを行うことはできません。独自のKey-Valueストアを実装する必要があります。とにかくGitは独自のKey-Valueストアを実装することを余儀なくされると思いますが、その場合に制限が解除されるかどうかはわかりません。
torek 2017

1
@ĐinhAnhHuy:この制限について説明している正式なドキュメントはありません。ただし、サブモジュールは完全に別個の名前空間にあります。サブモジュール名とブランチ名は、ブランチ名とファイル名が衝突しないのと同じ方法で衝突しないようにする必要があります(つまり、衝突しますが、明確化ツールを追加します。つまり、git checkout -- masterチェックアウトすることを意味します。ブランチ名ではなく、という名前のファイルmaster)。
torek 2018

62

チェックアウトすらしていなかった存在しないリモートブランチに関する情報がリポジトリにあるため、フェッチすらできない状態でした。私は以下の組み合わせ(@torekに感謝)を実行することでそれを解決しました:

  • git branch -r リモートブランチのローカルコピーを一覧表示する
  • git ls-remote リモートブランチを一覧表示する
  • git fetch --prune originリモートブランチのローカルコピーを更新します(これは実際には役に立ちませんでした
  • git remote prune origin削除されたリモートブランチに関する情報を削除します(これは行いました

8
git remote prune originこのエラー状態を解決するために実行した単一のコマンドでした。誤解を招くメッセージは確かに-私の場合、「release / 2.6.0」をプッシュしようとしていて、「refs / remotes / origin / release *」ディレクトリ全体を削除しました-それでも、error: update_ref failed for ref 'refs/remotes/origin/release/2.6.0': cannot lock ref 'refs/remotes/origin/release/2.6.0': 'refs/remotes/origin/release' exists; cannot create 'refs/remotes/origin/release/2.6.0'プッシュ/プル/フェッチを試みるたびにgitが文句を言い続けました
conny 2018年

32

私にとって->

エラー=

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

解決策=

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

1
git update-ref -d refs / remotes ...問題を「refs / remotes / origin / hotfix」に解決しました。'refs / remotes / origin / hotfix / ISSUEを作成できません
Eduardo

それはまた私の問題を修正しました。
ミハイルモルフィコフ

16

現在受け入れ答えは、私は削除するリモートレポに参照を持っていなかったので、私を助けていなかった-それは私の地元で純粋でした!したがって、そのような状況にある場合は、次のようにします。

これは私が直面していた問題です:

$ 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)

私は受け入れられた答えの提案を試しましたが、これを手に入れました:

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

したがって、refは存在しませんでしたorigin-それは明らかに私のローカルリポジトリのどこかにぶら下がっていました。だから私は走りました$ git remote show me、それは以下を生み出しました:

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

これにより、解決策が明確になりました。

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

これで、問題は消えました:

$ 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

3
うん、あなたが遭遇してそれをgit remote prune origin修正したのと同じ問題。ありがとう!
toddH 2018

3

次のコマンドを試して修正してください。

git gc

現在のリポジトリ内のハウスキーピングタスクを実行して(呼び出すことによって到達不能なオブジェクトを削除するgit prunegit fsck --unreachable)。

続きを読む:git help gcそしてgit help prune


2

他のすべてが失敗した場合は、リポジトリシステムにブランチ名の制限がないことを確認してください。私の場合、で始まるブランチしか作成できませんでしたSD-<number>。他の名前を付けると、一般的なものになります。

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 'git@git.example.com:project/repository.git'

1
#!/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

上記のスクリプトは、エラーをXXX-errors.logに記録し、次のコマンドを使用してXXX-errors.logからXXX-exist-tags-delete.shを自動的に生成して実行することにより、エラーを修正します。

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


1

Windowsユーザーとして、これまでのところ、どのソリューションも問題を解決していません。このエラーが表示された理由は、(OPのブランチ名を使用して)ブランチを作成しようとしたdev/subが、他の誰かがというブランチを作成したためです。Devです。ご存知のとおり、Windowsには大文字と小文字が区別されないファイルシステムがあります。

したがって、Windowsがプルダウンしようとしたとき、dev/sub最初にフォルダを作成しようとしましたdevが、Devすでに存在していたために作成できませんでした。

解決策は、を使用してDevローカルおよびリモートでブランチを削除することでしたgit branch -d Dev && git push origin :Dev。このgit pull後、うまくいきました。

今後の別の教訓として、この種の落とし穴を避けるために、ブランチ名は常に小文字にする必要があります。


1

私はこれがすでに答えられていることを理解していますが、それは私にとってはうまくいきませんでした。すでに押し上げられていたが、引き戻すのに問題があったため、ローカルの変更は気にしませんでした。私の場合、ブランチとしての「hotfix」から、「hotfix」としての親フォルダを持つフォルダシステムへの途中で変更しました。

-ホットフィックス---- hotfix / 1234_bug ---- hotfix / 3456_bug

だから私は次のエラーが発生していました:

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

同様のエラーを検索した後、最終的にここのディスカッションスレッド解決策を見つけまし

git remote prune origin


0

名前dev/subをに変更するとdev/sub/something、ブランチを作成できますdev/sub/master

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.