" cabang pelacakan jarak jauh lokal ". Pada dasarnya berarti remote harus terlihat seperti apa yang diharapkan klien Anda. git help pushmemiliki use-case yang menjelaskan tujuannya (pada dasarnya untuk menjaga Anda agar tidak merusak perubahan yang baru saja seseorang dorong). Apa yang sedikit tidak jelas bagi saya adalah cara kerja cabang pelacakan jarak jauh. Tapi mungkin itu perlu terlihat persis seperti apa yang terlihat terakhir kali Anda melakukan fetchatau pulltanpa komitmen baru.
zzxyz
4
@zzxyz: implementasi aktualnya --force-with-leasemirip dengan instruksi compare-and-swap pada CPU modern: orang yang menginginkan swap terjadi memasok nilai yang diharapkan dan nilai baru. Sistem yang melakukan swap membandingkan nilai yang diharapkan dengan nilai aktual saat ini, dan melakukan swap jika dan hanya jika keduanya sama. Dengan git push, nilai yang diharapkan adalah apa pun yang ada dalam nama pelacakan jarak jauh, misalnya, git push --force-with-lease origin Xmengirimkan nilai Anda sendiri origin/Xbersama dengan nilai yang diinginkan baru; originGit memberi tahu Anda apakah itu pertukaran, atau tidak.
torek
1
Jika Git di originmelakukan pertukaran, Anda selesai. Jika tidak, Anda dapat berlari git fetch originuntuk mengambil nilai saat ini yang baru , mengolah kembali perubahan Anda jika perlu, dan menjalankan pembandingan dan pertukaran swap-paksa dengan yang lain untuk mencoba lagi.
torek
Jawaban:
173
force menimpa cabang jauh dengan cabang lokal Anda.
--force-with-leaseadalah pilihan yang lebih aman yang tidak akan menimpa pekerjaan apa pun di cabang jarak jauh jika lebih banyak komitmen ditambahkan ke cabang jarak jauh (oleh anggota tim atau rekan kerja lain atau apa pun yang Anda miliki). Ini memastikan Anda tidak menimpa orang lain bekerja dengan paksa mendorong.
Saya pikir ide umum Anda seputar perintah itu benar. Jika cabang jarak jauh memiliki nilai yang sama dengan cabang jarak jauh pada mesin lokal Anda - Anda akan menimpa jarak jauh. Jika tidak memiliki nilai yang sama - ini menunjukkan perubahan yang dilakukan orang lain ke cabang jarak jauh saat Anda sedang mengerjakan kode Anda dan dengan demikian tidak akan menimpa kode apa pun. Jelas jika ada komit tambahan di jarak jauh maka nilainya tidak akan sama.
Saya hanya menganggap --force-with-leasesebagai opsi untuk digunakan ketika saya ingin memastikan saya tidak menimpa kode rekan tim. Banyak tim di perusahaan saya menggunakan --force-with-leasesebagai opsi default untuk gagal-aman. Ini tidak perlu dalam kebanyakan situasi tetapi akan menyelamatkan Anda dari banyak sakit kepala jika Anda menimpa sesuatu yang orang lain berikan pada remote.
Saya yakin Anda melihat dokumen tetapi mungkin ada beberapa penjelasan bertele-tele yang terkandung di sini:
yang terakhir hanya mendorong ke remote jika remote tidak memiliki komitmen yang tidak dimiliki cabang lokal?
Fitur itu diperkenalkan di komit ini (Desember 2013, Git v1.8.5-rc0)
--force-with-lease akan melindungi semua referensi jarak jauh yang akan diperbarui dengan mengharuskan nilainya saat ini sama dengan beberapa standar wajar, kecuali ditentukan lain;
Untuk saat ini, "beberapa default yang masuk akal" secara tentatif didefinisikan sebagai " nilai cabang pelacakan jarak jauh yang kami miliki untuk referensi jarak jauh yang diperbarui ", dan ini merupakan kesalahan jika kami tidak memiliki cabang pelacakan jarak jauh seperti itu.
Jadi "sewa" berarti:
" force-with-lease": Anda menganggap Anda mengambil sewa pada wasit ketika Anda mengambil untuk memutuskan apa yang seharusnya menjadi sejarah rebased, dan Anda dapat mendorong kembali hanya jika sewa belum rusak.
Sumber masih menyebutkan "cas":
Opsi ini pada awalnya disebut " cas" (untuk "bandingkan dan tukar"), nama yang tidak disukai siapa pun karena terlalu teknis.
Upaya kedua menyebutnya "lockref" (karena secara konseptual seperti mendorong setelah mengambil kunci) tetapi kata "kunci" dibenci karena menyiratkan bahwa ia dapat menolak dorongan oleh orang lain, yang bukan cara opsi ini bekerja.
Putaran ini menyebutnya "paksa-dengan-sewa".
Anda menganggap Anda mengambil sewa pada referensi ketika Anda mengambil untuk memutuskan apa yang seharusnya menjadi sejarah rebased, dan Anda dapat mendorong kembali hanya jika sewa belum rusak.
Jadi: " git push --force-with-leasevs. --force"
Seperti yang saya sebutkan di " push --force-with-leasesecara default ", seperti Git 2.13 (Q2 2017) menyebutkan, bahwa opsi --force-with-leasedapat diabaikan jika proses latar belakang (seperti yang Anda temukan dalam IDE dengan plugin Git) berjalan git fetch origin.
Dalam hal itu, --forcemenang.
git push --force merusak karena tanpa syarat menimpa repositori jarak jauh dengan apa pun yang dimiliki secara lokal. push git --force sangat tidak dianjurkan karena dapat menghancurkan commit lain yang sudah didorong ke repositori bersama. Salah satu penyebab kekuatan yang paling umum adalah ketika kita dipaksa untuk rebase cabang.
Sebagai contoh. Kami memiliki proyek dengan cabang fitur yang akan dikerjakan oleh Alice dan Bob. Mereka berdua mengkloning repositori ini dan mulai bekerja. Alice awalnya menyelesaikan bagiannya dari fitur, dan mendorongnya ke repositori utama. Ini semua baik dan bagus. Bob juga menyelesaikan pekerjaannya, tetapi sebelum mendorongnya ia memperhatikan beberapa perubahan telah digabung menjadi master. Ingin menjaga pohon yang bersih, ia melakukan rebase terhadap cabang utama. Tentu saja, ketika dia pergi untuk mendorong cabang rebased ini akan ditolak. Namun tidak menyadari bahwa Alice telah mendorong pekerjaannya, dia melakukan push - force. Sayangnya, ini akan menghapus semua catatan perubahan Alice di repositori pusat.
Apa - Force-with-lease tidak menolak untuk memperbarui cabang kecuali itu adalah keadaan yang kita harapkan; yaitu tidak ada yang memperbarui cabang hulu. Dalam praktiknya ini bekerja dengan memeriksa bahwa ref hulu adalah apa yang kita harapkan, karena ref adalah hash, dan secara implisit menyandikan rantai orang tua ke dalam nilainya.
Berikut ini adalah pos yang bagus mengenai git push --force dan git push --force-with-leasing.
apa yang saya tidak mengerti - jika Anda rebase dengan tuan, maka Anda harus bisa mendorong tanpa--force-with-lease ? Mengapa --force-with-leaseperlu setelah rebasing dengan master?
Alexander Mills
3
@AlexanderMills mungkin ada beberapa kemungkinan yang menyebabkan masalah. Jika Anda adalah orang terakhir yang mendorong ini untuk dikuasai maka tidak ada masalah tetapi ada orang lain yang bekerja dengan tugas lain maka itu dapat menyebabkan masalah serius. Katakan pada awalnya A - B - C adalah master, Pada awalnya Alice membuatnya A - B - C - D - E dan saat yang sama Bob membuatnya A - B - C - F - G. Jika Alice adalah orang terakhir yang mendorong master setelah rebasing A - B - C - D - E - F - G tidak akan menyebabkan masalah tetapi orang lain Tom mencoba untuk mendorong A - B - C - D - E - R pada saat yang sama dalam master bencana akan terjadi !! !
Shakil
3
--forcetidak kehilangan komitmen, itu hanya melepaskan mereka. Mereka dapat dibangkitkan dengan hash mereka, seperti dalam git checkout <SHA>atau git reset --hard <SHA>, dengan asumsi pemilik repo jarak jauh tidak melakukan GC atau operasi pemangkasan.
Keith Russell
1
"Dorongan push --force sangat tidak dianjurkan karena dapat menghancurkan commit lain yang sudah didorong ke repositori bersama" pernyataan ini sangat berdasarkan opini. Melakukan push paksa adalah bagian dari alur kerja tinjauan kode git rebase yang normal. Juga seperti disebutkan sudah Anda dapat mengambil komit bahkan setelah melakukan ini.
Étienne
9
Dengan asumsi kait pra-terima di server menerima dorongan, ini akan selalu berhasil:
git push --force
Sedangkan ini menjalankan pemeriksaan sisi klien tertentu sebelum melanjutkan:
git push --force-with-lease
Anda dapat menjalankan pemeriksaan spesifik sendiri secara manual. Inilah algoritma "pemeriksaan-sewa":
Cari tahu cabang Anda saat ini.
Lari git for-each-ref refs/remotes. Perhatikan komit-id yang menurut git Anda sesuai dengan kondisi hulu dari cabang Anda saat ini.
Misalnya, jika Anda menggunakan "foo" cabang, catat kom-id yang terkait dengan "ref / remote / origin / foo".
Tentukan komit aktual dari cabang jarak jauh pada server upstream git sekarang.
Biarkan "git push" berjalan jika komit yang Anda ekstrak dari langkah 2 dan langkah 3 setuju. Dengan kata lain, hanya lanjutkan jika gagasan kloning git lokal Anda tentang hulu setuju dengan hulu yang sebenarnya.
Ada implikasi yang menyedihkan di sini: karena git fetchmemperbarui semua referensi di bawah "ref / remote / origin / *" ke versi terbaru mereka, kombinasi perintah ini pada dasarnya identik dengan git push --force:
git fetch
# The command below behaves identically to "git push --force"
# if a "git fetch" just happened!
git push --force-with-lease
Untuk mengatasi kelemahan bawaan ini, git push --force-with-leasesaya mencoba untuk tidak pernah berlari git fetch. Alih-alih, saya selalu menjalankan git pull --rebasesetiap kali saya perlu menyinkronkan dengan hulu, karena git pullhanya memperbarui satu ref di bawah ref / remote, menjaga "sewa" --force-with-leaseberguna.
jika ceknya adalah sisi klien, apakah ada potensi untuk kondisi balapan? yaitu orang lain mendorong perubahan setelah cek tetapi sebelum dorongan paksa?
craq
2
Paksaan-dengan-sewa belum tentu aman. Ini hanya berfungsi seperti yang dikatakan Sylvie. Satu catatan: Dalam git, sebuah cabang hanyalah sebuah pointer pada sebuah commit. Dan komit menunjuk ke nol atau lebih komit induk. Bahkan jika Anda mengubah cabang sepenuhnya dengan reset git keras dan dorongan paksa atau dorongan dengan - - paksa-dengan-sewa tanpa menginginkannya, itu belum tentu masalah besar. Anda dapat menggunakan reflog git lokal Anda untuk melihat bagaimana tip lokal Anda pada cabang (Di mana KEPALA saat itu?) Telah berubah dan mengatur ulang dan mendorong cabang lagi. Maka Anda hanya kehilangan komit baru di cabang terpencil, tetapi bahkan itu dapat dipulihkan oleh anggota tim.
git help push
memiliki use-case yang menjelaskan tujuannya (pada dasarnya untuk menjaga Anda agar tidak merusak perubahan yang baru saja seseorang dorong). Apa yang sedikit tidak jelas bagi saya adalah cara kerja cabang pelacakan jarak jauh. Tapi mungkin itu perlu terlihat persis seperti apa yang terlihat terakhir kali Anda melakukanfetch
ataupull
tanpa komitmen baru.--force-with-lease
mirip dengan instruksi compare-and-swap pada CPU modern: orang yang menginginkan swap terjadi memasok nilai yang diharapkan dan nilai baru. Sistem yang melakukan swap membandingkan nilai yang diharapkan dengan nilai aktual saat ini, dan melakukan swap jika dan hanya jika keduanya sama. Dengangit push
, nilai yang diharapkan adalah apa pun yang ada dalam nama pelacakan jarak jauh, misalnya,git push --force-with-lease origin X
mengirimkan nilai Anda sendiriorigin/X
bersama dengan nilai yang diinginkan baru;origin
Git memberi tahu Anda apakah itu pertukaran, atau tidak.origin
melakukan pertukaran, Anda selesai. Jika tidak, Anda dapat berlarigit fetch origin
untuk mengambil nilai saat ini yang baru , mengolah kembali perubahan Anda jika perlu, dan menjalankan pembandingan dan pertukaran swap-paksa dengan yang lain untuk mencoba lagi.Jawaban:
force
menimpa cabang jauh dengan cabang lokal Anda.--force-with-lease
adalah pilihan yang lebih aman yang tidak akan menimpa pekerjaan apa pun di cabang jarak jauh jika lebih banyak komitmen ditambahkan ke cabang jarak jauh (oleh anggota tim atau rekan kerja lain atau apa pun yang Anda miliki). Ini memastikan Anda tidak menimpa orang lain bekerja dengan paksa mendorong.Saya pikir ide umum Anda seputar perintah itu benar. Jika cabang jarak jauh memiliki nilai yang sama dengan cabang jarak jauh pada mesin lokal Anda - Anda akan menimpa jarak jauh. Jika tidak memiliki nilai yang sama - ini menunjukkan perubahan yang dilakukan orang lain ke cabang jarak jauh saat Anda sedang mengerjakan kode Anda dan dengan demikian tidak akan menimpa kode apa pun. Jelas jika ada komit tambahan di jarak jauh maka nilainya tidak akan sama.
Saya hanya menganggap
--force-with-lease
sebagai opsi untuk digunakan ketika saya ingin memastikan saya tidak menimpa kode rekan tim. Banyak tim di perusahaan saya menggunakan--force-with-lease
sebagai opsi default untuk gagal-aman. Ini tidak perlu dalam kebanyakan situasi tetapi akan menyelamatkan Anda dari banyak sakit kepala jika Anda menimpa sesuatu yang orang lain berikan pada remote.Saya yakin Anda melihat dokumen tetapi mungkin ada beberapa penjelasan bertele-tele yang terkandung di sini:
https://git-scm.com/docs/git-push
sumber
"Bandingkan dan tukar" yang disebutkan oleh torek dalam komentar dan jawaban lainnya diilustrasikan lebih lanjut oleh sumber - sumber Git itu sendiri .
Fitur itu diperkenalkan di komit ini (Desember 2013, Git v1.8.5-rc0)
Jadi "sewa" berarti:
Sumber masih menyebutkan "cas":
Jadi: "
git push --force-with-lease
vs.--force
"Seperti yang saya sebutkan di "
push --force-with-lease
secara default ", seperti Git 2.13 (Q2 2017) menyebutkan, bahwa opsi--force-with-lease
dapat diabaikan jika proses latar belakang (seperti yang Anda temukan dalam IDE dengan plugin Git) berjalangit fetch origin
.Dalam hal itu,
--force
menang.sumber
git push --force merusak karena tanpa syarat menimpa repositori jarak jauh dengan apa pun yang dimiliki secara lokal. push git --force sangat tidak dianjurkan karena dapat menghancurkan commit lain yang sudah didorong ke repositori bersama. Salah satu penyebab kekuatan yang paling umum adalah ketika kita dipaksa untuk rebase cabang.
Sebagai contoh. Kami memiliki proyek dengan cabang fitur yang akan dikerjakan oleh Alice dan Bob. Mereka berdua mengkloning repositori ini dan mulai bekerja. Alice awalnya menyelesaikan bagiannya dari fitur, dan mendorongnya ke repositori utama. Ini semua baik dan bagus. Bob juga menyelesaikan pekerjaannya, tetapi sebelum mendorongnya ia memperhatikan beberapa perubahan telah digabung menjadi master. Ingin menjaga pohon yang bersih, ia melakukan rebase terhadap cabang utama. Tentu saja, ketika dia pergi untuk mendorong cabang rebased ini akan ditolak. Namun tidak menyadari bahwa Alice telah mendorong pekerjaannya, dia melakukan push - force. Sayangnya, ini akan menghapus semua catatan perubahan Alice di repositori pusat.
Apa - Force-with-lease tidak menolak untuk memperbarui cabang kecuali itu adalah keadaan yang kita harapkan; yaitu tidak ada yang memperbarui cabang hulu. Dalam praktiknya ini bekerja dengan memeriksa bahwa ref hulu adalah apa yang kita harapkan, karena ref adalah hash, dan secara implisit menyandikan rantai orang tua ke dalam nilainya.
Berikut ini adalah pos yang bagus mengenai git push --force dan git push --force-with-leasing.
sumber
--force-with-lease
? Mengapa--force-with-lease
perlu setelah rebasing dengan master?--force
tidak kehilangan komitmen, itu hanya melepaskan mereka. Mereka dapat dibangkitkan dengan hash mereka, seperti dalamgit checkout <SHA>
ataugit reset --hard <SHA>
, dengan asumsi pemilik repo jarak jauh tidak melakukan GC atau operasi pemangkasan.Dengan asumsi kait pra-terima di server menerima dorongan, ini akan selalu berhasil:
Sedangkan ini menjalankan pemeriksaan sisi klien tertentu sebelum melanjutkan:
Anda dapat menjalankan pemeriksaan spesifik sendiri secara manual. Inilah algoritma "pemeriksaan-sewa":
Cari tahu cabang Anda saat ini.
Lari
git for-each-ref refs/remotes
. Perhatikan komit-id yang menurut git Anda sesuai dengan kondisi hulu dari cabang Anda saat ini.Misalnya, jika Anda menggunakan "foo" cabang, catat kom-id yang terkait dengan "ref / remote / origin / foo".
Tentukan komit aktual dari cabang jarak jauh pada server upstream git sekarang.
Biarkan "git push" berjalan jika komit yang Anda ekstrak dari langkah 2 dan langkah 3 setuju. Dengan kata lain, hanya lanjutkan jika gagasan kloning git lokal Anda tentang hulu setuju dengan hulu yang sebenarnya.
Ada implikasi yang menyedihkan di sini: karena
git fetch
memperbarui semua referensi di bawah "ref / remote / origin / *" ke versi terbaru mereka, kombinasi perintah ini pada dasarnya identik dengangit push --force
:Untuk mengatasi kelemahan bawaan ini,
git push --force-with-lease
saya mencoba untuk tidak pernah berlarigit fetch
. Alih-alih, saya selalu menjalankangit pull --rebase
setiap kali saya perlu menyinkronkan dengan hulu, karenagit pull
hanya memperbarui satu ref di bawah ref / remote, menjaga "sewa"--force-with-lease
berguna.sumber
Paksaan-dengan-sewa belum tentu aman. Ini hanya berfungsi seperti yang dikatakan Sylvie. Satu catatan: Dalam git, sebuah cabang hanyalah sebuah pointer pada sebuah commit. Dan komit menunjuk ke nol atau lebih komit induk. Bahkan jika Anda mengubah cabang sepenuhnya dengan reset git keras dan dorongan paksa atau dorongan dengan - - paksa-dengan-sewa tanpa menginginkannya, itu belum tentu masalah besar. Anda dapat menggunakan reflog git lokal Anda untuk melihat bagaimana tip lokal Anda pada cabang (Di mana KEPALA saat itu?) Telah berubah dan mengatur ulang dan mendorong cabang lagi. Maka Anda hanya kehilangan komit baru di cabang terpencil, tetapi bahkan itu dapat dipulihkan oleh anggota tim.
sumber