Git Push error: menolak untuk memperbarui cabang yang sudah diperiksa

196

Saya telah menyelesaikan beberapa konflik gabungan, berkomitmen kemudian mencoba untuk mendorong perubahan saya dan menerima kesalahan berikut:

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'

Adakah yang tahu apa yang menyebabkan kesalahan ini?

Funky
sumber
6
Anda sebenarnya sekarang memiliki cara yang aman untuk mendorong ke repo non-telanjang dengan Git 2.3.0 (Februari 2015) dan git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

Jawaban:

229

Alasan: Anda mendorong ke Repositori Non-Telanjang

Ada dua jenis repositori: telanjang dan non-telanjang

Repositori kosong tidak memiliki salinan yang berfungsi dan Anda dapat mendorongnya. Itulah jenis-jenis repositori yang Anda dapatkan di Github! Jika Anda ingin membuat repositori kosong, Anda dapat menggunakan

git init --bare

Jadi, singkatnya, Anda tidak bisa mendorong ke repositori non-telanjang(Sunting: Ya, Anda tidak dapat mendorong ke cabang repositori yang saat ini diperiksa. Dengan repositori telanjang, Anda dapat mendorong ke cabang mana pun karena tidak ada yang diperiksa. Meskipun mungkin, mendorong ke repositori non-telanjang tidak umum) . Apa yang dapat Anda lakukan, adalah mengambil dan menggabungkan dari repositori lainnya. Inilah pull requestyang bisa Anda lihat di Github. Anda meminta mereka untuk menarik dari Anda, dan Anda tidak memaksa mereka.


Pembaruan : Terima kasih kepada VonC karena menunjukkan ini, dalam versi git terbaru (saat ini 2.3.0), mendorong ke cabang yang dicek dari repositori non-telanjang dimungkinkan . Meskipun demikian, Anda masih tidak dapat mendorong ke a pohon kerja yang kotor , yang sebenarnya bukan operasi yang aman.

Shahbaz
sumber
1
Iya! Ini benar, terima kasih! Karena saya memiliki sekitar sejuta hal yang harus dilakukan, saya tidak sengaja mengkloning direktori kerja .... doh!
Funky
25
Sebenarnya, Anda bisa mendorong ke repositori non-telanjang baik-baik saja, Anda tidak bisa mendorong ke satu cabang yang saat ini diperiksa .
Tidak ada pria
1
Sebenarnya ada puluhan skenario lain. Sebagai contoh, beberapa repositori saya hanya di workstation dan laptop saya (bukan kode, tetapi catatan saya ambil). Pada masing-masing saya memiliki dua cabang, "workstation" dan "laptop". Di workstation, saya hanya memeriksa "workstation", dan saya hanya mendorong ke cabang "workstation" di laptop (dan sebaliknya).
Tidak ada tempat
8
Anda sebenarnya sekarang memiliki cara yang aman untuk mendorong ke repo non-telanjang dengan Git 2.3.0 (Februari 2015) dan git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC
1
@kelly Klon Anda tidak kosong, sementara salin di github. Jadi, meskipun kedua klon memiliki semua riwayat, salinan di github tidak memiliki komit apa pun yang diperiksa, tetapi salinan Anda memilikinya, untuk memungkinkan Anda bekerja!
Shahbaz
115

Saya memecahkan masalah ini dengan terlebih dahulu memverifikasi bahwa remote tidak memiliki apa pun diperiksa (itu benar-benar tidak seharusnya), dan kemudian membuatnya kosong dengan:

$ git config --bool core.bare true

Setelah itu git push bekerja dengan baik.

Sasha Pachev
sumber
3
Ini adalah perbaikan satu-liner yang saya cari .. tapi mungkin jelaskan repo telanjang seperti jawaban
@shahbaz
Ini akan memungkinkan sejarah perubahan didorong, tetapi perubahan itu tidak akan tercermin dalam repo non-telanjang.
jhill515
akan Anda git config core.bare falsedan git reset --hard ?
Pesawat
1
Seperti disebutkan di atas, kendali jarak jauh tidak akan diubah saat Anda mendorongnya.
user1097111
46

Ringkasan

Anda tidak dapat mendorong ke cabang repositori yang sudah diperiksa karena itu akan mengacaukan dengan pengguna repositori tersebut dengan cara yang kemungkinan besar akan berakhir dengan hilangnya data dan riwayat . Tetapi Anda bisa mendorong ke cabang lain dari repositori yang sama.

Karena repositori telanjang tidak pernah memiliki cabang yang diperiksa, Anda selalu dapat mendorong ke cabang repositori telanjang mana pun.

Otopsi masalah

Ketika cabang dicentang, komit akan menambahkan komit baru dengan kepala cabang saat ini sebagai induknya dan memindahkan kepala cabang menjadi komit baru itu.

Begitu

A ← B
    ↑
[HEAD,branch1]

menjadi

A ← B ← C
        ↑
    [HEAD,branch1]

Tetapi jika seseorang bisa mendorong ke peralihan cabang itu, pengguna akan mendapatkan dirinya sendiri dalam apa yang disebut git mode head terpisah :

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

Sekarang pengguna tidak lagi di branch1, tanpa secara eksplisit diminta untuk memeriksa cabang lain. Lebih buruk lagi, pengguna sekarang berada di luar cabang apa pun , dan komit baru apa pun hanya akan menjuntai :

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

Hipotetis, jika pada titik ini, pengguna memeriksa cabang lain, maka komit menggantung ini menjadi permainan yang adil bagi pengumpul sampah Git .

