Kemarin, saya memposting sebuah pertanyaan tentang bagaimana untuk mengkloning Git repositori dari satu mesin ke yang lain, Bagaimana saya bisa 'git clone' dari mesin lain?.
Saya sekarang dapat berhasil clone Git repositori dari sumber saya (192.168.1.2) ke tujuan (192.168.1.1).
Tapi ketika saya lakukan edit file, git commit-a-m "test"
dan git push
, saya mendapatkan error ini pada saya tujuan (192.168.1.1):
git push
[email protected]'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://[email protected]/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://[email protected]/media/LINUXDATA/working'
I'm menggunakan dua versi yang berbeda dari Git (1.7 pada remote dan 1.5 di mesin lokal). Itu mungkin alasannya?
Anda hanya dapat mengkonversi remote repositori untuk bare repository (tidak ada kerja copy di bare repository - folder yang berisi hanya yang sebenarnya repositori data).
Jalankan perintah berikut di repositori remote folder:
git config --bool core.bare true
Kemudian hapus semua file kecuali .git
di folder itu. Dan kemudian anda akan dapat untuk melakukan git push
ke remote repository tanpa kesalahan.
Aku hanya punya kesalahan yang sama ketika saya mulai belajar Git. Beberapa jawaban yang lain yang jelas bukan untuk seseorang yang baru untuk Git!
(Saya akan menggunakan non teknis persyaratan untuk mendapatkan ide.) Pokoknya, apa yang terjadi adalah bahwa anda memiliki dua repositori, salah satunya adalah asli anda pertama kali dibuat, dan yang lainnya satu pekerjaan yang baru saja anda buat.
Sekarang anda berada di anda bekerja repositori dan menggunakan "master" cabang. Tapi kau juga terjadi untuk menjadi "masuk" di repositori yang sama "master" cabang. Sekarang karena anda're "masuk" dalam bahasa aslinya, Git ketakutan anda mungkin berantakan karena anda mungkin bekerja pada asli dan mengacaukan segalanya. Jadi, anda perlu untuk kembali ke asli repositori dan melakukan "git checkout someotherbranch", dan sekarang anda dapat menekan dengan tidak ada masalah.
Saya harap ini membantu.
Kesalahan pesan yang menjelaskan apa yang telah terjadi. Versi yang lebih modern dari Git menolak untuk memperbarui cabang melalui push jika cabang yang memeriksa.
Cara termudah untuk bekerja di antara dua non-telanjang repositori adalah baik untuk
selalu update repositori dengan menarik (atau mengambil dan menggabungkan) atau, jika anda harus,
dengan mendorong ke cabang yang terpisah (impor cabang) dan kemudian menggabungkan cabang ke cabang utama pada mesin remote.
Alasan pembatasan ini adalah bahwa push operasi hanya beroperasi pada remote repositori Git, itu doesn't memiliki akses ke indeks dan bekerja pohon. Jadi, jika diizinkan, yang mendorong pada check-out cabang akan mengubah KEPALA
untuk menjadi tidak konsisten dengan telunjuk dan bekerja pohon pada remote repository.
Ini akan membuatnya sangat mudah untuk sengaja melakukan perubahan yang membatalkan semua mendorong perubahan dan juga membuatnya sangat sulit untuk membedakan antara perubahan lokal yang belum dilakukan dan perbedaan antara new KEPALA
, indeks dan bekerja pohon yang telah disebabkan oleh push bergerak KEPALA
.
Anda tidak bisa mendorong ke satu memeriksa cabang dari repositori karena akan main-main dengan pengguna dari repositori tersebut dengan cara yang kemungkinan besar akan berakhir dengan hilangnya data dan sejarah. Tapi anda dapat mendorong untuk cabang lain dari repositori yang sama.
Sebagai bare repository pernah punya cabang memeriksa, anda dapat selalu mendorong untuk setiap cabang telanjang repositori.
Ada beberapa solusi, tergantung pada kebutuhan anda.
Seperti yang disarankan, jika pada salah satu mesin, anda don't perlu bekerja direktori, anda dapat pindah ke bare repository. Untuk menghindari main dengan repositori, anda hanya bisa clone:
machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo
Sekarang anda dapat mendorong semua yang anda inginkan ke alamat yang sama seperti sebelumnya.
Tapi jika anda perlu untuk memeriksa kode pada remote <remote>
, maka anda dapat menggunakan sebuah cabang khusus untuk mendorong. Let's mengatakan bahwa di repositori lokal anda telah disebut remote asal
dan're pada branch master. Kemudian anda bisa melakukan
machine2$ git push origin master:master+machine2
Kemudian anda perlu untuk menggabungkan itu bila anda're dalam asal
remote repo:
machine1$ git merge master+machine2
Ketika sebuah cabang memeriksa, melakukan akan menambahkan baru komit dengan arus cabang's kepala sebagai induknya dan bergerak cabang's kepala untuk menjadi yang baru dilakukannya.
Jadi
A ← B
↑
[HEAD,branch1]
menjadi
A ← B ← C
↑
[HEAD,branch1]
Tapi jika seseorang bisa mendorong untuk yang cabang peralihan, pengguna akan mendapatkan dirinya dalam apa git panggilan terpisah kepala mode:
A ← B ← X
↑ ↑
[HEAD] [branch1]
Sekarang pengguna tidak di branch1 lagi, tanpa harus secara eksplisit diminta untuk memeriksa cabang lain. Lebih buruk lagi, pengguna sekarang di luar setiap cabang, dan baru melakukan hanya akan menjadi menjuntai:
[HEAD]
↓
C
↙
A ← B ← X
↑
[branch1]
Secara hipotesis, jika pada titik ini, pengguna memeriksa cabang lain, maka ini menggantung berkomitmen menjadi permainan yang adil untuk Git's garbage collector.
Anda bisa mendapatkan sekitar ini "batasan" dengan mengedit .git/config
pada server tujuan. Tambahkan kode berikut untuk memungkinkan sebuah repositori git yang akan didorong untuk bahkan jika itu adalah "memeriksa":
[receive]
denyCurrentBranch = warn
atau
[receive]
denyCurrentBranch = false
Yang pertama akan memungkinkan push sementara peringatan dari kemungkinan untuk mengacaukan cabang, sedangkan yang kedua hanya akan diam-diam membiarkan hal itu.
Hal ini dapat digunakan untuk "menggunakan" kode untuk server yang tidak dimaksudkan untuk mengedit. Ini bukan pendekatan yang terbaik, tapi salah satu yang cepat untuk menyebarkan kode.
git config --lokal menerima.denyCurrentBranch updateInstead
https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
Gunakan pada server repositori, dan juga update tree kerja jika tidak terpantau menimpa akan terjadi.
Ia menambahkan dalam Git 2.3 sebagai yang disebutkan oleh VonC di komentar.
I've disusun Git 2.3 dan memberikan it a try. Contoh penggunaan:
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
Output:
a
b
Yay, b
harus didorong!
Saya suka ide dari masih memiliki repositori yang dapat digunakan pada remote kotak, tapi bukannya dummy cabang, saya menggunakan:
git checkout --detach
Hal ini tampaknya menjadi fitur yang sangat baru dari Git - I'm menggunakan git versi 1.7.7.4.
Saya memiliki masalah yang sama. Bagi saya, saya menggunakan Git push untuk memindahkan kode ke server saya. Saya tidak pernah mengubah kode di sisi server, jadi ini lebih aman.
Dalam repositori, anda mendorong untuk type:
git config receive.denyCurrentBranch ignore
Ini akan memungkinkan anda untuk mengubah repository sementara itu's kerja copy.
Setelah anda menjalankan Git push, pergi ke mesin remote dan jenis ini:
git checkout -f
Ini akan membuat perubahan yang anda mendorong akan tercermin dalam kerja copy dari remote mesin.
Harap dicatat, ini isn't selalu aman jika anda membuat perubahan di dalam kerja copy yang anda're mendorong untuk.
Apa yang mungkin anda lakukan untuk menyebabkan ini:
Hal semacam ini sering terjadi ketika anda pergi ke bang keluar sedikit program. Anda're tentang untuk mengubah sesuatu yang sudah bekerja, jadi anda melemparkan anda tingkat-3 mantra abadi undoability:
machine1:~/proj1> git init
dan anda mulai menambahkan/melakukan. Tapi kemudian, proyek ini mulai mendapatkan lebih terlibat dan anda ingin bekerja dari komputer lain (seperti rumah anda PC atau laptop), jadi anda melakukan sesuatu seperti
machine2:~> git clone ssh://machine1/~/proj1
dan itu klon dan semuanya terlihat baik, dan anda bekerja pada kode anda dari machine2.
Kemudian... anda mencoba untuk mendorong anda melakukan dari machine2, dan anda mendapatkan pesan peringatan dalam judul.
Alasan untuk ini pesan ini karena git repo anda ditarik dari agak dimaksudkan untuk digunakan hanya untuk folder yang di machine1. Anda dapat clone dari itu baik-baik saja, tapi mendorong dapat menyebabkan masalah. "tepat" cara untuk menjadi managing kode di dua lokasi yang berbeda adalah dengan "telanjang" repo, seperti yang telah disarankan. Telanjang repo isn't dirancang untuk memiliki pekerjaan yang sedang dilakukan di itu, hal ini dimaksudkan untuk mengkoordinasikan komit dari berbagai sumber. Ini adalah mengapa teratas menjawab menunjukkan menghapus semua file/folder lain .git folder setelah anda git config --bool core.telanjang kenyataan
.
Menjelaskan top-rated menjawab: Banyak komentar yang menjawab mengatakan sesuatu seperti "aku't menghapus non-.git file dari machine1 dan aku masih mampu untuk melakukan dari machine2". Yang's benar. Namun, orang-file lain yang benar-benar "bercerai" dari git repo, sekarang. Pergi mencoba git status
di sana dan anda harus melihat sesuatu seperti "fatal: Ini operasi yang harus berjalan dalam bekerja pohon". Jadi, saran untuk menghapus file isn't sehingga komit dari machine2 akan kerja; it's sehingga anda don't mendapatkan bingung dan berpikir bahwa git masih melacak file-file tersebut. Tapi, menghapus file adalah sebuah masalah jika anda masih ingin bekerja pada file pada 1, isn't itu?
Jadi, apa yang harus anda lakukan?
Tergantung pada seberapa banyak anda berencana untuk tetap bekerja di machine1 dan machine2...
Jika anda're dilakukan pengembangan dari machine1 dan telah pindah semua dari anda untuk pengembangan machine2... hanya melakukan apa yang teratas menjawab menunjukkan: git config --bool core.telanjang sejati
dan kemudian, opsional, menghapus semua file/folder lain .git dari folder itu, karena mereka're terpantau dan akan menimbulkan kebingungan.
Jika anda bekerja pada machine2 hanya satu kali, dan anda don't perlu untuk melanjutkan pembangunan di sana... kemudian don't repot-repot dengan pembuatan telanjang repo; hanya ftp/rsync/scp/etc. file anda dari mesin2 di atas file pada mesin1, komit dorong dari mesin1, dan kemudian menghapus file dari mesin2. Orang lain telah menyarankan untuk membuat cabang, tapi saya berpikir bahwa's sedikit berantakan jika anda hanya ingin menggabungkan beberapa pengembangan yang anda lakukan pada satu waktu dasar dari mesin yang lain.
Jika anda perlu untuk melanjutkan pembangunan di kedua machine1 dan machine2... maka anda perlu untuk mengatur hal-hal dengan benar. Anda perlu mengkonversi repo telanjang, kemudian anda perlu untuk membuat tiruan dari yang di machine1 bagi anda untuk kerja dalam. Mungkin cara tercepat untuk melakukan ini adalah untuk melakukan
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
Penting: karena anda've pindah lokasi repo dari proj1 untuk proj1.git, anda perlu update ini di .git/config pada machine2. Setelah itu, anda dapat melakukan perubahan dari machine2. Terakhir, saya mencoba untuk menjaga saya telanjang repos di lokasi sentral, jauh dari pekerjaan saya pohon (yaitu don't put 'proj1.git' di saat yang sama folder induk sebagai 'proj1'). Saya menyarankan anda untuk melakukan hal yang sama, tapi saya ingin menjaga langkah-langkah di atas sesederhana mungkin.
Dengan beberapa setup langkah-langkah anda dapat dengan mudah menyebarkan perubahan ke situs web anda menggunakan one-liner seperti
git push production
Yang bagus dan sederhana, dan anda don't harus login ke remote server dan melakukan tarik atau apa pun. Catatan bahwa ini akan bekerja terbaik jika anda don't menggunakan produksi checkout sebagai kerja branch! (OP bekerja dalam konteks yang sedikit berbeda, dan saya pikir @Robert Gould's solusi ditangani dengan baik. Solusi ini lebih tepat untuk penyebaran ke remote server.)
Pertama, anda perlu untuk mengatur telanjang repositori di suatu tempat pada server anda, di luar webroot.
mkdir mywebsite.git
cd mywebsite.git
git init --bare
Kemudian buat file kait/pasca-menerima
:
#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f
Dan membuat file executable:
chmod +x hooks/post-receive
Pada mesin lokal anda,
git remote add production [email protected]:mywebsite.git
git push production +master:refs/heads/master
Semua diatur! Sekarang di masa depan, anda dapat menggunakan git push produksi` untuk menerapkan perubahan anda!
Kredit untuk solusi ini berlaku untuk http://sebduggan.com/blog/deploy-your-website-changes-using-git/. Terlihat ada untuk penjelasan yang lebih rinci dari apa yang's terjadi.
git pull; git push
git push origin master:foo
dan bergabung di remote (baik oleh git
atau pull-request)
git merge foo
rebase
):git push origin master -f
Jika masih menolak, menonaktifkan denyCurrentBranch
di remote repositori:
git config menerima.denyCurrentBranch mengabaikan
Aku punya masalah yang sama menggunakan Git untuk mensinkronisasi repositori pada ponsel Android saya dan laptop. Solusi bagi saya adalah untuk melakukan yang menarik bukan push, seperti @CharlesBailey yang disarankan.
git push origin master
pada Android repository gagal untuk saya dengan pesan kesalahan bahwa @hap497 punya karena dorongan untuk nonbare checkout dari repositori + kerja-copy.
git pull droid master
pada laptop repositori dan kerja-copy bekerja untuk saya. Tentu saja, anda harus memiliki sebelumnya menjalankan sesuatu seperti git remote add droid /media/KINGSTON4GB/notes_repo/
.
periksa .git/config
pada tujuan proyek:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[receive]
denyCurrentBranch = updateInstead
Jika inti. telanjang
adalah palsu, anda dapat mengaturnya dengan benar:
$ git config core.bare true
dan kemudian di push ke remote:
git push remote_repo // suppose the destination repo is remote_repo
ini akan sukses, remote_repo anda dapat memeriksa versi git.
$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < [email protected]>
Date: Thu May 17 21:54:37 2018 +0800
dan sekarang anda tidak bisa menggunakan git pada anda "kerja":
$ git status
fatal: This operation must be run in a work tree
anda harus mengatur telanjang.telanjang
kembali ke false.
$ git config core.bare false
Versi Git digunakan untuk memungkinkan mendorong untuk saat ini memeriksa cabang non-bare repository.
Ternyata hal ini sangat membingungkan hal yang memungkinkan. Sehingga mereka menambahkan pesan peringatan yang anda lihat, yang juga sangat membingungkan.
Jika dulu repositori hanya bertindak sebagai server kemudian mengubahnya ke bare repository sebagai jawaban yang lain merekomendasikan dan dilakukan dengan hal itu.
Namun jika anda perlu untuk memiliki bersama cabang antara dua repos yang baik di gunakan anda dapat mencapai itu dengan setup berikut
Repo1 - akan bertindak sebagai server dan juga dapat digunakan untuk pengembangan
Repo2 - akan untuk pengembangan hanya
Setup Repo1 sebagai berikut
Membuat cabang untuk berbagi pekerjaan.
git branch shared_branch
Untuk amannya, anda juga harus membuat $(REPO).git/kait/update yang menolak setiap perubahan apa-apa selain shared_branch, karena anda don't ingin orang-orang mucking dengan pribadi anda cabang-cabang.
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
Sekarang buat sebuah cabang lokal di repo1 di mana anda akan melakukan pekerjaan yang sebenarnya.
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'
(mungkin perlu untuk git config --global mendorong.default hulu
dalam rangka untuk git push
untuk bekerja)
Sekarang anda dapat membuat repo2 dengan
git clone path/to/repo1 repo2
git checkout shared_branch
Pada titik ini anda memiliki kedua repo1 dan repo2 setup untuk bekerja di cabang-cabang lokal yang mendorong dan menarik dari shared_branch
di repo1, tanpa perlu khawatir tentang pesan kesalahan atau memiliki direktori kerja keluar dari sync di repo1. Apapun yang normal alur kerja anda gunakan harus bekerja.
OK, jika anda ingin normal remote repositori, kemudian membuat tambahan cabang dan check it out. Dorong ke salah satu cabang (yang tidak memeriksa) dan bergabung dengan salah satu yang sedang aktif kemudian setelah mendorong dari lokal.
Misalnya, pada remote server:
git branch dev
git checkout dev
Di daerah setup:
git push
Pada remote server:
git merge dev
Berikut adalah salah satu tes yang dapat anda lakukan untuk melihat bagaimana telanjang
server bekerja hal:
Bayangkan anda memiliki sebuah workstation dan server dengan situs di-host di atasnya, dan anda ingin memperbarui situs ini dari waktu ke waktu (ini juga berlaku untuk situasi di mana dua pengembang yang mengirim mereka bekerja bolak-balik melalui telanjang perantara).
Membuat beberapa direktori pada komputer lokal anda dan cd
ke dalamnya, kemudian jalankan perintah ini:
# initialization
git init --bare server/.git
git clone server content
git clone server local
server
direktori (perhatikan .git di akhir). Direktori ini akan berfungsi sebagai wadah untuk penyimpanan file saja.konten
direktori. Ini adalah hidup anda/produksi direktori yang akan dilayani oleh perangkat lunak server anda.Sekarang di sini adalah dasar alur kerja:
lokal
direktori, membuat beberapa file dan melakukan mereka. Akhirnya mendorong mereka untuk server:git commit-av git push origin master
konten
direktori dan update server's konten:git pull
konten
mungkin pengembang lain yang dapat mendorong ke server juga, dan lokal
seperti yang anda tarik dari dia.Aku harus kembali menjalankan git --initdi yang ada bare repository, dan ini telah menciptakan
.gitdi dalam direktori telanjang repositori pohon - saya menyadari bahwa setelah mengetik
git status` di sana. Saya dihapus itu dan semuanya baik-baik lagi :)
(Ini jawaban yang bagus, tapi dalam kasus saya itu adalah sesuatu yang sama sekali berbeda (sejauh yang saya bisa melihat), seperti yang dijelaskan.)