Gitプッシュエラー '[リモート拒否]マスター->マスター(ブランチは現在チェックアウトされています)'


961

昨日、あるマシンから別のマシンにGitリポジトリのクローンを作成する方法に関する質問を投稿しました。別のマシンから「git clone」するにどうすればよいですか?

これで、ソース(192.168.1.2)から宛先(192.168.1.1)にGitリポジトリを正常に複製できます。

しかし、ファイルを編集すると、 git commit -a -m "test"とaをとgit push、宛先(192.168.1.1)でこのエラーが発生します。

git push                                                
hap@192.168.1.2's password: 
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error: 
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
error: 
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git+ssh://hap@192.168.1.2/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://hap@192.168.1.2/media/LINUXDATA/working'

2つの異なるバージョンのGit(リモートでは1.7、ローカルマシンでは1.5)を使用しています。それは考えられる理由ですか?


5
オールドタイマーは、stackoverflow.com / a / 9283833/397872への受け入れられた回答を変更して、スレッドをアーカイブまたは何かに移動できますか?または所有権などを変更しますか?
リシュタ2012

9
これで、Git 2.3.0(2015年2月)およびstackoverflow.com/a/28262104/6309git config receive.denyCurrentBranch=updateInstead
VonC

これは、@ stigiが言及した本の新しいリンクです:git-scm.com/book/en/v1/Git-on-the-Server
Abdelilah El Aissaoui


しかし、なぜ、どのように機能するのか理解できますか?それは働いています、はい、それがすべてです。
Tilak Maddy

回答:


1149

単純にリモートリポジトリをベアリポジトリに変換できます(ベアリポジトリには作業用コピーがありません-フォルダには実際のリポジトリデータのみが含まれます)。

リモートリポジトリフォルダで次のコマンドを実行します。

git config --bool core.bare true

次に.git、そのフォルダー以外のすべてのファイルを削除します。そして、git pushエラーが発生することなく、リモートリポジトリに対して実行できます。


4
ありがとう。これも必要でした。私はGitコミュニティブックのサブモジュールチュートリアルに従っていて、この障害にぶつかりました。
Shiki

6
サーバー上のファイルを削除するのか、クライアントのファイルを削除するのかわからなかったので、何も削除しなかったので、実行しただけで問題は解決しましたgit config --bool core.bare true。一部のファイルを削除する必要がある特別な理由はありますか?もしそうなら、何を削除する必要があるかについてより正確にできますか?
ブライアンヴァンデンバーグ

24
これは最良の答えであり、他の誰もInterwebsの穴にそれを提供していません。私たちは皆同じエラーメッセージをググったと思います、そして私たちは皆これを読んでとても幸せでした。
セバスティアンGrignoli

40
たくさんの票を獲得しましたが、これはその特定の質問に対する本当に適切な回答だとは思いません。ベアリポジトリをきれいに作成する方法をユーザーに指示することは、半分ほど悪いことですが、たとえば、ユーザーが2つのコンピューター上で作業しているリポジトリである場合など、ファイルをチェックアウトしたままにする必要がある場合はどうでしょうか。
どこにも男はない

9
ソースリポジトリをベアに変更するのはやりすぎです。@Robertが指摘するように、必要なのはソースリポジトリの新しいブランチにプッシュすることだけです:stackoverflow.com/a/2933656/402949
Dan Solovay 2013年

708

Gitの学習を開始したときに、同じエラーが発生しました。他の答えのいくつかは明らかにGitを初めて使う人には向いていません!

(私はアイデアを理解するために非技術的な用語を使用します。)とにかく、起こっているのは2つのリポジトリがあることです。

現在、作業リポジトリにあり、「マスター」ブランチを使用しています。ただし、元のリポジトリで同じ「マスター」ブランチに「ログイン」していることもあります。オリジナルで「ログイン」しているので、Gitはオリジナルに取り組んでいて、物事を台無しにするかもしれないので、失敗するかもしれないと恐れています。したがって、元のリポジトリに戻り、「git checkout someotherbranch」を実行する必要があります。これで、問題なくプッシュできます。

これがお役に立てば幸いです。


76
+1もっと参考になりました、ロバートに感謝します。私の場合、私は裸のレポに変換する意味がありませんでした。プッシュしようとしているブランチを単に「非アクティブ化」する必要があります。理にかなっています。
Eric Muyser、

32
@ FMaz008:ダミーのブランチを作成するだけ(git checkout -b dummy)
Dror Cohen

14
これは、ほとんどの投票された答えよりもはるかに優れています:)ありがとう。他の答えも良い点ですが:)
IvanIvanić11年