Tidak ada pria
sumber
Saya memperluas sedikit di stackoverflow.com/questions/2816369/…
Tidak ada tempat
21

cd ke direktori repo / yang Anda tekan pada mesin remote dan masuk

$ git config core.bare true
Ricky
sumber
Ini tidak bekerja. Repositori tetap kosong setelah mendorong ke dalamnya.
Sören
seperti yang dikatakan oleh jhil515 di atas, file-file non-telanjang tidak diperbarui, hanya database.
Denis Cousineau
19

Bagi saya, berikut ini caranya:

git config --global receive.denyCurrentBranch updateInstead

Saya mengatur drive F :, hampir secara keseluruhan, untuk menyinkronkan antara desktop Windows 10 dan laptop Windows 10 saya, menggunakan Git. Saya akhirnya menjalankan perintah di atas pada kedua mesin.

Pertama saya membagikan drive F desktop di jaringan. Lalu saya bisa mengkloningnya di laptop saya dengan menjalankan:

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

Sayangnya, semua file berakhir di bawah "F: \ f \" di laptop saya, bukan di bawah F: \ secara langsung. Tapi saya bisa memotong dan menempelkannya secara manual. Git masih bekerja dari lokasi baru sesudahnya.

Kemudian saya mencoba membuat beberapa perubahan pada file di laptop, membuatnya, dan mendorongnya kembali ke desktop. Itu tidak berhasil sampai saya menjalankan perintah git config yang disebutkan di atas.

Perhatikan bahwa saya menjalankan semua perintah ini dari dalam Windows PowerShell, di kedua mesin.

UPDATE: Saya masih memiliki masalah mendorong perubahan, dalam beberapa kasus. Saya akhirnya baru mulai menarik perubahan, dengan menjalankan yang berikut di komputer saya ingin menarik komit terbaru ke:

git pull --all --prune

Stephen G Tuggy
sumber
1
Saya lebih suka lokal ini daripada repo git:git config receive.denyCurrentBranch updateInstead
klor
14

Karena sudah ada repositori yang ada, jalankan

git config --bool core.bare true

pada repositori jarak jauh sudah cukup

Dari dokumentasi core.bare

Jika true (bare = true), repositori diasumsikan kosong tanpa direktori kerja yang terkait. Jika demikian, sejumlah perintah yang memerlukan direktori yang berfungsi akan dinonaktifkan, seperti git-add atau git-merge (tetapi Anda akan dapat mendorongnya).

Pengaturan ini secara otomatis ditebak oleh git-clone atau git-init ketika repositori dibuat. Secara default repositori yang diakhiri dengan "/.git" diasumsikan tidak kosong (bare = false), sementara semua repositori lainnya diasumsikan kosong (bare = true).

Johnny
sumber
12

TLDR

  1. Tarik & dorong lagi: git pull &&& git push .
  2. Masih masalah? Dorong ke cabang yang berbeda:git push origin master:foo dan gabungkan pada repo jarak jauh.
  3. Sebagai alternatif, paksa dorongan dengan menambahkan -f( denyCurrentBranchperlu diabaikan).

Pada dasarnya kesalahan berarti bahwa repositori Anda tidak up-to-date dengan kode jarak jauh (indeks dan pohon kerjanya tidak konsisten dengan apa yang Anda dorong).

Biasanya Anda harus pullterlebih dahulu mendapatkan perubahan terbaru danpush melakukannya lagi.

Jika tidak akan membantu, cobalah mendorong ke cabang lain, misalnya:

git push origin master:foo

kemudian gabungkan cabang ini pada repositori jarak jauh kembali dengan master.

Jika Anda mengubah beberapa komit sebelumnya dengan sengaja git rebasedan Anda ingin mengganti repo dengan perubahan Anda, Anda mungkin ingin memaksakan dorongan dengan menambahkan -f/ --forceparameter (tidak disarankan jika Anda tidak melakukannya rebase). Jika masih tidak berfungsi, Anda perlu mengatur receive.denyCurrentBranchke ignorejarak jauh seperti yang disarankan oleh pesan git melalui:

git config receive.denyCurrentBranch ignore
kenorb
sumber
3

Mungkin repo jarak jauh Anda ada di cabang yang ingin Anda dorong. Anda dapat mencoba checkout cabang lain di mesin jarak jauh Anda. Saya melakukan ini, daripada kesalahan ini hilang, dan saya mendorong kesuksesan ke repo jarak jauh saya. Perhatikan bahwa saya menggunakan ssh untuk menghubungkan server saya sendiri dan bukan github.com.

JZAU
sumber
1

Saya memiliki kesalahan ini karena repo git (secara tidak sengaja) diinisialisasi dua kali di lokasi yang sama: pertama sebagai repo non-telanjang dan segera setelah sebagai repo telanjang. Karena folder .git tetap, git menganggap repositori itu tidak kosong. Menghapus folder .git dan data direktori kerja menyelesaikan masalah.

xastor
sumber
1
Dalam situasi saya, inilah masalahnya. Menghapus .gitfolder pada remote memungkinkan saya untuk menekan komit awal.
tim.rohrer
0

Saya mendapatkan kesalahan ini ketika saya bermain-main saat membaca progit. Saya membuat repositori lokal, lalu mengambilnya dalam repo lain pada sistem file yang sama, melakukan pengeditan dan mencoba mendorong. Setelah membaca jawaban NowhereMan, perbaikan cepat adalah pergi ke direktori "remote" dan sementara memeriksa komit lain, mendorong dari direktori saya membuat perubahan, kemudian kembali dan meletakkan kembali kepala pada master.

Nathan Chappell
sumber