Gitプッシュエラー:チェックアウトされたブランチの更新を拒否


196

いくつかのマージの競合を解決し、コミットして変更をプッシュしようとしたところ、次のエラーが発生しました:

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master
Done
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To C:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:/Development/GIT_Repo/Project'

誰かがこのエラーを引き起こしている可能性があることを知っていますか?



6
あなたが実際に今のGit 2.3.0(2015年2月)と非裸のレポにプッシュする安全な方法を持っているgit config receive.denyCurrentBranch=updateInsteadstackoverflow.com/a/28262104/6309
VonC

回答:


229

理由:非ベアリポジトリにプッシュしています

リポジトリには、ベアと非ベアの 2種類があります。

ベアリポジトリには作業用コピーがないため、プッシュできます。これらは、Githubで取得するリポジトリのタイプです!ベアリポジトリを作成したい場合は、

git init --bare

つまり、要するに、裸でないリポジトリにプッシュすることはできません(編集:ええと、リポジトリの現在チェックアウトされているブランチにプッシュすることはできません。ベアリポジトリでは、チェックアウトされていないため、任意のブランチにプッシュできます。可能ですが、非ベアリポジトリへのプッシュは一般的ではありません) 。あなたができることは、他のリポジトリからフェッチしてマージすることです。これがpull request、Githubで確認できる方法です。あなたは彼らにあなたから引くように頼みます、そしてあなたは彼らに無理に押し込むことはしません


更新:これを指摘してくれたVonCのおかげで、最新のgitバージョン(現在2.3.0)では、非ベアリポジトリのチェックアウトされたブランチへのプッシュが可能です。それでも、ダーティな作業ツリーにプッシュすることはできません。これはとにかく安全な操作ではありません。


1
はい!これは正しいですありがとうございます!やるべきことが100万件あるので、誤って作業ディレクトリのクローンを作成しました。
ファンキー

25
実際には、ベアリポジトリ以外のリポジトリに問題なくプッシュできます現在チェックアウトされている1つのブランチにプッシュすることはできません。
どこ男なかっ

1
実際には、他にも数十のシナリオがあります。たとえば、私のリポジトリの一部は、自分のワークステーションとラップトップ上にあります(コードではなく、メモを取ります)。それぞれに「ワークステーション」と「ラップトップ」という2つのブランチがあります。ワークステーションでは、「ワークステーション」のみをチェックアウトし、ラップトップの「ワークステーション」ブランチにのみプッシュします(逆も同様です)。
2013

8
あなたが実際に今のGit 2.3.0(2015年2月)と非裸のレポにプッシュする安全な方法を持っているgit config receive.denyCurrentBranch=updateInsteadstackoverflow.com/a/28262104/6309
VonC

1
@skellyあなたのクローンは裸ではありませんが、githubにコピーしています。そのため、両方のクローンにはすべての履歴がありますが、github上のコピーにはコミットがチェックアウトされていませんが、あなたのコピーにはチェックアウトされているため、作業できます!
Shahbaz

115

私は最初に、リモートが何もチェックアウトしていないことを確認することでこの問題を解決し(実際には想定されていなかった)、次にそれを次のように裸にしました:

$ git config --bool core.bare true

その後、git pushはうまくいきました。


3
これは、私が探していたワンライナーフィックスです。でも、@ shahbazの回答のような裸の裸のリポジトリを説明するかもしれません
Mr5o1

これにより、変更履歴をプッシュできますが、それらの変更は非ベアリポジトリに反映されません。
jhill515

あなたgit config core.bare falsegit reset --hard
航空機

1
上記のように、リモートにプッシュしてもリモートは変更されません。
user1097111

46

概要

リポジトリのチェックアウトされたブランチにプッシュすることはできません。これは、データと履歴が失われる可能性が最も高い方法で、リポジトリのユーザーを混乱させるためです。ただし、同じリポジトリの他のブランチにプッシュできます。

ベアリポジトリではブランチがチェックアウトされないため、ベアリポジトリの任意のブランチにいつでもプッシュできます。

問題の剖検

ブランチがチェックアウトされると、コミットすると現在のブランチのヘッドを親として新しいコミットが追加され、ブランチのヘッドがその新しいコミットになるように移動します。

そう

A ← B
    ↑
[HEAD,branch1]

なる

A ← B ← C
        ↑
    [HEAD,branch1]

しかし、誰かがその間にあるブランチにプッシュできた場合、ユーザーはgitがデタッチヘッドモードと呼んでいるものになります。

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