103
ただ、プッシュのターゲットだレポでは、この明確にしますgit checkout -b tmp。次に、ソースリポジトリで:git push。その後、ターゲットに戻ります(オプション):git checkout master; git branch -d tmp
Hari Karam Singh 2012

18
ハリのコメントは最も簡単なレシピです。gitは多くの点で素晴​​らしいかもしれませんが、svnや他のrvからのものであるかもしれませんが、この全体は驚くほど直感的ではないと言っています。
UnconditionallyReinstateMonica

128

エラーメッセージは何が起こったかを説明しています。最新バージョンのGitは、ブランチがチェックアウトされている場合、プッシュを介してブランチを更新することを拒否します。

2つの非ベアリポジトリ間で作業する最も簡単な方法は、次のいずれかです。

  1. 常にプル(またはフェッチとマージ)または必要に応じて、リポジトリを更新します。

  2. 別のブランチ(インポートブランチ)にプッシュし、そのブランチをリモートマシンのマスターブランチにマージする。

この制限の理由は、プッシュ操作はリモートGitリポジトリでのみ動作し、インデックスと作業ツリーへのアクセス権がないためです。したがって、許可されている場合、チェックアウトされたブランチをプッシュする と、がリモートリポジトリのインデックスおよび作業ツリーと矛盾するように変更さHEAD れます。

これにより、プッシュされたすべての変更を元に戻す変更を誤ってコミットすることが非常に簡単になり、コミットされていないローカル変更と、新しいHEAD、インデックス、および作業ツリーの違いを区別することが非常に困難になりますプッシュ移動によるHEAD


1
ありがとう。どうすれば問題を解決できますか?私の192ボックスでは、「$ cd(project-directory)$ git init $(add some files)$ git add。」その後、191ボックスで「git clone」を実行していくつかのファイルを編集し、「git push」を試みました。
hap497

16
まあ、私は私の答えで可能性を説明しました。あなたは192のボックスに移動し、191箱(リモートという名前の通り191ボックスを追加したい場合があります-を見てから取り出すことができるのいずれかgit remote add box191 <191url>)、またはあなたは、代わりに名前のブランチ(例えばに191箱からプッシュすることができgit push origin master:refs/heads/upload、その後、) 192ボックスにマージします(例:)git merge upload
CBベイリー

3
Git 2.3.0(2015年2月)で非ベアリポジトリにプッシュする安全な方法が実際にありますgit config receive.denyCurrentBranch=updateInsteadstackoverflow.com/a/28262104/6309:オプション2はもう必要ありません。
VonC、2015

122

概要

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

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

ニーズに応じて、複数のソリューションがあります。

解決策1:ベアレポジトリを使用する

提案されているように、1つのマシンで作業ディレクトリが不要な場合は、ベアリポジトリに移動できます。リポジトリをいじるのを避けるために、単にそれを複製することができます:

machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo

これで、以前と同じアドレスに必要なすべてをプッシュできます。

解決策2:チェックアウトされていないブランチにプッシュする

ただし、リモート<remote>でコードをチェックアウトする必要がある場合は、特別なブランチを使用してプッシュできます。ローカルリポジトリでリモートoriginを呼び出し、ブランチマスターにいるとします。その後、あなたはできる

machine2$ git push origin master:master+machine2

次に、originリモートリポジトリにいるときにそれをマージする必要があります。

machine1$ git merge master+machine2

問題の剖検

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

そう

A ← B
    ↑
[HEAD,branch1]

なる

A ← B ← C
        ↑
    [HEAD,branch1]

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

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

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

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

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


3
「オートプシー」に対する1つの技術的な修正:HEADプッシュされたリポジトリでgitが実際に切り離されない。 HEADブランチは引き続きポイントされ、ブランチはプッシュされた新しいコミットをポイントします。ただし、作業ディレクトリとインデックス/ステージング領域は変更されません。プッシュ先のリポジトリで作業している人は誰でも、プッシュの影響から回復するために一生懸命働かなければなりません。保存する変更があるかどうかを確認し、変更がある場合は慎重に保存してください。
torek 14

回答に追加情報を追加するために、人々がプッシュするリモートリポジトリを非公開にする理由はほとんどないため、ベアリポジトリを使用するのが最善のソリューションです。

2
実際、ベアリポジトリ以外にプッシュする必要がある多くの状況があり、ソリューション2をかなり使用しています。また、私が非ベアリポジトリをプッシュするブランチは、決して一時的なブランチではなく、リモート追跡ブランチと同じ目的を果たします。
男はどこにもいない

