Bagaimana saya bisa membuang perubahan jarak jauh dan menandai file sebagai "diselesaikan"?

197

Saya punya beberapa file lokal, saya tarik dari cabang jauh dan ada konflik. Saya tahu bahwa saya ingin menyimpan perubahan lokal saya dan mengabaikan perubahan jarak jauh yang menyebabkan konflik. Apakah ada perintah yang bisa saya gunakan untuk mengatakan "tandai semua konflik telah diselesaikan, gunakan lokal"?

Tom DeMille
sumber
1
Jawaban di bawah ini sangat mencerahkan bagi saya. Ada beberapa poin halus yang dibuat untuk saya, saya sarankan pengguna GIT non-ahli untuk membaca semua komentar di bawah posting di bawah ini, dan terima kasih Brian!
Tom DeMille

Jawaban:

332

git checkoutmemiliki --oursopsi untuk memeriksa versi file yang Anda miliki secara lokal (sebagai lawan dari --theirs, yang merupakan versi yang Anda tarik). Anda dapat melewatinya .untuk git checkoutmengatakannya untuk memeriksa semua yang ada di pohon. Maka Anda perlu menandai konflik sebagai terselesaikan, yang dapat Anda lakukan dengan git add, dan melakukan pekerjaan Anda setelah selesai:

git checkout --ours .  # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

Perhatikan .pada git checkoutperintah. Itu sangat penting, dan mudah untuk dilewatkan. git checkoutmemiliki dua mode; satu di mana ia beralih cabang, dan satu di mana ia memeriksa file dari indeks ke dalam copy pekerjaan (kadang-kadang menarik mereka ke dalam indeks dari revisi lain terlebih dahulu). Cara membedakannya adalah dengan apakah Anda telah memasukkan nama file di; jika Anda belum memasukkan nama file, ia mencoba berpindah cabang (meskipun jika Anda tidak lulus cabang juga, itu hanya akan mencoba memeriksa cabang saat ini lagi), tetapi ia menolak untuk melakukannya jika ada file yang dimodifikasi bahwa itu akan berpengaruh. Jadi, jika Anda menginginkan perilaku yang akan menimpa file yang ada, Anda harus .memasukkan atau nama file untuk mendapatkan perilaku kedua git checkout.

Ini juga merupakan kebiasaan yang baik untuk memiliki, ketika memasukkan nama file, untuk mengimbanginya --, seperti git checkout --ours -- <filename>. Jika Anda tidak melakukan ini, dan nama file kebetulan cocok dengan nama cabang atau tag, Git akan berpikir bahwa Anda ingin memeriksa revisi itu, alih-alih memeriksa nama file itu, dan karenanya gunakan bentuk pertama dari checkoutperintah .

Saya akan memperluas sedikit tentang bagaimana konflik dan penggabungan bekerja di Git. Saat Anda menggabungkan kode orang lain (yang juga terjadi saat tarikan; tarikan pada dasarnya adalah pengambilan diikuti oleh gabungan), ada beberapa situasi yang mungkin.

Yang paling sederhana adalah Anda berada di revisi yang sama. Dalam hal ini, Anda "sudah terkini", dan tidak ada yang terjadi.

Kemungkinan lain adalah bahwa revisi mereka hanyalah turunan dari Anda, dalam hal ini Anda secara default akan memiliki "penggabungan cepat", di mana Anda HEADbaru saja diperbarui ke komit mereka, tanpa terjadi penggabungan (ini dapat dinonaktifkan jika Anda benar-benar ingin merekam gabungan, menggunakan --no-ff).

Kemudian Anda masuk ke situasi di mana Anda sebenarnya perlu menggabungkan dua revisi. Dalam hal ini, ada dua kemungkinan hasil. Pertama adalah bahwa penggabungan terjadi secara bersih; semua perubahan ada di file yang berbeda, atau berada di file yang sama tetapi terpisah cukup jauh sehingga kedua set perubahan dapat diterapkan tanpa masalah. Secara default, ketika gabungan bersih terjadi, maka secara otomatis berkomitmen, meskipun Anda dapat menonaktifkan ini dengan --no-commitjika Anda perlu untuk mengedit itu terlebih dahulu (misalnya, jika Anda mengubah nama fungsi foountuk bar, dan orang lain menambahkan kode baru bahwa panggilan foo, itu akan menggabungkan bersih , tetapi hasilkan pohon yang patah, jadi Anda mungkin ingin membersihkannya sebagai bagian dari gabungan komit untuk menghindari komit yang rusak).

