Bagaimana cara memaksa git pull untuk menimpa segalanya pada setiap tarikan?

203

Saya memiliki repositori telanjang TENGAH yang memiliki tiga repositori pengembang menarik dan mendorongnya secara normal.

Saya juga memiliki dua repositori lain yang menarik dari repo telanjang TENGAH: satu adalah server hidup, dan yang lainnya adalah server tes / tahap — masing-masing menarik dari cabang masing-masing.

Skenarionya adalah ini: Saya memiliki post-updateskrip kait pada repo TENGAH yang secara otomatis mengakses tes dan repo langsung dan menjalankan perintah tarik pada masing-masing. Ini memperbarui server uji dan langsung, semua tergantung pada cabang apa yang memiliki komitmen baru. Ini semua bekerja dengan baik.

Masalahnya adalah ini: mungkin ada saat-saat dalam keadaan darurat bahwa file dapat langsung diperbarui di server (melalui ftp atau apa pun) dan skrip post-update TENGAH kemudian akan gagal karena konflik gabungan / timpa akan terjadi. Tidak ada cara untuk menghindari skenario ini, dan itu tidak bisa dihindari.

Yang saya inginkan terjadi adalah ini: Saya ingin tarikan dari situs langsung dan pengujian selalu menimpa / menggabungkan tarikan. Selalu. Repo-repo ini hanya akan menarik karena tidak untuk pengembangan.

Dalam semua penelitian saya, saya tidak dapat menemukan solusi yang baik untuk memiliki daya tarik selalu memaksa menimpa file lokal. Apakah ini mungkin? Itu akan membuat skenario pengembangan yang bagus jika demikian.

bmilesp
sumber
1
Meskipun saya telah memilih jawaban 'reset ke apa yang baru saja Anda ambil' di bawah, saya pikir solusi untuk masalah Anda yang sebenarnya adalah dengan tidak melakukan perubahan out-of-band. Modifikasi, betapa pun mendesaknya, harus selalu melalui kontrol versi. Tidak seorang pun kecuali operator harus memiliki akses langsung ke situs yang sedang berjalan (misalnya bukan pengembang). Menggunakan kontrol versi secara konsisten berarti bahwa Anda memiliki catatan tentang kapan perubahan dilakukan, dan siapa yang membuatnya, dan alat yang lebih baik untuk bekerja dengannya. Mengapa menumbangkannya, tanpa manfaat nyata?
Phil Miller
1
@Novelocrat benar, saya mengerti apa yang Anda katakan. Sayangnya, ada sejumlah skenario di mana seseorang dapat mengunggah file langsung ke server. Dalam hal ini saya perlu menjalankan sejumlah perintah untuk menyinkronkan ulang repo. Sebelumnya kami menggunakan skrip FTP untuk memindahkan file dari repo ke server. Metode yang diusulkan di atas hanya akan menghilangkan langkah FTP, yang telah bekerja sangat baik di masa lalu.
bmilesp
3
Jadi, jangan biarkan orang mengakses server secara langsung. Kunci akses FTP dan SSH, atau beri tahu mereka bahwa mereka akan dipecat karena melakukan perubahan yang tidak bertanggung jawab. Membiarkan latihan semacam itu berlanjut hanya akan menyakiti Anda dan tim Anda dalam jangka panjang.
Phil Miller

Jawaban:

510

Sebenarnya cara ideal untuk melakukan ini adalah tidak menggunakan pullsama sekali, tetapi sebaliknya fetchdan reset:

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df

(Mengubah mastercabang apa pun yang ingin Anda ikuti.)

pulldirancang untuk menggabungkan perubahan bersama dalam beberapa cara, sedangkan resetdirancang sekitar hanya membuat salinan lokal Anda cocok dengan komit tertentu.

Anda mungkin ingin mempertimbangkan opsi yang sedikit berbeda cleantergantung pada kebutuhan sistem Anda.

Amber
sumber
3
@ user730569 reset --hardadalah perintah yang digunakan untuk memaksa keadaan direktori kerja (dan cabang saat ini) ke keadaan yang cocok dengan komit tertentu.
Amber
25
FETCH_HEADadalah referensi yang secara otomatis dibuat oleh fetchuntuk mewakili referensi yang diambil. Itu tidak digabung, hanya langsung ditimpa setiap kali Anda mengambil. cleanadalah perintah yang menghapus file yang tidak dilacak git, -dfflag memerintahkannya untuk menghapus direktori ( -d) dan benar-benar melakukan penghapusan ( -f).
Amber
4
mengapa tidak ada kata kunci untuk ini? Saya membutuhkan ini lebih sering daripada menarik.
Wolfgang Fahl
14
Anda mungkin ingin menggunakan git clean -dnsebelum menggunakan git clean -dfsehingga Anda akan melihat file / folder apa yang akan dihapus. git clean -dfhanya dapat dibalik jika Anda memiliki cadangan
Ibrahim Lawal
1
@NickMiddleweek Saya khawatir git clean -dfakan menghapus file gitignored juga, tetapi ternyata tidak. git clean --helpmengatakan "Biasanya, hanya file yang tidak dikenal ke Git yang dihapus, tetapi jika opsi -x ditentukan, file yang diabaikan juga dihapus. Ini dapat, misalnya, berguna untuk menghapus semua produk build."
nickang
6

Saya tidak yakin bagaimana melakukannya dalam satu perintah tetapi Anda dapat melakukan sesuatu seperti:

git reset --hard
git pull

atau bahkan

git stash
git pull
Matt Wolfe
sumber
Untuk menjalankan dalam satu perintah: git reset --hard && git pull. Atau, tetapi tidak lebih baik git reset --hard; git pull,. Menggunakan &&hanya akan menjalankan perintah kedua jika perintah pertama berhasil. ;akan menjalankannya terlepas dari kode keluar dari perintah pertama.
mazunki
5

Untuk menarik salinan cabang dan memaksa menimpa file lokal dari asal gunakan:

git reset --hard origin/current_branch

Semua pekerjaan saat ini akan hilang dan kemudian akan sama dengan cabang asal

Andrew Atkinson
sumber
5
git reset --hard HEAD
git fetch --all
git reset --hard origin/your_branch
Dzmitry
sumber
2

Anda dapat mengubah pengait untuk membersihkan semuanya.

# Danger! Wipes local data!

# Remove all local changes to tracked files
git reset --hard HEAD

# Remove all untracked files and directories
git clean -dfx

git pull ...
Dietrich Epp
sumber
2
apa yang x lakukan? tolong jelaskan sakelar
Steve K
2
X seharusnya menghapus semua file yang tidak terlacak, saya pikir. Sulit dikatakan dalam bahasa manual, itulah sebabnya kami memiliki SO.
JosephK
2
@ JosephK: Itu tidak benar. Tujuan dasar git cleansudah "Hapus file yang tidak terlacak dari pohon yang berfungsi" (bagian atas halaman). Biasanya, ini tidak termasuk file yang diabaikan, tetapi -xmemberitahu git cleanuntuk memasukkan file yang diabaikan juga (kecuali ini tidak mempengaruhi file yang diabaikan oleh -eopsi).
Dietrich Epp
2

Jika Anda belum melakukan perubahan lokal sejak penarikan / klon terakhir, Anda dapat menggunakan:

git checkout *
git pull

checkoutakan menghapus perubahan lokal Anda dengan komit lokal terakhir, dan pullakan mengautronkannya ke repositori jarak jauh

Maviles
sumber