Paksa "git push" untuk menimpa file jarak jauh

768

Saya ingin mendorong file lokal saya, dan memilikinya pada repo jarak jauh, tanpa harus berurusan dengan konflik penggabungan. Saya hanya ingin versi lokal saya memiliki prioritas di atas yang jauh.

Bagaimana saya bisa melakukan ini dengan Git?

opensas
sumber
106
Tidak git push origin --forceberhasil untukmu?
3
kemungkinan duplikat
Mengganti
Tidak jelas apakah Anda hanya ingin mengganti file .git, atau copy pekerjaan yang terkait. Jika repositori git, push git adalah jawabannya. Jika Anda ingin memperbarui copy pekerjaan jarak jauh, Anda harus menggunakan hook pasca-terima
Pierre-Olivier Vares
@ Mike yang bekerja untuk saya untuk beberapa alasan ... bertanya-tanya apa yang terjadi dengan OP
Kemungkinan penyebabnya, push force tidak berfungsi adalah, bahwa itu mungkin telah secara eksplisit dinonaktifkan pada repo jarak jauh (untuk memastikan tidak ada yang hilang karena kontributor bodoh dan / atau memfitnah): gunakan config receive.denyNonFastforwardsuntuk mencari tahu.
Frank Nocke

Jawaban:

1088

Anda harus dapat memaksa revisi lokal Anda ke repo jarak jauh dengan menggunakan

git push -f <remote> <branch>

(misalnya git push -f origin master). Berangkat <remote>dan <branch>akan memaksa mendorong semua cabang lokal yang telah ditetapkan --set-upstream.

Hanya diperingatkan, jika orang lain membagikan repositori ini, riwayat revisi mereka akan bertentangan dengan yang baru. Dan jika mereka memiliki komitmen lokal setelah titik perubahan mereka akan menjadi tidak valid.

Memperbarui : Saya pikir saya akan menambahkan catatan tambahan. Jika Anda membuat perubahan yang akan ditinjau oleh orang lain, maka tidak jarang membuat cabang dengan perubahan itu dan melakukan rebase secara berkala agar tetap terbarui dengan cabang pengembangan utama. Biarkan pengembang lain tahu ini akan terjadi secara berkala sehingga mereka akan tahu apa yang diharapkan.

Pembaruan 2 : Karena semakin banyaknya pemirsa, saya ingin menambahkan beberapa informasi tambahan tentang apa yang harus dilakukan ketika Anda upstreambenar - benar mengalami tekanan.

Katakanlah saya sudah mengkloning repo Anda dan telah menambahkan beberapa commit seperti:

            D ---- E topik
           /
A ---- B ---- C development

Tetapi kemudian developmentcabang dipukul dengan a rebase, yang akan menyebabkan saya menerima kesalahan seperti ketika saya menjalankan git pull:

Membongkar objek: 100% (3/3), selesai.
Dari <repo-lokasi>
 * pengembangan cabang -> FETCH_HEAD
Penggabungan otomatis <file>
CONFLICT (konten): Gabungkan konflik di <lokasi>
Penggabungan otomatis gagal; perbaiki konflik dan kemudian hasilkan.

Di sini saya dapat memperbaiki konflik dan commit, tetapi itu akan meninggalkan saya dengan sejarah komit yang benar-benar jelek:

       C ---- D ---- E ---- F topik
      / /
A ---- B -------------- Pengembangan C '

Mungkin terlihat menarik untuk digunakan git pull --forcetetapi berhati-hatilah karena itu akan membuat Anda terlantar:

            D ---- E topik

A ---- B ---- C 'development

Jadi mungkin pilihan terbaik adalah melakukan git pull --rebase. Ini akan mengharuskan saya untuk menyelesaikan konflik seperti sebelumnya, tetapi untuk setiap langkah alih-alih melakukan saya akan menggunakan git rebase --continue. Pada akhirnya histori komit akan terlihat jauh lebih baik:

            Topik D '--- E'
           /
A ---- B ---- C 'development

Pembaruan 3: Anda juga dapat menggunakan --force-with-leaseopsi sebagai dorongan gaya "aman", seperti yang disebutkan oleh Cupcake dalam jawabannya :