Kemungkinan terakhir adalah bahwa ada penggabungan nyata, dan ada konflik. Dalam hal ini, Git akan melakukan sebanyak penggabungan karena dapat, dan file hasil dengan spidol konflik ( <<<<<<<, =======, dan >>>>>>>) di copy pekerjaan Anda. Dalam indeks (juga dikenal sebagai "area pementasan"; tempat penyimpanan file git addsebelum melakukannya), Anda akan memiliki 3 versi setiap file dengan konflik; ada versi asli file dari leluhur dari dua cabang yang Anda HEADgabungkan, versi dari (sisi penggabungan Anda), dan versi dari cabang jarak jauh.

Untuk menyelesaikan konflik, Anda dapat mengedit file yang ada di copy pekerjaan Anda, menghapus penanda konflik dan memperbaiki kode sehingga berfungsi. Atau, Anda dapat memeriksa versi dari satu atau sisi lain dari penggabungan, menggunakan git checkout --oursatau git checkout --theirs. Setelah Anda memasukkan file ke dalam keadaan yang Anda inginkan, Anda mengindikasikan bahwa Anda telah selesai menggabungkan file dan siap untuk berkomitmen menggunakan git add, dan kemudian Anda dapat melakukan penggabungan dengan git commit.

Brian Campbell
sumber
7
Anda mungkin harus mencatat bahwa git add --allmenambahkan semua file ke repositori sehingga ini dapat menambahkan lebih banyak file daripada yang dimaksudkan kecuali .gitignorepola Anda dalam keadaan sempurna. git add -umungkin lebih cocok untuk situasi ini, Anda cenderung tidak memiliki pengeditan untuk melacak file yang tidak ingin Anda tambahkan saat menyelesaikan penggabungan.
CB Bailey
Ups, maaf. Itu yang saya maksud. Diperbaiki sekarang.
Brian Campbell
1
terima kasih atas jawaban terinci Anda. Saya sebenarnya mencoba checkout git --ours dan menerima pesan kesalahan (yang saya tidak ingat sekarang). File-file yang dimaksud adalah dll (kami memiliki beberapa yang kami lakukan simpanan, sebagian besar referensi pihak ke-3) dan saya hanya ingin mengatakan 'ok salinan saya adalah yang saya inginkan tetapi kesalahannya adalah seperti' tidak dapat checkout saat menggabungkan ' ..... Saya akan menyimpan artikel ini sebagai referensi dan lain kali hal itu terjadi, cobalah lagi dan lihat apakah itu berfungsi atau apakah saya dapat memposting pesan itu. Terima kasih lagi
Tom DeMille
tetapi penjelasan Anda sangat jelas bagi saya tentang prosesnya, terima kasih lagi ... Pertanyaan lanjutan: Adakah cara untuk mendapatkan git untuk menghapus file .orig setelah penggabungan selesai?
Tom DeMille
2
Yang perlu Anda lakukan git checkout --ours .. Itu .penting; lewat nama file (dalam hal ini, seluruh direktori) memilih antara dua mode operasi yang berbeda checkout, yang beralih cabang dan yang memindahkan file dari indeks ke copy yang berfungsi. Saya setuju, ini sangat membingungkan. Anda juga dapat melakukan git checkout --ours -- <filename>untuk memeriksa file individual pada suatu waktu.
Brian Campbell
23

Pastikan asal konflik: jika itu adalah hasil dari git merge, lihat Brian Campbell 's jawaban .

Tetapi jika ini adalah hasil dari git rebase, untuk membuang perubahan jarak jauh dan menggunakan perubahan lokal , Anda harus melakukan:

git checkout --theirs -- .

Lihat " Mengapa arti" ours"dan" theirs"terbalik" "untuk melihat bagaimana oursdan theirsditukar selama rebase (karena cabang hulu dicentang).

VONC
sumber