Saya pikir masalah dasar Anda di sini adalah bahwa Anda salah menafsirkan dan / atau salah memahami apa yang dilakukan git dan mengapa git melakukannya.
Saat Anda mengkloning beberapa repositori lain, git membuat salinan apa pun yang ada "di sana". Ia juga mengambil label cabang "mereka", seperti master, dan membuat salinan dari label itu yang "nama lengkapnya" di pohon git Anda adalah (biasanya) remotes/origin/master(tetapi dalam kasus Anda, remotes/upstream/master). Seringkali Anda juga bisa menghilangkan remotes/bagian tersebut, jadi Anda bisa merujuk ke salinan aslinya sebagai upstream/master.
Jika sekarang Anda membuat dan melakukan beberapa perubahan ke beberapa file, Anda adalah satu-satunya yang memiliki perubahan tersebut. Sementara itu, orang lain dapat menggunakan repositori asli (tempat Anda membuat klon) untuk membuat klon lain dan mengubah klon tersebut. Mereka adalah satu-satunya yang memiliki perubahan, tentunya. Namun pada akhirnya, seseorang mungkin memiliki perubahan yang mereka kirim kembali ke pemilik aslinya (melalui "push" atau tambalan atau apa pun).
The git pullperintah kebanyakan hanya singkatan untuk git fetchdiikuti oleh git merge. Ini penting karena artinya Anda perlu memahami apa yang sebenarnya dilakukan oleh kedua operasi tersebut.
The git fetchperintah mengatakan untuk kembali ke mana pun Anda kloning dari (atau telah ditetapkan sebagai tempat untuk mengambil dari) dan menemukan "baru barang-barang orang lain ditambahkan atau diubah atau dihapus". Perubahan tersebut disalin dan diterapkan ke salinan Anda dari apa yang Anda dapatkan dari mereka sebelumnya . Mereka tidak diterapkan pada pekerjaan Anda sendiri, hanya pada pekerjaan mereka.
The git mergeperintah lebih rumit dan adalah di mana Anda akan kacau. Apa yang dilakukannya, sedikit disederhanakan, adalah membandingkan "apa yang Anda ubah dalam salinan Anda" dengan "perubahan yang Anda ambil dari orang lain dan dengan demikian ditambahkan ke salinan-karya-karya-orang lain". Jika perubahan Anda dan perubahannya tidak menimbulkan konflik, mergeoperasi menggabungkannya dan memberi Anda "komit gabungan" yang mengikat pengembangan Anda dan perkembangannya bersama-sama (meskipun ada kasus "mudah" yang sangat umum di mana Anda tidak memiliki berubah dan Anda mendapatkan "maju cepat").
Situasi yang Anda hadapi sekarang adalah situasi di mana Anda telah membuat perubahan dan melakukannya — sembilan kali, pada kenyataannya, karena itu "9 di depan" —dan mereka tidak membuat perubahan. Jadi, dengan fetchpatuh tidak mengambil apa-apa, dan kemudian mergemengambil kekurangan-perubahan mereka dan juga tidak melakukan apa-apa.
Yang Anda inginkan adalah melihat, atau mungkin bahkan "menyetel ulang" ke, versi kode "mereka".
Jika Anda hanya ingin melihatnya, Anda dapat melihat versi itu:
git checkout upstream/master
Itu memberitahu git bahwa Anda ingin memindahkan direktori saat ini ke cabang yang nama lengkapnya sebenarnya remotes/upstream/master. Anda akan melihat kode mereka sejak terakhir kali Anda menjalankan git fetchdan mendapatkan kode terbaru mereka.
Jika Anda ingin mengabaikan semua perubahan Anda sendiri, yang perlu Anda lakukan adalah mengubah gagasan git tentang revisi label mana master, yang harus diberi nama. Saat ini, ini memberi nama komit terbaru Anda. Jika Anda kembali ke cabang itu:
git checkout master
maka git resetperintah tersebut akan memungkinkan Anda untuk "memindahkan label", sebagaimana mestinya. Satu-satunya masalah yang tersisa (dengan asumsi Anda benar-benar siap untuk meninggalkan semua yang telah Anda lakukan) adalah menemukan di mana label harus menunjuk.
git logakan membiarkan Anda menemukan nama numerik — hal-hal seperti 7cfcb29—yang merupakan nama permanen (tidak pernah berubah), dan ada banyak cara lain untuk menamainya, tetapi dalam hal ini Anda hanya menginginkan namanya upstream/master.
Untuk memindahkan label, memusnahkan perubahan Anda sendiri (apapun yang Anda telah berkomitmen sebenarnya dipulihkan untuk cukup lama tapi itu jauh lebih sulit setelah ini jadi sangat yakin):
git reset --hard upstream/master
Perintah itu --hardmemberitahu git untuk menghapus apa yang telah Anda lakukan, memindahkan label cabang saat ini, dan kemudian memeriksa komit yang diberikan.
Tidak terlalu umum untuk benar - benar ingin git reset --harddan menghapus banyak pekerjaan. Metode yang lebih aman (membuatnya jauh lebih mudah untuk memulihkan pekerjaan itu jika Anda memutuskan beberapa di antaranya bermanfaat) adalah dengan mengganti nama cabang Anda yang ada:
git branch -m master bunchofhacks
dan kemudian buat cabang lokal baru bernama master"trek" (Saya tidak terlalu suka istilah ini karena menurut saya ini membingungkan orang, tetapi itu istilah git :-)) master asal (atau upstream):
git branch -t master upstream/master
yang kemudian dapat Anda lakukan sendiri:
git checkout master
Apa yang dilakukan tiga perintah terakhir (ada pintasan untuk menjadikannya hanya dua perintah) adalah mengubah nama yang ditempelkan pada label yang ada, lalu membuat label baru, lalu beralih ke label itu:
sebelum melakukan apapun:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
setelah git branch -m:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
setelah git branch -t master upstream/master:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
Berikut C0adalah komit terbaru (pohon sumber lengkap) yang Anda dapatkan saat pertama kali melakukan git clone. C1 hingga C9 adalah komitmen Anda.
Perhatikan bahwa jika Anda menjadi git checkout bunchofhacksdan kemudian git reset --hard HEAD^^, ini akan mengubah gambar terakhir menjadi:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
Alasannya adalah HEAD^^menamai revisi dua dari kepala cabang saat ini (yang tepat sebelum reset akan dilakukan bunchofhacks), dan reset --hardkemudian memindahkan label. Commits C8 dan C9 sekarang sebagian besar tidak terlihat (Anda dapat menggunakan hal-hal seperti reflog dan git fsckmenemukannya tetapi tidak lagi sepele). Label Anda adalah milik Anda untuk dipindahkan sesuka Anda. The fetchperintah mengurus orang-orang yang memulai dengan remotes/. Adalah konvensional untuk mencocokkan "milik Anda" dengan "milik mereka" (jadi jika mereka memiliki remotes/origin/mauveAnda akan menamai Anda mauvejuga), tetapi Anda dapat mengetikkan "milik mereka" kapan pun Anda ingin memberi nama / melihat komitmen yang Anda dapatkan "dari mereka". (Ingatlah bahwa "satu komit" adalah keseluruhan pohon sumber. Anda dapat memilih satu file tertentu dari satu komit, dengan git showmisalnya,