Mendorong paksa dengan "sewa" memungkinkan dorongan gaya gagal jika ada komit baru pada kendali jarak jauh yang tidak Anda harapkan (secara teknis, jika Anda belum mengambilnya ke cabang pelacak jarak jauh Anda), yang berguna jika Anda tidak ingin secara tidak sengaja menimpa komitmen orang lain yang bahkan belum Anda ketahui, dan Anda hanya ingin menimpa komitmen Anda sendiri:

git push <remote> <branch> --force-with-lease

Anda dapat mempelajari lebih detail tentang cara menggunakan --force-with-leasedengan membaca salah satu dari yang berikut:

Trevor Norris
sumber
5
Karena ini adalah jawaban yang dipilih, saya akan berkomentar di sini. Menggunakan kekuatan bukanlah masalah saat bekerja sendiri. Sebagai contoh, host cloud saya mulai dengan git itu sendiri. Jika saya bekerja secara lokal dan membangun sebuah proyek, dan saya ingin meletakkannya di cloud host saya (OpenShift), saya memiliki dua proyek git yang terpisah. Lokal dan OpenShift saya. Saya mendapatkan lokal saya sesuka saya, tetapi sekarang ingin mempratinjau di OpenShift saya. Anda kemudian mendorong ke OpenShift untuk pertama kalinya, menggunakan -fbendera. Pada dasarnya menempatkan git lokal Anda ke OpenShift.
Wade
128

Anda ingin memaksakan dorongan

Apa yang pada dasarnya ingin Anda lakukan adalah memaksa mendorong cabang lokal Anda, untuk menimpa yang jauh.

Jika Anda ingin penjelasan lebih rinci tentang masing-masing perintah berikut, maka lihat bagian detail saya di bawah ini. Pada dasarnya Anda memiliki 4 opsi berbeda untuk memaksa mendorong dengan Git:

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

git push <remote> <branch> --force-with-lease

Jika Anda menginginkan penjelasan yang lebih terperinci untuk setiap perintah, lihat bagian jawaban panjang saya di bawah ini.

Peringatan: memaksa mendorong akan menimpa cabang jarak jauh dengan keadaan cabang yang Anda dorong. Pastikan ini adalah apa yang benar-benar ingin Anda lakukan sebelum menggunakannya, jika tidak, Anda dapat menimpa komitmen yang sebenarnya ingin Anda pertahankan.

Paksa mendorong detail

Menentukan remote dan cabang

Anda dapat sepenuhnya menentukan cabang dan remote tertentu. The -fbendera adalah versi pendek dari--force

git push <remote> <branch> --force
git push <remote> <branch> -f

Menghilangkan cabang

Ketika cabang untuk mendorong cabang dihilangkan, Git akan mencari tahu berdasarkan pengaturan konfigurasi Anda. Dalam versi Git setelah 2.0, repo baru akan memiliki pengaturan default untuk mendorong cabang yang saat ini check-out:

git push <remote> --force

sementara sebelum 2.0, repo baru akan memiliki pengaturan default untuk mendorong beberapa cabang lokal. Pengaturan yang dimaksud adalah pengaturan remote.<remote>.pushdan push.default(lihat di bawah).

Menghilangkan remote dan cabang

Ketika remote dan cabang dihilangkan, perilaku just git push --forceditentukan oleh push.defaultpengaturan konfigurasi Git Anda :

git push --force
  • Pada Git 2.0, pengaturan default simple,, pada dasarnya hanya akan mendorong cabang Anda saat ini ke counter-part jarak jauh hulu. Remote ditentukan oleh pengaturan cabang branch.<remote>.remote, dan default ke repo asal jika sebaliknya.

  • Sebelum Git versi 2.0, pengaturan default matching,, pada dasarnya hanya mendorong semua cabang lokal Anda ke cabang dengan nama yang sama pada remote (yang default ke asal).

Anda dapat membaca lebih banyak push.defaultpengaturan dengan membaca git help configatau versi online dari Halaman Manual git-config (1) .

Paksa mendorong dengan lebih aman --force-with-lease

Mendorong paksa dengan "sewa" memungkinkan dorongan gaya gagal jika ada komit baru pada kendali jarak jauh yang tidak Anda harapkan (secara teknis, jika Anda belum mengambilnya ke cabang pelacak jarak jauh Anda), yang berguna jika Anda tidak ingin secara tidak sengaja menimpa komitmen orang lain yang bahkan belum Anda ketahui, dan Anda hanya ingin menimpa komitmen Anda sendiri:

