プッシュは、非裸のリポジトリの作業コピーとステージング領域を更新しません
最初のリポジトリのステージング領域には、プッシュされたばかりの変更の逆が含まれているように見えます。これは、ベアリポジトリではないためです。つまり、作業コピーが含まれていることを意味します。 Git ドキュメント。一方、ベアリポジトリには作業コピー ディレクトリがありません。
リポジトリは裸ではないため、それにプッシュすると、プッシュはブランチ参照とシンボリックHEAD
参照のみを更新します。これは、ベア以外のリポジトリgit push
に存在する作業コピーとステージング領域で動作しないためです。
この結果、非ベア リポジトリの作業コピーとステージング領域は、更新されたプッシュの前HEAD
に存在していたリポジトリと同じ状態のままになります。つまり、working-copy と staging-area の実際の状態は、 が指すコミットの状態と一致しません HEAD
。git status
これが、とgit diff
が実行されたときに 2 つの状態の違いが現れる理由です。
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: plans.txt
$ git diff --staged
diff --git a/plans.txt b/plans.txt
index febb495..ce01362 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1 @@
MWA HA HA HA HA!
-Step 1: set up super secret spy base in Cleveland, Ohio
(次善の) 解決策: ハード リセット
working-copy と staging-area は と同期してHEAD
いないため、それらを再度一致させるための解決策は、単に使用することです
git reset --hard HEAD
git reset --hard
working-coy と staging-area を が指すコミットにリセットしHEAD
ます。
ただし、これは理想的なソリューションではありません...
理想的な解決策: 代わりに裸のリポジトリにプッシュする
作業コピーとステージング領域がリポジトリ参照と同期していないという正確な問題があるため、裸でないリポジトリにプッシュすることは実際には想定されていません。代わりに、非ベア リポジトリにプッシュする特別な理由がない限り、作業コピーを持たないベア リポジトリにプッシュする必要があります。
ベア リポジトリを作成するには、次の--bare
フラグを使用します。
# Initialize a bare repo
mkdir bare
cd bare
git init --bare
# Push changes to the bare repo
cd ..
mkdir project
cd project
# Make some changes and commit
git remote add origin ../bare
git push origin master
# Or create a bare clone from another bare or non-bare repo
git clone --bare <repo-path-or-uri>
Git 1.6.2 以降、裸でないリポジトリへのプッシュはデフォルトで拒否されます
Git バージョン 1.6.2 以降、裸でないリポジトリへのプッシュはデフォルトで拒否されていることに注意してください。
次のメジャー リリースでgit push
は、現在チェックアウトされているブランチへの移動はデフォルトで拒否されます。receive.denyCurrentBranch
受信リポジトリで構成変数を設定することにより、そのようなプッシュで何が起こるかを選択できます。
実際、現在のバージョンの Git を使用して非ベア リポジトリにプッシュしようとすると、次のエラー メッセージが表示されてプッシュが拒否されます (簡潔にするためにわずかに変更されています)。
$ git push origin master
Total 0 (delta 0), 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 non-bare
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'non-bare'
上記のエラー メッセージで説明されているように、リモートの非ベア リポジトリの構成receive.denyCurrentBranch
設定を無効にすることで、非ベア リポジトリへのプッシュを防止する安全性チェックを無効にできます。
git config receive.denyCurrentBranch warn # Warn when pushing to non-bare repo
git config receive.denyCurrentBranch ignore # Don't even bother warning