これで、ユーザーは、別のブランチをチェックアウトするように明示的に要求しなかったため、もはやブランチ1にはいません。さらに悪いことに、ユーザーは現在ブランチの外にいて、新しいコミットはぶら下がっているだけです:

      [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

仮に、この時点でユーザーが別のブランチをチェックアウトすると、このぶら下がりコミットはGitのガベージコレクターにとって公平なゲームになります。



21

リモートマシンのpush先のリポジトリ/ディレクトリにcdして、次のように入力します。

$ git config core.bare true

これは動作しません。リポジトリは、プッシュした後も空のままです。
ソレン

上記のjhil515で述べたように、非ベアファイルは更新されず、データベースのみが更新されます。
Denis Cousineau

19

私にとっては、次のことがトリックを行いました:

git config --global receive.denyCurrentBranch updateInstead

ドライブF:のほぼ全体を、Gitを使用してWindows 10デスクトップとWindows 10ラップトップ間で同期するように設定しました。上記のコマンドを両方のマシンで実行してしまいました。

まず、ネットワーク上のデスクトップのFドライブを共有しました。次に、次のコマンドを実行して、ラップトップでクローンを作成できました。

F: git clone 'file://///DESKTOP-PC/f'

残念ながら、私のラップトップではすべてのファイルがF:\の下ではなく、F:\ fの下に置かれていました。しかし、私はそれらを手動でカットアンドペーストすることができました。その後もGitは新しい場所で動作しました。

次に、ラップトップのファイルにいくつかの変更を加えてコミットし、デスクトップに戻しました。上記のgit configコマンドを実行するまで、これは機能しませんでした。

これらのコマンドはすべてWindows PowerShell内から両方のマシンで実行したことに注意してください。

更新:場合によっては、変更をプッシュするのにまだ問題がありました。最後に、代わりに変更をプルし始めました。最新のコミットをプルしたいコンピューターで次のコマンドを実行することによって:

git pull --all --prune


1
私はこれをgitリポジトリよりもローカルにします:git config receive.denyCurrentBranch updateInstead
klor

14

すでに既存のリポジトリがあるので、

git config --bool core.bare true

リモートリポジトリでは十分です

core.bareドキュメントから

true(bare = true)の場合、リポジトリは、作業ディレクトリが関連付けられていない裸であると見なされます。この場合、git-addやgit-mergeなど、作業ディレクトリを必要とする多くのコマンドが無効になります(ただし、それにプッシュすることはできます)。

この設定は、リポジトリの作成時にgit-cloneまたはgit-initによって自動的に推測されます。デフォルトでは、「/。git」で終わるリポジトリはベアではないと見なされ(bare = false)、他のすべてのリポジトリはベアであると見なされます(bare = true)。


12

TLDR

  1. もう一度プルしてプッシュ:git pull &&& git push
  2. まだ問題がありますか?別のブランチにプッシュしgit push origin master:foo、リモートリポジトリにマージします。
  3. 代替的に添加することにより、プッシュを強制-fdenyCurrentBranchニーズを無視します)。

基本的にエラーは、リポジトリがリモートコードで最新でないことを意味します(そのインデックスと作業ツリーは、プッシュした内容と一致しません)。

通常、pull最初に最新の変更を取得し、pushそれを再度取得する必要があります。

役に立たない場合は、別のブランチにプッシュしてみてください。例:

git push origin master:foo

次に、リモートリポジトリのこのブランチをマスターにマージします。

を介して過去のコミットを意図的にgit rebase変更し、その変更でリポジトリをオーバーライドしたい場合は、-f/ --forceパラメータを追加してプッシュを強制することをお勧めします(そうしなかった場合はお勧めしませんrebase)。それでも機能しない場合は、次のgitメッセージで提案されているようreceive.denyCurrentBranchignore、リモートに設定する必要があります。

git config receive.denyCurrentBranch ignore

3

多分あなたのリモートレポはあなたがプッシュしたいブランチにあります。リモートマシンの別のブランチをチェックアウトしてみることができます。私はこれを行いましたが、これらのエラーが消えたので、リモートリポジトリに成功をプッシュしました。github.comの代わりにsshを使用して自分のサーバーに接続していることに注意してください。


1

gitリポジトリが同じ場所で(誤って)2回初期化されたため、このエラーが発生しました。最初は非ベアリポジトリとして、直後はベアリポジトリとして。.gitフォルダーが残っているため、gitはリポジトリがベアでないと想定します。.gitフォルダーと作業ディレクトリデータを削除すると、問題が解決しました。


1
私の状況では、これが事実でした。.gitリモート上のフォルダーを削除すると、最初のコミットをプッシュすることができました。
tim.rohrer 2018年

0

progitを読んで遊んでいるときにこのエラーが発生しました。ローカルリポジトリを作成し、同じファイルシステムの別のリポジトリにフェッチして編集し、プッシュしようとしました。NowhereManの回答を読んだ後の簡単な修正は、「リモート」ディレクトリに移動して一時的に別のコミットをチェックアウトし、変更を加えたディレクトリからpushしてから、戻ってヘッドをマスターに戻すことでした。

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