SourceTreeを使用して複数のユーザーが作成したすべてのリポジトリーをホストするGITフォルダーをサーバーに作成しました。masterローカルPCにリポジトリを作成しました。remotesサーバーフォルダーにを追加し、別のユーザーがそれをプル/フェッチして作業できるように、リポジトリをサーバーにプッシュしようとしました。次のエラーが表示されます。! [remote rejected] master -> master (branch is currently checked out)どうすればチェックインできますか?
SearchForKnowledge 2015

1
@SearchForKnowledge、私が答えている質問を正確に尋ねていることに気づいていますか?!
2015

65

.git/config宛先サーバーでを編集することにより、この「制限」を回避できます。次のコードを追加して、「チェックアウト」されている場合でもgitリポジトリをプッシュできるようにします。

[receive]
denyCurrentBranch = warn

または

[receive]
denyCurrentBranch = false

前者はブランチをめちゃくちゃにする可能性を警告しながらプッシュを許可しますが、後者は静かに許可します。

これは、編集用ではないサーバーにコードを「デプロイ」するために使用できます。これは最善の方法ではありませんが、コードをデプロイするための簡単な方法です。


7
これを使用してサーバーにコードを「デプロイ」することはできません。チェックアウトされたブランチにプッシュできるように警告を無効にしても、作業コピーはプッシュで更新されることはありません。
Arrowmaster

10
上記のメソッドとcd .. && git reset --hardpost-receiveフックを使用してデプロイしています。ハックですが、動作します。
jholster

9
後者のコマンドラインバージョンは次のようになりますgit config receive.denyCurrentBranch warn
Andre Holzner

4
これは受け入れられる答えになるはずです。私たちの何人かは私たちが何をしているかを知っており、Gitの初心者ではありません。これがその人たちの答えです。
Qix-モニカは

2
ハ、しかし質問はそれらの人々によって尋ねられませんでした
どこにも男

46

git config --local receive.denyCurrentBranch updateInstead

https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

これをサーバーリポジトリで使用します。追跡されない上書きが発生しない場合は、作業ツリーも更新されます。

VonCで言及されているようにGit 2.3で追加されましたコメントで。

Git 2.3をコンパイルして試してみました。使用例:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

出力:

a
b

イェーイ、b押されてしまいました!


@VonCありがとう!それは私の仕事での最小限の例への執着です:-)
Ciro Santilli冠状病毒审查六四事件法轮機能

これは、サーバーで最新でない変更のコミットに問題がありますか?
akozi

@akoziどういう意味かわかりません。プルする前にローカルでコミットすると、従来の--bareクローンとまったく同じように動作します。--forceプッシュする必要があり、リモートでコミットを「失う」ようになります。
Ciro Santilli冠状病毒审查六四事件法轮功

1
@CiroSantilli新疆改造中心六四事件法轮功今は心配ありません。オプションの意味を調べました。updateInsteadはforceの同義語だと思いました。
akozi

updateInsteadはreceive.denyCurrentBranchの有効な値ではなくなりました
Xalorous

41

リモートボックスにまだ使用可能なリポジトリがあるという考えが好きですが、ダミーのブランチではなく、次のように使用します。

git checkout --detach

これはGitの非常に新しい機能のようです-私はgitバージョン1.7.7.4を使用しています。


8
そして、変更をプッシュした後、次を使用できます:git checkout mastermasterブランチに戻る。そうして初めて、変更が適用されます。
MAZDAK 2014年

30

同じ問題がありました。私は、Gitプッシュを使用してコードをサーバーに移動します。サーバー側ではコードを変更しないので、これは安全です。

リポジトリで、次のように入力します。

git config receive.denyCurrentBranch ignore

これにより、作業コピーのリポジトリを変更できます。

Gitプッシュを実行した後、リモートマシンに移動して次のように入力します。

git checkout -f

これにより、プッシュした変更がリモートマシンの作業コピーに反映されます。

プッシュする作業コピーに変更を加えた場合、これが常に安全であるとは限らないことに注意してください。


おかげで、ログ、私はあなたの提案をマージdenyCurrentBranchして入れてgit checkout -f内部のhooksジャックsenechal投稿@のようなフォルダをここに
ÉdersonT.シュラフタ

リモートリポジトリに移動してこのコマンドを実行せずにファイルを表示する方法はありますか?つまり、ローカルからのコマンドによって?
Royi 2016年

24

サーバーリポジトリを再作成して、ローカルブランチマスターからサーバーマスターにpushできます。

リモートサーバー:

mkdir myrepo.git
cd myrepo.git
git init --bare

さて、あなたのローカルブランチから:

git push origin master:master

3
リモートサーバーで '--bare'を省略していたので、これが私の解決策でした。この質問に対する答えは、リモートサーバーリポジトリを作業ディレクトリとして使用しているかどうかによって異なり、後者の場合はこれが正しい答えです。
Cas

