Bagaimana cara memaksa "git pull" untuk menimpa file lokal?

7190

Bagaimana cara memaksa file lokal ditimpa git pull?

Skenarionya adalah sebagai berikut:

  • Anggota tim memodifikasi templat untuk situs web yang sedang kami kerjakan
  • Mereka menambahkan beberapa gambar ke direktori gambar (tetapi lupa menambahkannya di bawah kendali sumber)
  • Mereka mengirim gambar melalui pos, nanti, ke saya
  • Saya menambahkan gambar di bawah kontrol sumber dan mendorongnya ke GitHub bersama dengan perubahan lainnya
  • Mereka tidak dapat menarik pembaruan dari GitHub karena Git tidak ingin menimpa file mereka.

Ini kesalahan yang saya dapatkan:

kesalahan: File pohon yang tidak dapat dilacak 'publik / images / icon.gif' akan ditimpa oleh gabungan

Bagaimana cara memaksa Git untuk menimpa mereka? Orang tersebut adalah seorang desainer - biasanya, saya menyelesaikan semua konflik dengan tangan, sehingga server memiliki versi terbaru yang hanya perlu mereka perbarui di komputer mereka.

Jakub Troszok
sumber
17
siapa pun yang membaca ini yang berpikir mereka mungkin kehilangan file, saya sudah dalam posisi ini dan menemukan buffer Sublime Text telah menyelamatkan saya - jika saya sedang mengerjakan sesuatu, maka secara tidak sengaja hapus semuanya dengan mencoba memecahkan masalah yang serupa dengan ini atau dengan menggunakan jawaban atas pertanyaan ini dan memiliki file terbuka di Sublime (yang ada kemungkinan bagus) maka file akan tetap ada Sublime, baik di sana, atau dalam sejarah yang dibatalkan
Toni Leigh
64
git reset --hard origin/branch_to_overwrite
Andrew Atkinson
1
pada dasarnya, hanya melakukan pull from develop setelah checkout awal -b. lakukan pekerjaanmu, lalu dorong kembali.
ldgorman
1
Jawaban singkat: hapus dan buat kembali cabang. 1. Hapus cabang: git branch <branch> -D2. Reset ke komit sebelum konflik:git reset <commit> --hard 3. Buat ulang cabang: git branch <branch>4. Atur pelacakan ke server: git --set-upstream-to=origin/<branch> <branch> 5. Pull: git pull`
Nino Filiu
1
Untuk mengubah semua ujung CRLF ke LF, (mulai bersih)git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Chloe

Jawaban:

10043

Penting: Jika Anda memiliki perubahan lokal, itu akan hilang. Dengan atau tanpa --hardopsi, komit lokal apa pun yang tidak didorong akan hilang. [*]

Jika Anda memiliki file apa pun yang tidak dilacak oleh Git (misalnya konten pengguna yang diunggah), file-file ini tidak akan terpengaruh.


Saya pikir ini adalah cara yang benar:

git fetch --all

Kemudian, Anda memiliki dua opsi:

git reset --hard origin/master

ATAU Jika Anda berada di cabang lain:

git reset --hard origin/<branch_name>

Penjelasan:

git fetch mengunduh yang terbaru dari jarak jauh tanpa mencoba menggabungkan atau mengubah apa pun.

Kemudian git resetreset cabang master ke apa yang baru saja Anda ambil. The --hardpilihan perubahan semua file dalam pohon kerja Anda untuk mencocokkan file dalamorigin/master


Pertahankan komitmen lokal saat ini

[*] : Perlu dicatat bahwa dimungkinkan untuk mempertahankan komit lokal saat ini dengan membuat cabang dari mastersebelum mengatur ulang:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

Setelah ini, semua komitmen lama akan disimpan new-branch-to-save-current-commits .

Perubahan tidak dikomit

Namun, perubahan yang tidak dikomit (bahkan dipentaskan), akan hilang. Pastikan untuk menyimpan dan melakukan apa pun yang Anda butuhkan. Untuk itu Anda dapat menjalankan yang berikut ini:

git stash

Dan kemudian menerapkan kembali perubahan yang tidak dikomit ini:

git stash pop
RNA
sumber
14
Awas! Jika Anda memiliki komitmen lokal yang belum dicuci, ini akan menghapusnya dari cabang Anda! Solusi ini membuat file tidak terlacak tidak dalam repositori utuh, tetapi menimpa segalanya.
Matthijs P
479
Ini pertanyaan yang populer, jadi saya ingin mengklarifikasi pada komentar teratas di sini. Saya baru saja menjalankan perintah seperti yang dijelaskan dalam jawaban ini dan belum menghapus SEMUA file lokal. Hanya file yang dilacak dari jarak jauh yang ditimpa, dan setiap file lokal yang ada di sini dibiarkan tidak tersentuh.
Merah
14
dalam kasus Anda menarik dari repo yang memiliki nama cabang jauh berbeda dari "master", gunakangit reset --hard origin/branch-name
Nerrve
97
Mengingat jumlah upvotes untuk pertanyaan dan jawaban ini, saya pikir git harus memasukkan perintah sepertigit pull -f
Sophivorus
7
Komit yang tidak mendorong sebelum hard reset dapat dipulihkan menggunakan git reflog, yang mencantumkan semua komit, juga yang tanpa basis. Sampai Anda membersihkan salinan lokal Anda menggunakan git gc, maka semua hilang
Koen.
936

Coba ini:

git reset --hard HEAD
git pull

Itu harus melakukan apa yang Anda inginkan.

Travis Reeder
sumber
16
Saya sudah melakukan ini dan beberapa file lokal yang tidak lagi di repo dibiarkan di disk.
Piotr Owsiak
26
Saya tidak berpikir ini benar. yang di atas akan melakukan penggabungan, bukan menimpa yang diminta dalam pertanyaan: "Bagaimana memaksa git untuk menimpa mereka?" Saya tidak punya jawaban, saat ini saya mencarinya .. saat ini saya beralih ke cabang dengan kode yang ingin saya simpan "git checkout BranchWithCodeToKeep", lalu lakukan "git branch -D BranchToOverwrite" dan akhirnya "git checkout -b BranchToOverwrite". Anda sekarang akan memiliki kode persis dari BranchWithCodeToKeep pada branchToOverwrite cabang tanpa harus melakukan penggabungan.
felbus
252
alih-alih menggabungkan menggunakan 'git pull', coba git fetch --semua diikuti oleh 'git reset --hard origin / master'
Lloyd Moore
5
ya, solusi @lloydmoore bekerja untuk saya. Bisa dilakukan dengan menjadi jawaban daripada hanya komentar.
Max Williams
2
Ini akan mengatur ulang perubahan saat ini kembali ke komit cabang terakhir yang ditarik. Kemudian git pull menggabungkan perubahan dari cabang terbaru. Ini melakukan persis apa yang saya ingin lakukan .. Terima kasih!
Codeversed
459

PERINGATAN: git cleanmenghapus semua file / direktori Anda yang tidak dilacak dan tidak dapat diurungkan.


Terkadang clean -ftidak membantu. Jika Anda memiliki DIRECTORIES yang tidak dilacak, opsi -d juga diperlukan:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

PERINGATAN: git cleanmenghapus semua file / direktori Anda yang tidak dilacak dan tidak dapat diurungkan.

Pertimbangkan untuk menggunakan -n( --dry-run) flag terlebih dahulu. Ini akan menunjukkan kepada Anda apa yang akan dihapus tanpa benar-benar menghapus apa pun:

git clean -n -f -d

Contoh output:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
David Avsajanishvili
sumber
33
Luar biasa ... Lari ini terhadap repo dotfiles saya ... Di direktori rumah saya. Untung aku tidak benar-benar memiliki sesuatu yang penting di sana ...
Lauri
7
Saya pikir deskripsi skenario menjelaskan bahwa dia tidak benar-benar ingin membuang konten. Alih-alih yang dia inginkan adalah berhenti git berbicara tentang menimpa file. @Luri, ini seharusnya tidak terjadi padamu. Sayangnya orang-orang tampaknya salah membaca esensi dari deskripsi skenario - lihat saran saya.
Landak
19
AKHIRNYA . git clean -f -d berguna ketika make clean gagal membersihkan semuanya.
earthmeLon
7
@crizCraig kecuali jika ditambahkan.gitignore
Bleeding Fingers
5
@earthmeLon, untuk itu Anda mungkin ingin git clean -dfx. The -xabaikan Gitignore. Biasanya produk build Anda akan berada di .gitignore.
Paul Draper
384

Seperti Landak, saya pikir jawabannya mengerikan. Tetapi meskipun jawaban Hedgehog mungkin lebih baik, saya tidak berpikir itu seanggun mungkin. Cara saya menemukan untuk melakukan ini adalah dengan menggunakan "ambil" dan "bergabung" dengan strategi yang ditentukan. Yang seharusnya membuatnya agar perubahan lokal Anda dipertahankan selama mereka bukan salah satu file yang Anda coba paksa timpa.

Pertama, lakukan komitmen terhadap perubahan Anda

 git add *
 git commit -a -m "local file server commit message"

Kemudian ambil perubahan dan timpa jika ada konflik

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"-X" adalah nama opsi, dan "milik mereka" adalah nilai untuk opsi itu. Anda memilih untuk menggunakan perubahan "mereka", alih-alih perubahan "Anda" jika ada konflik.

Richard Kersey
sumber
56
Ini adalah jawaban terbaik yang pernah saya lihat sejauh ini. Saya belum mencobanya, tetapi tidak seperti jawaban lain, ini tidak mencoba untuk menyembunyikan semua file Anda yang tidak terlacak, yang sangat berbahaya karena alasan yang jelas.
huyz
5
Ditto - ini bekerja untuk saya ketika melakukan penggabungan yang sangat besar (permintaan tarik GitHub) di mana saya hanya ingin menerima semuanya di atas apa yang saya miliki. Jawaban yang bagus! Dalam kasus saya, dua perintah terakhir adalah: 1) get fetch other-repo; 2)git merge -s recursive -X theirs other-repo/master
quux00
2
Ini akan menimpa konflik dengan file repositori dan bukan yang lokal, benar?
Nathan F.
2
Jawaban Terbaik. Jawaban tertinggi yang diterima meninggalkan saya dalam kasus saya di kepala terpisah. Saya kembali ke cabang utama setempat dan berlarigit merge -X theirs origin/master
petergus
2
Masalah dengan jawaban (luar biasa) ini, adalah menambahkan semua file lokal, yang kadang-kadang mungkin bukan yang Anda inginkan. Anda mungkin hanya ingin menambahkan file tertentu yang dihilangkan. Tetapi hal terbaik tentang itu adalah, itu membuatnya melakukan apa yang seharusnya dia lakukan - menambahkannya secara lokal. Anda mungkin tidak akan memerlukan strategi -X mereka, karena mereka gambar yang sama. Bahkan, saya sarankan berhenti dulu, hanya untuk mengetahui apakah ada anomali, dan menambahkannya jika ada, setelah meninjau bahwa 'milik mereka' selalu merupakan pilihan yang tepat. Tapi kemudian, saya paranoid.
Bob Kerns
279

Alih-alih melakukan:

git fetch --all
git reset --hard origin/master

Saya menyarankan melakukan hal berikut:

git fetch origin master
git reset --hard origin/master

Tidak perlu mengambil semua remote dan cabang jika Anda akan mengatur ulang ke cabang asal / master bukan?

Johanneke
sumber
3
Jawaban Anda adalah apa yang Anda butuhkan untuk perwakilan Anda. Saya harus bertanya, apakah ini juga menghapus semua file yang tidak terlacak?
Nicolas De Jay
5
Ya, sebagian besar perwakilan saya berasal dari sini :) Ini juga akan menghapus semua file yang tidak terlacak. Sesuatu yang saya lupakan dan diingatkan dengan menyakitkan 2 hari yang lalu ...
Johanneke
1
Lihat komentar pada jawaban lain ini: stackoverflow.com/a/8888015/2151700
Johanneke
Ini tidak menghapus file saya yang tidak terlacak; yang sebenarnya adalah apa yang saya harapkan. Adakah alasannya bagi sebagian orang dan tidak bagi orang lain?
arichards
File yang tidak dilacak tidak terpengaruh oleh reset git. Jika Anda ingin mereka juga dihapus, lakukan git add .terlebih dahulu, sebelumgit reset --hard
Johanneke
131

Sepertinya cara terbaik adalah pertama-tama melakukannya:

git clean

Untuk menghapus semua file yang tidak dilacak dan kemudian melanjutkan dengan git pull...

Jakub Troszok
sumber
4
Saya mencoba menggunakan "git clean" untuk menyelesaikan masalah yang sama, tetapi tidak menyelesaikannya. status git mengatakan "Cabang dan 'asal / master' Anda masing-masing berbeda, # dan masing-masing memiliki 2 dan 9 komit yang berbeda." dan git pull mengatakan sesuatu yang mirip dengan yang Anda miliki di atas.
slacy
43
git clean adalah instrumen yang agak tumpul, dan bisa membuang banyak hal yang mungkin ingin Anda simpan. Lebih baik menghapus atau mengganti nama file yang dikeluhkan git sampai tarikan berhasil.
Neil Mayhew
2
Saya tidak berpikir ini bekerja secara umum. Apakah tidak ada cara untuk melakukan remote git kloning pada dasarnya melalui tarikan git paksa?
mathtick
10
@mathick:git fetch origin && git reset --hard origin/master
Arrowmaster
3
Apakah git cleanjawaban terbaik di sini? Sepertinya menghapus file belum tentu seperti yang diinginkan OP. Mereka meminta 'timpa file lokal' bukan penghapusan.
JohnAllen
111

Peringatan, melakukan ini akan menghapus file Anda secara permanen jika Anda memiliki entri direktori / * di file gitignore Anda.

Beberapa jawaban tampaknya mengerikan. Mengerikan dalam arti apa yang terjadi pada @Lauri dengan mengikuti saran David Avsajanishvili.

Sebaliknya (git> v1.7.6):

git stash --include-untracked
git pull

Nanti Anda bisa membersihkan simpanan sejarah.

Secara manual, satu per satu:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Secara brutal, sekaligus:

$ git stash clear

Tentu saja jika Anda ingin kembali ke apa yang Anda sembunyikan:

$ git stash list
...
$ git stash apply stash@{5}
landak
sumber
2
Tidak, kurasa tidak. Menyimpan hanya memindahkan file yang tidak dikomit keluar dari jalan. Di atas juga memindahkan (menyimpan) file yang tidak dilacak git. Ini mencegah file yang telah ditambahkan ke remote, yang belum ditarik ke mesin Anda - tetapi yang telah Anda buat (!) - untuk ditarik ke bawah. Semua tanpa merusak pekerjaan yang tidak berkomitmen. Harapan itu masuk akal?
Hedgehog
3
Jika Anda tidak memiliki 1.7.6, Anda dapat meniru --include-untrackedhanya dengan sementara git add-ing seluruh repo Anda, kemudian segera menyimpannya.
nategood
3
Saya setuju dengan Hedgehog. Jika Anda melakukan jawaban populer di sini, kemungkinan besar Anda akan menemukan bahwa Anda telah secara tidak sengaja membunuh banyak hal yang sebenarnya tidak ingin Anda hilangkan.
Guardius
1
Saya punya file lain yang tidak dilacak - selain file yang ingin ditimpa, jadi solusi ini bekerja paling baik. git stash applymengembalikan semua file saya yang tidak terlacak dengan pengecualian (yang benar) dari yang telah dibuat gabungan: "sudah ada, tidak perlu checkout." Bekerja dengan sempurna.
BigBlueHat
2
Ini adalah jawaban terbersih, dan harus diterima. Untuk menghemat mengetik Anda dapat menggunakan bentuk pendek: git stash -u.
ccpizza
93

Anda mungkin menemukan perintah ini berguna untuk membuang perubahan lokal:

git checkout <your-branch> -f

Dan kemudian lakukan pembersihan (menghapus file yang tidak terlacak dari pohon yang berfungsi):

git clean -f

Jika Anda ingin menghapus direktori yang tidak dilacak selain file yang tidak dilacak:

git clean -fd
Vishal
sumber
Saya pikir deskripsi skenario menjelaskan bahwa dia tidak benar-benar ingin membuang konten. Alih-alih yang dia inginkan adalah berhenti git berbicara tentang menimpa file. Lihat saran saya.
Landak
3
Meskipun jawaban itu mungkin tidak sesuai dengan deskripsi, masih menyelamatkan saya dari frustrasi git memutar-mutar pengembalian kereta (acara dengan autocrlf false). Ketika git reset --hard HEAD tidak meninggalkan Anda dengan file yang "tidak" dimodifikasi, flag "-f" ini cukup membantu. Terima kasih banyak.
Kellindil
88

Alih-alih bergabung dengan git pull, coba ini:

git fetch --all

diikuti oleh:

git reset --hard origin/master.

Lloyd Moore
sumber
61

Satu-satunya hal yang berhasil bagi saya adalah:

git reset --hard HEAD~5

Ini akan membawa Anda kembali lima komit dan kemudian dengan

git pull

Saya menemukan bahwa dengan mencari cara membatalkan penggabungan Git .

Chris BIllante
sumber
Inilah yang akhirnya berhasil bagi saya karena saya telah memaksa mendorong cabang saya ke repo asal dan terus mendapatkan konflik penggabungan ketika mencoba menariknya ke repo jarak jauh saya.
jwfrench
Hai, sebenarnya ini adalah trik untuk work aroundtetapi sangat efektif. Karena beberapa konflik dapat terjadi hanya dalam beberapa komit maka mengembalikan 5 komit akan memastikan tidak ada konflik dengan kode jarak jauh.
Hoang Le
54

Masalah dengan semua solusi ini adalah bahwa semuanya terlalu kompleks, atau, masalah yang lebih besar, adalah mereka menghapus semua file yang tidak terlacak dari server web, yang tidak kita inginkan karena selalu ada file konfigurasi yang diperlukan yang ada di server dan bukan di repositori Git.

Berikut adalah solusi terbersih yang kami gunakan:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • Perintah pertama mengambil data terbaru.

  • Perintah kedua memeriksa apakah ada file yang sedang ditambahkan ke repositori dan menghapus file-file yang tidak dilacak dari repositori lokal yang akan menyebabkan konflik.

  • Perintah ketiga memeriksa semua file yang dimodifikasi secara lokal.

  • Akhirnya kami melakukan pembaruan untuk memperbarui ke versi terbaru, tetapi kali ini tanpa konflik, karena file yang tidak terlacak dalam repo tidak ada lagi dan semua file yang dimodifikasi secara lokal sudah sama seperti di repositori.

Strahinja Kustudic
sumber
Menggunakan "git merge origin / master" sebagai baris terakhir (seperti yang Anda katakan dalam catatan Anda) alih-alih "git pull" akan lebih cepat karena Anda sudah melakukan perubahan apa pun dari repo git.
Josh
1
Ya tentu saja, git merge origin/masterakan lebih cepat dan mungkin bahkan lebih aman. Karena jika seseorang mendorong perubahan baru selama penghapusan file skrip ini (yang tidak mungkin terjadi, tetapi mungkin), seluruh tarikan dapat gagal. Satu-satunya alasan saya menempatkan pulldi sana adalah karena seseorang mungkin tidak bekerja pada cabang master, tetapi beberapa cabang lainnya dan saya ingin skripnya menjadi universal.
Strahinja Kustudic
Jika Anda memiliki file yang dibuat secara lokal seperti file opsi, masukkan .gitignore.
Sebi
52

Pertama-tama, coba cara standar:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Peringatan : Perintah di atas dapat menyebabkan hilangnya data / file hanya jika Anda tidak membuatnya! Jika Anda tidak yakin, buat cadangan terlebih dahulu dari seluruh folder repositori Anda.

Lalu tarik lagi.

Jika di atas tidak akan membantu dan Anda tidak peduli dengan file / direktori yang tidak dilacak (buat cadangan terlebih dahulu untuk berjaga-jaga), coba langkah-langkah sederhana berikut:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Ini akan MENGHAPUS semua file git (pengecualian .git/dir, di mana Anda memiliki semua komit) dan tarik lagi.


Mengapa git reset HEAD --hardbisa gagal dalam beberapa kasus?

  1. Aturan khusus di .gitattributes file

    Memiliki eol=lf aturan dalam .gitattributes dapat menyebabkan git untuk memodifikasi beberapa perubahan file dengan mengubah CRLF akhir baris menjadi LF di beberapa file teks.

    Jika demikian, Anda harus melakukan perubahan CRLF / LF ini (dengan memeriksanya di git status ), atau mencoba: git config core.autcrlf falseuntuk mengabaikannya sementara.

  2. Ketidakmampuan sistem file

    Ketika Anda menggunakan sistem file yang tidak mendukung atribut izin. Sebagai contoh, Anda memiliki dua repositori, satu di Linux / Mac (ext3 /hfs+ ) dan satu lagi di sistem file berbasis FAT32 / NTFS.

    Seperti yang Anda perhatikan, ada dua jenis sistem file, jadi yang tidak mendukung izin Unix pada dasarnya tidak dapat mengatur ulang izin file pada sistem yang tidak mendukung izin semacam itu, jadi tidak masalah bagaimana --hardAnda mencoba, git selalu deteksi beberapa "perubahan".

kenorb
sumber
47

Saya memiliki masalah yang sama. Tidak ada yang memberi saya solusi ini, tetapi itu berhasil untuk saya.

Saya menyelesaikannya dengan:

  1. Hapus semua file. Tinggalkan .gitdirektori saja.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Sekarang berhasil.

John John Pichler
sumber
1
Sama disini. Kadang-kadang hanya solusi yang sangat sulit yang berhasil, sering kali hanya reset dan membersihkan tidak cukup entah bagaimana ...
jdehaan
41

Bonus:

Dalam berbicara tentang menarik / mengambil / menggabungkan jawaban sebelumnya, saya ingin berbagi trik yang menarik dan produktif,

git pull --rebase

Perintah di atas adalah perintah yang paling berguna dalam hidup Git saya yang menghemat banyak waktu.

Sebelum mendorong komit baru Anda ke server, coba perintah ini dan itu akan secara otomatis menyinkronkan perubahan server terbaru (dengan mengambil + gabungan) dan akan menempatkan komit Anda di bagian atas dalam log Git. Tidak perlu khawatir tentang tarikan / penggabungan manual.

Temukan detail di Apa yang "git pull --rebase" lakukan? .

Sazzad Hissain Khan
sumber
3
Singkatnya: git pull -r.
kenorb
29

Saya punya masalah serupa. Saya harus melakukan ini:

git reset --hard HEAD
git clean -f
git pull
Ryan
sumber
6
gunakan git cleandengan hati
nategood
29

Saya merangkum jawaban lain. Anda dapat mengeksekusi git pulltanpa kesalahan:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Peringatan : Skrip ini sangat kuat, sehingga Anda bisa kehilangan perubahan.

Robert Moon
sumber
2
Ini akan menimpa file yang dimodifikasi (file yang sebelumnya diperiksa) dan itu akan menghapus file yang tidak dilacak (file yang belum pernah diperiksa). Persis apa yang saya cari, terima kasih!
styfle
3
Saya menduga baris ketiga git reset --hard HEADmungkin berlebihan; halaman manual lokal saya (2.6.3) mengatakan bahwa resetpada baris kedua git reset --hard origin/master "default ke HEAD dalam segala bentuk."
arichards
2
@arichards Saya pikir tersangka Anda benar tetapi jika baris kedua tidak berfungsi (dengan alasan apa pun) baris ketiga berfungsi dengan baik untuk mengatur ulang. Solusi ini tidak perlu dioptimalkan. Saya baru saja merangkum jawaban lain. Itu saja. Terima kasih atas komentarmu. :)
Robert Moon
28

Berdasarkan pengalaman saya yang serupa, solusi yang ditawarkan oleh Strahinja Kustudic di atas sejauh ini adalah yang terbaik. Seperti yang telah ditunjukkan orang lain, cukup melakukan hard reset akan menghapus semua file yang tidak terlacak yang dapat mencakup banyak hal yang tidak ingin Anda hapus, seperti file konfigurasi. Yang lebih aman, adalah menghapus hanya file yang akan ditambahkan, dan dalam hal ini, Anda mungkin juga ingin checkout file yang dimodifikasi secara lokal yang akan diperbarui.

Itu dalam pikiran, saya memperbarui skrip Kustudic untuk melakukan hal itu. Saya juga memperbaiki kesalahan ketik (yang hilang 'di aslinya).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull
Rolf Kaiser
sumber
Menggunakan "git merge origin / master" sebagai baris terakhir (seperti yang Anda katakan dalam catatan Anda) alih-alih "git pull" akan lebih cepat karena Anda sudah melakukan perubahan apa pun dari repo git.
Josh
Diperlukan checkout dari file yang dimodifikasi, jadi ini berfungsi 100% kali. Saya memperbarui skrip saya dengan itu sejak lama, tetapi lupa untuk memperbarui di sini juga. Saya juga menggunakannya sedikit berbeda dari Anda. Saya checkout file yang memiliki semua jenis modifikasi, bukan hanya M, jadi ini berfungsi setiap saat.
Strahinja Kustudic
24

Saya percaya ada dua kemungkinan penyebab konflik, yang harus diselesaikan secara terpisah, dan sejauh yang saya bisa katakan, tidak satu pun jawaban di atas yang membahas keduanya:

  • File lokal yang tidak terlacak perlu dihapus, baik secara manual (lebih aman) atau seperti yang disarankan dalam jawaban lain, oleh git clean -f -d

  • Komit lokal yang tidak ada di cabang jarak jauh perlu dihapus juga. IMO cara termudah untuk mencapai ini adalah dengan: git reset --hard origin/master(ganti 'master' dengan cabang apa pun yang sedang Anda kerjakan, dan jalankan yang git fetch originpertama)

tiho
sumber
22

Cara yang lebih mudah adalah:

git checkout --theirs /path/to/file.extension
git pull origin master

Ini akan menimpa file lokal Anda dengan file pada git

maximus 69
sumber
21

Sepertinya sebagian besar jawaban di sini difokuskan pada master cabang; Namun, ada saat-saat ketika saya mengerjakan cabang fitur yang sama di dua tempat berbeda dan saya ingin rebase di salah satu tercermin di yang lain tanpa banyak melompat melalui lingkaran.

Berdasarkan kombinasi jawaban RNA dan jawaban torek untuk pertanyaan serupa , saya telah menemukan ini yang bekerja sangat baik:

git fetch
git reset --hard @{u}

Jalankan ini dari cabang dan itu hanya akan mereset cabang lokal Anda ke versi hulu.

Ini juga dapat dimasukkan ke alias git ( git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Atau, di .gitconfigfile Anda :

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Nikmati!

JacobEvelyn
sumber
Jawaban ini juga bagus karena berfungsi terlepas dari cabang mana Anda berada!
leafmeal
19

Saya memiliki masalah yang sama dan untuk beberapa alasan, bahkan git clean -f -dtidak akan melakukannya. Inilah sebabnya: Untuk beberapa alasan, jika file Anda diabaikan oleh Git (melalui entri .gitignore, saya berasumsi), itu masih mengganggu tentang menimpa ini dengan tarikan yang kemudian , tetapi clean tidak akan menghapusnya, kecuali jika Anda menambahkan -x.

Tierlieb
sumber
19

Saya tahu metode yang jauh lebih mudah dan tidak menyakitkan:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Itu dia!

ddmytrenko
sumber
18

Saya baru saja menyelesaikan ini sendiri dengan:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

di mana perintah terakhir memberikan daftar apa perubahan lokal Anda. Terus memodifikasi cabang "tmp" sampai diterima dan kemudian bergabung kembali ke master dengan:

git checkout master && git merge tmp

Untuk waktu berikutnya, Anda mungkin dapat menangani ini dengan cara yang lebih bersih dengan mencari "git stash branch" meskipun simpanan kemungkinan akan menyebabkan Anda bermasalah pada beberapa percobaan pertama, jadi lakukan percobaan pertama pada proyek yang tidak penting ...

Simon B.
sumber
17

Saya memiliki situasi aneh yang tidak berhasil git cleanatau tidak git reset. Saya harus menghapus file yang bertentangan git indexdengan menggunakan skrip berikut pada setiap file yang tidak dilacak:

git rm [file]

Maka saya bisa menarik dengan baik.

Chen Zhang
sumber
16

git fetch --all && git reset --hard origin/master && git pull

Luar biasa
sumber
14

Terlepas dari pertanyaan awal, jawaban teratas dapat menyebabkan masalah bagi orang yang memiliki masalah serupa, tetapi tidak ingin kehilangan file lokal mereka. Misalnya, lihat komentar Al-Punk dan crizCraig.

Versi berikut melakukan perubahan lokal Anda ke cabang sementara ( tmp), memeriksa cabang asli (yang saya asumsikan master) dan menggabungkan pembaruan. Anda dapat melakukan ini dengan stash, tetapi saya telah menemukan itu biasanya lebih mudah untuk hanya menggunakan pendekatan cabang / gabungan.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch origin master
git merge -s recursive -X theirs origin master

di mana kami menganggap repositori lainnya adalah origin master.

Snowcrash
sumber
13

Keempat perintah ini bekerja untuk saya.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Untuk memeriksa / menarik setelah menjalankan perintah ini

git pull origin master

Saya mencoba banyak tetapi akhirnya berhasil dengan perintah ini.

vishesh chandra
sumber
2
"git branch -D master" hapus cabang. jadi berhati-hatilah dengan itu. Saya lebih suka menggunakan "git checkout origin / master -b <new branch name>" yang membuat cabang baru dengan nama baru dan Anda selesai membutuhkan 3,4 baris. Juga disarankan untuk menggunakan "git clean -f" juga.
Chand Priyankara
13

Kerjakan saja

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Jadi Anda menghindari semua efek samping yang tidak diinginkan, seperti menghapus file atau direktori yang ingin Anda simpan, dll.

pengguna2696128
sumber
12

Setel ulang indeks dan kepala ke origin/master, tetapi jangan mengatur ulang pohon kerja:

git reset origin/master

sumber
Saya pribadi menemukan ini paling bermanfaat. Kemudian menyimpan pohon kerja Anda sehingga Anda dapat memeriksanya kembali. Untuk masalah saya, saya menghapus file yang sama dengan yang ditambahkan sehingga macet. Aneh, saya tahu.
Jason Sebring
12

Persyaratan:

  1. Lacak perubahan lokal sehingga tidak ada seorang pun di sini yang pernah kehilangan mereka.
  2. Buat repositori lokal cocok dengan repositori asal asal.

Larutan:

  1. Simpan perubahan lokal.
  2. Ambil dengan bersih dari file dan direktori mengabaikan Gitignore dan hard reset ke asal .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
vezenkov
sumber