git push <remote> <branch> --force-with-lease

Anda dapat mempelajari lebih detail tentang cara menggunakan --force-with-leasedengan membaca salah satu dari yang berikut:

Komunitas
sumber
Anda benar, tetapi ini seharusnya hanya digunakan dalam situasi luar biasa .
Scott Berrevoets
1
@ScottBerrevoets " Saya lebih suka mendorong apa yang saya miliki dan membiarkannya menimpa dari jarak jauh daripada mengintegrasikan. " Saya memberikan OP persis apa yang dia minta.
Saya tahu, tetapi OP mungkin tidak menyadari konsekuensi dari melakukan ini. Anda secara teknis menjawab pertanyaan itu, tetapi saya pikir peringatan untuk tidak melakukan ini tidak salah.
Scott Berrevoets
1
@ScottBerrevoets Saya mencoba untuk memiliki moderator menggabungkan jawaban saya ke dalam kanonik, karena saya menyebutkan --force-with-leaseopsi baru;)
1
FYI: digabung dari stackoverflow.com/questions/24768330/…
Shog9
32

Pilihan lain (untuk menghindari dorongan paksa yang dapat menimbulkan masalah bagi kontributor lain) adalah untuk:

  • letakkan komit baru Anda di cabang khusus
  • atur ulang masterpada Andaorigin/master
  • menggabungkan cabang khusus Anda master, selalu menjaga komitmen dari cabang khusus (artinya membuat revisi baru masteryang akan mencerminkan cabang khusus Anda).
    Lihat " perintah git untuk membuat satu cabang seperti yang lain " untuk strategi mensimulasikan a git merge --strategy=theirs.

Dengan begitu, Anda bisa mendorong master ke jarak jauh tanpa harus memaksa apa pun.

VONC
sumber
Bagaimana hasilnya berbeda dari "push-force"?
alexkovelsky
6
@alexkovelsky Setiap dorongan paksa akan menulis ulang sejarah, memaksa pengguna repo lain untuk mereset repo lokal mereka sendiri agar sesuai dengan komitmen yang baru saja didorong. Pendekatan ini hanya menciptakan komitmen baru dan tidak memerlukan dorongan paksa.
VonC
1
Saya sarankan Anda menambahkan tajuk ke jawaban Anda: "Anda tidak ingin memaksakan dorongan" :)
alexkovelsky
@alexkovelsky Poin bagus. Saya telah mengedit jawaban sesuai dengan itu.
VonC
4

git push -f sedikit merusak karena me-reset perubahan jarak jauh yang telah dilakukan oleh orang lain di tim. Opsi yang lebih aman adalah {git push --force-with-leasing}.

Apa yang {--force-with-lease} lakukan adalah menolak untuk memperbarui cabang kecuali jika itu adalah keadaan yang kami 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. Anda dapat memberi tahu {--force-with-lease} apa yang harus diperiksa, tetapi secara default akan memeriksa referensi jarak jauh saat ini. Apa artinya ini dalam praktiknya adalah bahwa ketika Alice memperbarui cabangnya dan mendorongnya ke repositori jarak jauh, kepala penunjuk ref cabang akan diperbarui. Sekarang, kecuali Bob melakukan penarikan dari remote, referensi lokal ke remote akan ketinggalan zaman. Ketika dia pergi untuk mendorong menggunakan {--force-with-lease}, git akan memeriksa referensi lokal terhadap remote baru dan menolak untuk memaksa push. {--force-with-lease} secara efektif hanya memungkinkan Anda untuk mendorong-paksa jika tidak ada orang lain yang mendorong perubahan ke jarak jauh untuk sementara. Ini {--force} dengan sabuk pengaman aktif.

Lando Ke
sumber
3

Bekerja untuk saya:

git push --set-upstream origin master -f
PN Jithish
sumber
0

Langkah-langkah sederhana dengan menggunakan tortoisegit

GIT memberikan file lokal komit dan mendorong ke repositori git.

Langkah :

1) simpanan mengubah nama simpanan

2) tarik

3) simpanan pop

4) komit 1 atau lebih file dan berikan komit set deskripsi set pembuat dan Tanggal

5) mendorong

Nagnath Mungade
sumber