2
わかりません:SIがベアリポジトリを作成してクローンしようとしましたが、クローンは何もダウンロードせず、何もアップロードしませんでしたので、これは機能しません... :-)ベアリポジトリに関するチュートリアルを読みましたが、ベアリポジトリファイルが含まれていません...それは間違いなく私が探しているものではありません...
inf3rno

22

これを引き起こすためにあなたがしたこと:

この種のことは、小さなプログラムを始めたときに起こります。すでに機能しているものを変更しようとしているので、レベル3の永続的な取り消し可能性の呪文を唱えます。

machine1:~/proj1> git init

追加/コミットを開始します。しかし、その後、プロジェクトはより複雑になり始め、別のコンピューター(自宅のPCやラップトップなど)からプロジェクトに取り組みたいので、次のようにします。

machine2:~> git clone ssh://machine1/~/proj1

そして、それは複製され、すべてが良さそうなので、machine2からコードを操作します。

次に、コミットをmachine2からプッシュしようとすると、タイトルに警告メッセージが表示されます。

このメッセージが表示されるのは、プルしたgitリポジトリが、machine1のそのフォルダにのみ使用されることを意図していたためです。そこからうまくクローンできますが、プッシュすると問題が発生する可能性があります。2つの異なる場所でコードを管理する「適切な」方法は、提案されているように「裸の」リポジトリを使用することです。ベアリポジトリはそこで行われる作業を行うようには設計されていません。複数のソースからのコミットを調整することを目的としています。このため、評価の高い回答では、.gitフォルダー以外のすべてのファイル/フォルダーを削除するよう提案されていますgit config --bool core.bare true

最高評価の回答の明確化:その回答に対するコメントの多くは、「。git以外のファイルをmachine1から削除していませんが、machine2からコミットすることはできました」のようなものです。そのとおり。ただし、これらの他のファイルはgitリポジトリから完全に「分離」されています。git statusそこに試してみると、「致命的:この操作は作業ツリーで実行する必要があります」のようなものが表示されます。だから、ファイルを削除する提案はmachine2で意志からコミットほどではない作品。混乱しないようにして、gitがまだこれらのファイルを追跡していると考えてください。しかし、machine1上のファイルを操作したい場合は、ファイルの削除が問題になりますよね。

それで、あなたは本当に何をすべきですか?

machine1とmachine2で引き続き作業する予定の量によって異なります...

machine1からの開発が完了し、すべての開発をmachine2に移動した場合...最高評価の回答が示すことをgit config --bool core.bare true実行します。次に、オプションで、.git以外のすべてのファイル/フォルダーをそのフォルダーから削除します。追跡されておらず、混乱を引き起こす可能性があります。

machine2での作業が1回限りのものであり、そこで開発を続ける必要がない場合は...裸のリポジトリを作成する必要はありません。ftp / rsync / scp / etcだけです。machine * 2 *のファイルをmachine * 1 *のファイルの上に置き、machine * 1 *からコミット/プッシュして、machine * 2 *からファイルを削除します。他の人がブランチを作成することを提案しましたが、別のマシンから一度だけ行った開発をマージしたいだけなら、それは少し面倒だと思います。

machine1とmachine2の両方で開発を継続する必要がある場合は、適切に設定する必要があります。リポジトリをベアに変換する必要があります。次に、そのクローンをmachine1で作成して作業する必要があります。これを行う最も簡単な方法は、

machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1

非常に重要:リポジトリの場所をproj1からproj1.gitに移動したので、machine2 の.git / configファイルでこれを更新する必要があります。その後、machine2から変更をコミットできます。最後に、裸のリポジトリを作業ツリーから離れた中央の場所に保持しようとします(つまり、 'proj1.git'を 'proj1'と同じ親フォルダーに配置しないでください)。同様に行うことをお勧めしますが、上記の手順をできるだけ簡単にしたかったのです。


非常に詳細で役立つ。私の事件は最後の事件でした、そしてあなたの指示は魅力のように働きました。
pojda 2017年

私はケース3にいて、少し違うことをしました。mkgit-server; mv .git git-server / proj.gitそしてgit clone git-server / proj.git to 1 and 2(またはgit remote origin ...)、適切なssh://プレフィックスを使用してマシン2私は通常のGHまたは他のHTTPサーバーでのマスターコピーのようなベアマスターコピーを保持し、両方のマシンでプッシュ/プルを使用し続けます。
zakmck 2018年

18

いくつかの設定手順を使用すると、次のようなワンライナーを使用して、変更をWebサイトに簡単に展開できます

