1001

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

これで、Gitリポジトリをソース(192.168.1.2)から宛先(192.168.1.1)に正常に複製できるようになりました。

しかし、ファイルagit 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)。それは考えられる理由ですか?

4

31 に答える 31

1186

このエラー メッセージerror: refusing to update checked out branch: refs/heads/masterはリモート リポジトリから出力されます。これは、作業ディレクトリで現在チェックアウトされている別のコードを持つ、リモートのベアでないリポジトリにコードをプッシュしようとしていることを意味します。この問題を回避する最善の方法は、ベア リポジトリのみにプッシュすることです。ベア リポジトリではこの問題は発生しません。

リモート リポジトリをベア リポジトリに変換するだけです (ベア リポジトリには作業コピーはなく、フォルダには実際のリポジトリ データのみが含まれます)。

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

git config --bool core.bare true

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

于 2010-07-14T22:45:21.807 に答える
741

Gitの学習を始めたときに同じエラーが発生しました。他の回答のいくつかは、明らかに Git の初心者向けではありません。

アイデアを理解するために、非専門用語を使用します。とにかく、何が起こっているかというと、2 つのリポジトリがあり、1 つは最初に作成したオリジナルで、もう 1 つは作成したばかりの作品です。

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

于 2010-05-29T03:26:25.603 に答える
132

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

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

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

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

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

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

于 2010-05-12T06:21:14.573 に答える
126

概要

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

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

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

解決策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]

これで、ユーザーは、別のブランチをチェックアウトするように明示的に要求することなく、branch1にいなくなりました。さらに悪いことに、ユーザーはブランチの外にいて、新しいコミットはぶら下がっています:

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

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

于 2013-02-14T16:28:01.017 に答える
68

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

[receive]
denyCurrentBranch = warn

また

[receive]
denyCurrentBranch = false

1 つ目は、ブランチを台無しにする可能性を警告しながらプッシュを許可しますが、2 つ目は静かに許可します。

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

于 2010-12-16T05:17:16.747 に答える
53

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押された!

于 2015-02-07T14:57:34.263 に答える
44

リモートボックスに使用可能なリポジトリを引き続き配置するというアイデアは気に入っていますが、ダミーブランチの代わりに次を使用するのが好きです:

git checkout --detach

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

于 2012-02-14T20:37:50.877 に答える
30

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

リポジトリでは、次のように入力するようにプッシュしています。

git config receive.denyCurrentBranch ignore

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

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

git checkout -f

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

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

于 2011-01-27T00:42:27.197 に答える
25

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

この種のことは、小さなプログラムを作成しようとすると発生します。すでに機能していたものを変更しようとしているので、レベル 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てみると、「fatal: This operation must be run in a work tree」のようなメッセージが表示されるはずです。したがって、ファイルを削除するという提案は、machine2 からのコミットが機能するためではありませ。混乱して、git がまだこれらのファイルを追跡していると思い込まないようにするためです。しかし、まだ machine1 上のファイルで作業したい場合、ファイルを削除するのは問題ですよね?

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

machine1 と machine2 でどれだけの作業を計画しているかによって異なります...

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

machine2 での作業が 1 回限りのものであり、そこで開発を続ける必要がない場合は、むき出しのレポを作成する必要はありません。ftp/rsync/scp/etc. マシン*2* のファイルをマシン*1* のファイルの上に置き、マシン*1* からコミット/プッシュしてから、マシン*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' と同じ親フォルダーに配置しないでください)。同様に行うことをお勧めしますが、上記の手順をできるだけ簡単にしたかったのです。

于 2016-05-12T21:07:51.297 に答える
25

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

リモートサーバーで:

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

OK、ローカル ブランチから:

git push origin master:master
于 2011-02-07T08:22:48.067 に答える
18

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

git push production

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

まず、サーバーのWebルートの外のどこかにベアリポジトリを設定する必要があります。

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/にあります。何が起こっているのかについてのより詳細な説明については、そこで見てください。

于 2012-10-15T18:16:00.607 に答える
13

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

于 2010-05-12T06:09:09.490 に答える
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
    
于 2015-09-30T15:40:12.283 に答える
7

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

于 2010-12-11T15:03:42.097 に答える
5

Gitを使用してAndroid携帯とラップトップのリポジトリを同期するのと同じ問題がありました。@CharlesBaileyが提案したように、私にとっての解決策は、プッシュではなくプルを実行することでした。

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

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

于 2012-04-15T04:29:24.683 に答える
3

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

たとえば、リモート サーバーでは次のようになります。

git branch dev
git checkout dev

ローカル設定:

git push 

リモートサーバー上:

git merge dev
于 2013-01-31T15:28:52.233 に答える
2

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

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

初期化

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

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

ワークフロー

基本的なワークフローは次のとおりです。

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

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

    git pull
    
  3. 1-2 を繰り返します。contentサーバーにプッシュできる別の開発者がいる可能性がありますlocal

于 2012-07-18T12:59:24.370 に答える
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
于 2012-09-02T23:55:52.040 に答える
1

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

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

于 2013-05-06T20:33:50.487 に答える
1

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

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

于 2012-09-06T19:09:06.173 に答える
1

私が見つけた、他の人に役立つかもしれない記事はGit in 5 minutesです。

DC にあるVirtual Distributed Ethernet (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を使用しているため、プッシュ時にパスワードの入力を求められません。記事Hosting Git Repositories, the Easy (and Secure) Wayでは、すべての設定方法について説明しています。

于 2012-03-16T12:18:07.267 に答える
0

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

于 2015-06-19T06:27:22.943 に答える
0

私にとっての解決策は次のとおりです。

リモートで:

git checkout -b some_tmp_name

ローカルで:

git push

リモートで:

git checkout master
git branch -d some_tmp_name

しかし、これは単なる回避策であり、本当の解決策ではありません。

于 2014-06-28T14:10:50.650 に答える