git push production

これは素晴らしくシンプルです。リモートサーバーにログインしてプルなどを行う必要はありません。これは、運用チェックアウトを作業ブランチとして使用しない場合に最適です。(OPは少し異なるコンテキスト内で機能していました。@ Robert Gouldのソリューションはそれをうまく処理したと思います。このソリューションはリモートサーバーへの展開に適しています。)

最初に、サーバー上のどこかに、Webrootの外に、ベアリポジトリをセットアップする必要があります。

mkdir mywebsite.git
cd mywebsite.git
git init --bare

次に、ファイルを作成しますhooks/post-receive

#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

そしてファイルを実行可能にします:

chmod +x hooks/post-receive

ローカルマシンで、

git remote add production git@myserver.com:mywebsite.git
git push production +master:refs/heads/master

準備完了!将来的にはgit push production、変更をデプロイするために使用できます!

このソリューションの功績はhttp://sebduggan.com/blog/deploy-your-website-changes-using-git/にあります。何が起こっているかの詳細な説明については、そこを見てください。


あなたの提案は私を大いに助けました、しかし私はを使用しませんでしたbare、私はこれに従い、hooks(あなたが提案した)とマージして完璧に機能しました。
–ÉdersonT. Szlachta 2014

11

ベアリポジトリにのみプッシュする必要があります。ベアリポジトリは、チェックアウトされたブランチがないリポジトリです。裸のリポジトリディレクトリにcdすると、.gitディレクトリの内容しか表示されません。


9
非ベアリポジトリのチェックアウトされていないブランチにプッシュすることに何の問題もありません。これは完全に有効な作業方法です。
CBベイリー

十分に公正で、それはうまくいくでしょう。しかし、それはユーザーが行っていることではありません。
RibaldEddie、2010年

13
彼が「間違った」裸のリポジトリを使用していないという事実ではありません。それは彼がチェックアウト済みブランチにプッシュしているという事実です。彼が別個の裸のリポジトリを持っているか、または望んでいるという証拠はないので、彼が非裸のリポジトリにのみプッシュするべきであるというあなたの包括的な声明は、質問者にすべてのオプションを与えていません。その1つは、彼の差し迫った問題をより簡単に解決するかもしれません。
CBベイリー

10

3つのオプションがあります

  1. プルしてもう一度プッシュ:

    git pull; git push
    
  2. 別のブランチにプッシュ:

    git push origin master:foo
    

    そしてそれをリモートでマージします(gitまたはリクエストによって

    git merge foo
    
  3. 強制的に実行します(を介してコミットを意図的に変更しない限り、お勧めしませんrebase)。

    git push origin master -f
    

    それでも拒否される場合は、リモートリポジトリで無効にdenyCurrentBranch ます。

    git config receive.denyCurrentBranch ignore
    

オプション2がうまくいきます。リモートgit initローカルgit push originマスター:ブランチリモートgitマージ完了
ジャッキーチョン

7

実際、リモートをチェックアウトされていないブランチに設定するだけで十分です。別のブランチでリモコンをチェックアウトしたら、プッシュできます。


7

.git/config宛先プロジェクトで確認してください:

$ cat .git/config 
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[receive]
    denyCurrentBranch = updateInstead

core. bareがfalseの場合は、trueに設定できます。

$ git config core.bare true

そして、リモートへのローカルプッシュで:

git push remote_repo   // suppose the destination repo is remote_repo

成功します。remote_repoでgitのバージョンを確認できます。

$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < aircraft_xxx@126.com>
Date:   Thu May 17 21:54:37 2018 +0800

そして今、あなたはあなたの「ワークスペース」でgitを使うことができません:

$ git status
fatal: This operation must be run in a work tree

bare.barefalseに戻す必要があります。

$ git config core.bare false

5

Androidスマートフォンとラップトップでリポジトリを同期するためにGitを使用するのと同じ問題がありました。私にとっての解決策は、@ CharlesBaileyが示唆したように、プッシュではなくプルを行うことでした。

git push origin master Androidリポジトリでは、リポジトリ+作業コピーの非ベアチェックアウトへのプッシュが原因で@ hap497が受け取ったのと同じエラーメッセージで失敗します。

git pull droid masterラップトップリポジトリと作業コピーで動作します。もちろん、以前にのようなものを実行しておく必要がありますgit remote add droid /media/KINGSTON4GB/notes_repo/


4

以前のバージョンのGitでは、非ベアリポジトリの現在チェックアウトされているブランチへのプッシュが可能でした。

これは、許可するのがひどく紛らわしいことでした。そこで、彼らはあなたが見る警告メッセージを追加しましたが、これもひどく混乱しています。

最初のリポジトリがサーバーとして機能しているだけの場合は、他の回答が推奨するように、それをベアリポジトリに変換し、それで完了します。

ただし、両方が使用されている2つのリポジトリ間に共有ブランチが必要な場合は、次の設定で実現できます。

Repo1-サーバーとして機能し、開発にも使用されます

Repo2-開発専用です

次のようにRepo1を設定します

作業を共有するブランチを作成します。

git branch shared_branch

安全のために、共有ブランチをいじくりまわしたくないので、shared_branch以外への変更を拒否する$(REPO).git / hooks / updateも作成する必要があります。

repo1/.git/hooks  (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"

if [ "${refname}" != "refs/heads/shared_branch" ]
then
   echo "You can only push changes to shared_branch, you cannot push to ${refname}"
   exit 1
fi

次に、実際の作業を行うローカルブランチをrepo1に作成します。

git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch 'my_work'

(が機能するためgit config --global push.default upstreamに必要になる場合がありますgit push

これで、repo2を作成できます

git clone path/to/repo1 repo2 
git checkout shared_branch 

この時点で、repo1でプッシュおよびプルするローカルブランチで動作するようにrepo1とrepo2の両方のセットアップがありshared_branch、そのエラーメッセージを心配したり、repo1で作業ディレクトリの同期を外したりする必要はありません。使用する通常のワークフローが機能する必要があります。


3

通常のリモートリポジトリが必要な場合は、追加のブランチを作成してチェックアウトしてください。それを1つのブランチ(チェックアウトされていない)にプッシュし、ローカルからプッシュした後に後でアクティブになるブランチとマージします。

たとえば、リモートサーバーの場合:

git branch dev
git checkout dev

ローカルセットアップ:

git push 

リモートサーバー:

git merge dev

2

bareサーバーがどのように機能するかを確認するために実行できる1つのテストを次に示します。

ライブサイトがホストされているワークステーションとサーバーがあり、このサイトを時々更新したいとします(これは、2人の開発者が裸の仲介者を通じて作業をやり取りしている状況にも当てはまります)。

初期化

ローカルコンピュータにディレクトリを作成cdし、その中に次のコマンドを実行します。

# initialization
git init --bare server/.git
git clone server content
git clone server local
  1. まず、ベアserverディレクトリを作成します(最後の.gitに注意してください)。このディレクトリは、リポジトリファイルのコンテナとしてのみ機能します。
  2. 次に、サーバーリポジトリを新しく作成したcontentディレクトリに複製します。これは、サーバーソフトウェアによって提供されるlive / productionディレクトリです。
  3. 最初の2つのディレクトリはサーバー上にあり、3番目はワークステーション上のローカルディレクトリです。

ワークフロー

これが基本的なワークフローです。

  1. localディレクトリに入り、いくつかのファイルを作成してコミットします。最後にそれらをサーバーにプッシュします。

    # create crazy stuff
    git commit -av
    git push origin master
    
  2. 次に、contentディレクトリに入り、サーバーのコンテンツを更新します。

    git pull
    
  3. 1-2を繰り返します。ここではcontent、あまりにもサーバーにプッシュすることができ、他の開発者であってもよく、localあなたは彼から引くこととして。


2

これを使用してリモートのアップストリームブランチにプッシュすると、この問題が解決しました。

git push <remote> master:origin/master

リモートはアップストリームリポジトリにアクセスできなかったため、これは最新の変更をそのリモートに取得するための良い方法でした


1
より一般的には(これはコマンドの最終的な効果であるとして)、使用しますgit push <remote> master:newbranch。アイデアは、新しいブランチをリモートにプッシュし、それをマージできるようにすることです。これにより、エラーメッセージに記載されている不整合の問題を回避できます。
クレイ

1

git --init既存のベアリポジトリで再実行する必要があり、これ.gitによりベアリポジトリツリー内にディレクトリが作成されていましたgit status。私はそれを削除し、すべてが再び大丈夫でした:)

(これらの答えはすべて素晴らしいですが、私の場合、説明されているように、(私が見る限り)まったく異なるものでした。)


1

この質問を見ているほとんどの人は最初の2つの大きな答えで止まると思いますが、私の解決策を提供したいと思います。

説明されているエラーが発生したときに、Eclipse + EGit Webプロジェクトをセットアップしました。私を助けたのは、GitHubアプリを使用することだけでした。これは、魔法のように問題を解決したようです。EGitは常にプッシュを拒否しますが、GitHubデスクトップアプリは肩をすくめて変更をプッシュします。たぶん、マルチログイン状況をより適切に処理します。


1

他の人に役立つかもしれないと私が見つけた記事は5分でわかるGitです。

DC にある仮想分散イーサネット(VDE)にプッシュアップしたいGitバージョン管理下のXcodeプロジェクトがありました。VDEはCentos 5を実行します。

私がGitについて読んだ記事で、ベアリポジトリについて話したものはありません。SVNのバックグラウンドから簡単に実現できると思ったものを試してみるまでは、とてもシンプルに聞こえました。

リモートリポジトリをそのまま動作させるためのここでの提案。Xcodeプロジェクトのクローンを作成して、projectname.gitに作成、それをリモートサーバーにコピーすることで、。それからプッシュは魔法のように働きました。次のステップは、コミットに関するエラーなしでXcodeをプッシュすることですが、今のところ、ターミナルから実行しても問題ありません。

そう:

cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git sshusername@remotehost.com:repos/<br/>

Xcodeでコミットした後にXcodeプロジェクトから変更をプッシュするには:

cd /xcode-project-directory<br/>
git push sshusername@remotehost.com:repos/projectname.git<br/>

上記を行うためのよりスムーズで洗練された方法があると私は確信していますが、少なくともこれはうまくいきます。すべてがはっきりしているので、いくつかの説明/xcode-project-directoryがあります: xcodeプロジェクトが格納されているディレクトリです。/Users/Your_Name/Documents/Project_Nameです。projectnameは文字通りプロジェクトの名前ですが、任意の名前を付けることができます。Gitは関係ありません。

scpを使用するには、SSHアクセスを許可されているリモートサーバー上のユーザーアカウントが必要です。自分のサーバーを実行している人は誰でもこれを使用できます。共有ホスティングなどを使用している場合、運が悪い場合があります。

remotehost.comリモートホストの名前です。IPアドレスを簡単に使用できます。さらに明確にするために、リモートホストでSSHキーを使用してGitosisを使用しているため、プッシュするときにパスワードの入力を求められません。記事「Gitリポジトリをホストする、簡単な(そして安全な)方法」では、これらすべての設定方法について説明しています。


1

これを行う最良の方法は次のとおりです。

mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/

これによりリポジトリが複製されますが、で作業コピーは作成されません.../remote。リモートを見ると、と呼ばれる1つのディレクトリが作成されていることがわかりcurrentrepo.gitます。

次に、ローカルGitリポジトリから:

git remote add remoterepo ..../remote/currentrepo.git

変更後、次のことができます。

git push remoterepo master

1

Herokuのデプロイgitリポジトリでこの問題に遭遇しました。

Herokuの側に非ベアリポジトリがある理由はわかりませんが、回避策として、リモートリポジトリをリセットして再アップロードすることができました。

Herokuのリポジトリのコピーをコラボレーションのための唯一のgitリポジトリとして使用しないでください。念のため、はっきり言います。リポジトリの完全なコピーが安全な場所以外に安全に保存されていることが確実でない限り、これを行わないでくださいHeroku。リセットすると、リポジトリの内容が削除されます。

リセットするには:

  1. Herokuツールベルト(コマンドラインクライアントを含む)をまだインストールしていない場合は、インストールします。
  2. heroku-repoプラグインをまだインストールしていない場合はインストールします。

    heroku plugins:install https://github.com/heroku/heroku-repo.git
    
  3. リセットを実行すると、リポジトリが削除され、新しい空のリポジトリが作成されます

    heroku repo:reset
    
  4. 通常どおりにHerokuリモートにプッシュします。すべてを再アップロードします。


これを機能させるには、Herokuリポジトリツールのインストールが必要になる場合があります。するheroku plugins:install https://github.com/heroku/heroku-repo.git
ノア

1

empty(bare)リポジトリを作成したら、リモートサーバーの構成ファイルを変更する必要があります。

root@development:/home/git/repository/my-project# cat config 

そこにあなたは見るでしょう

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

あなたはこれを裸から偽に真にして、私はlogallrefupdates = trueを削除しました(その使用についてはわかりません!)

[core]
repositoryformatversion = 0
filemode = true
bare = true

以下をテストできます

$ git remote show origin
* remote origin
Fetch URL: my-portal@development:/home/XYZ/repository/XYZ
Push  URL: my-portal@development:/home/XYZ/repository/XYZ
HEAD branch: (unknown)

このHEADブランチ:(不明)は、プッシュできない場合に表示されます。したがって、HEADブランチが不明な場合は、ベアをtrueに変更し、プッシュが成功した後、

git remote show origin

そしてあなたは見るでしょう

 HEAD branch: master

0

私にとって作業ソリューションは次のとおりです。

リモートで:

git checkout -b some_tmp_name

ローカルで:

git push

リモートで:

git checkout master
git branch -d some_tmp_name

しかし、これは単なる回避策である実際のソリューションではありません。


中央リポジトリがない場合、これは有効なソリューションです。
Rick

0

誰かが便利だと思ったときのために。私にとっては、gitサーバーのアクセス許可の問題でした。最初からプロジェクトをチェックアウトして単純なファイルをプッシュすると、「プッシュが拒否されました:送信元/マスターへのプッシュが拒否されました」というメッセージが表示されました


-1

Gitでは、2つの通常の(非ベア)リポジトリーがファイルを直接プッシュ/プルすることはできません。中間のベアリポジトリが必要です。どうやらそれは子供を持っている夫婦のようなもので、カップルは離婚しつつあります。両親はお互いに話しませんが、子供を通してコミュニケーションします。

したがって、1つのリポジトリーがあり、このリポジトリーをベア・リポジトリーに複製してから、3番目に複製します。1番目と3番目は、2番目のリポジトリであるベアリポジトリを介して情報を交換できます。これは理にかなっていると思います。誰かがあなたの同意なしにリポジトリにチェックインできるようにしたくないので、マージの競合などを引き起こす可能性があるからです。

だから、ここに例があります:

PCでは、〜/ workspace

git init
echo "line 1" > afile.txt
git add .
git commit -m ‘initial import’
git clone --bare . ../remote-repository.git
git remote add origin ../remote-repository.git
git push --set-upstream origin master

ラップトップでは、〜/ workspace(git initなどを実行しないでください)

git clone //LJZ-DELLPC/remote-repository.git/ .

//次に、さまざまなコミットを行い、それらをプッシュします。

echo "line 2" > afile.txt
git add afile.txt
git commit -m 'added line 2'
git push    

次に、PCの〜/ workspaceに戻ります。

git pull

//次に、さまざまなコミットを行い、それらをプッシュします。

git push

ラップトップでgit pull

などなど。

コマンドウィンドウから直接コピーした、1台のマシン上のすべての具体的な例を次に示します。これにより、ステップが省略されていないこと、実際に機能したことなどがわかります。

lylez@LJZ-DELLPC ~
$ cd gitdir
/home/lylez/gitdir

lylez@LJZ-DELLPC ~/gitdir
$ ls

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1
/home/lylez/gitdir/repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git init
Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 1" > afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'initial import'
[master (root-commit) f407e12] initial import
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git clone --bar . ../repo1-bare-clone
Cloning into bare repository '../repo1-bare-clone'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git remote add origin ../repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push --set-upstream origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ..

lylez@LJZ-DELLPC ~/gitdir
$ ls
repo1  repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1-remote

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1-remote
/home/lylez/gitdir/repo1-remote

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git clone ../repo1-bare-clone .
Cloning into '.'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ echo "line 2" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git commit -m 'added line 2'
[master 5ad31e0] added line 2
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   f407e12..5ad31e0  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cd ../repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../repo1-bare-clone
   f407e12..5ad31e0  master     -> origin/master
Updating f407e12..5ad31e0
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 3" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'added line 3'
[master 3fa569e] added line 3
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../repo1-bare-clone
   5ad31e0..3fa569e  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ../repo1-remote/

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   5ad31e0..3fa569e  master     -> origin/master
Updating 5ad31e0..3fa569e
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
line 3

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git --version
git version 2.1.1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote

これは何が機能するかの例であり、その理由の説明です。あなたのコメントを除いて、ここには誤解はありません。
Lyle Z

1
「Gitを使用すると、2つの通常の(非ベア)リポジトリーはファイルを直接プッシュ/プルできません」-できることを除いて。
Andrew C

攻撃の代わりに具体例を投稿してください。
Lyle Z

それともグーグルできますか?stackoverflow.com/questions/1764380/…–
Andrew C、

あなたのサイトのスレッドでの最初の応答は、「...しかしgit readyと公式のgit wikiによると、ただのリポジトリにプッシュするだけです。」で始まります。次の応答は、「マスター->マスターをプッシュするだけの場合、コマンドはgit push origin:だけです」と述べ、それは単に機能せず、その影響には膨大な数の投稿があります。最後の応答は「サーバーにベアリポジトリとローカルワーキング(ベアでない)リポジトリを用意することをお勧めします。」で始まります。これはまさに私が提案したものです。
Lyle Z

-3

私のソリューション(使用中)

  1. リモートサーバーの「マスター」をチェックアウト
  2. 「dev」ブランチでローカルに作業する
  3. リモート開発に変更をプッシュする
  4. リモートでマスターに開発をマージ

ビンゴ

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