git pullmungkin membuat komit. Jika Anda membuat komit lokal dan kemudian menjalankan git pullsetelah orang lain mendorong komit ke repositori, Git mengunduh komit pengembang lain dan kemudian menggabungkannya ke cabang lokal Anda.
Bagaimana cara menghindari komitmen gabungan ini di masa mendatang
Anda dapat menggunakan git pull --rebaseuntuk mencegah hal ini terjadi di masa mendatang, tetapi rebasing memiliki risiko sendiri, dan saya sarankan untuk menghindarinya pullsama sekali .
Sebagai gantinya, saya mendorong Anda untuk mengikuti pola penggunaan ini:
# download the latest commits
git remote update -p
# update the local branch
git merge --ff-only @{u}
# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}
Penjelasan
git remote update -pmengunduh semua komit di repositori jarak jauh dan memperbarui cabang pelacakan jarak jauh (misalnya, origin/master). Ini TIDAK menyentuh direktori kerja, indeks, atau cabang lokal Anda.
The -pplum Argumen dihapus cabang hulu. Dengan demikian, jika foocabang tersebut terhapus di originrepositori, git remote update -potomatis origin/fooref Anda akan terhapus .
git merge --ff-only @{u}memberi tahu Git untuk menggabungkan cabang upstream ( @{u}argumen) ke dalam cabang lokal Anda tetapi hanya jika cabang lokal Anda dapat "diteruskan dengan cepat" ke cabang upstream (dengan kata lain, jika cabang tersebut belum menyimpang).
git rebase -p @{u}secara efektif memindahkan komit yang telah Anda buat tetapi belum mendorong ke atas cabang hulu, yang menghilangkan kebutuhan untuk membuat komit gabungan konyol yang Anda coba hindari. Ini meningkatkan linearitas riwayat pengembangan, membuatnya lebih mudah untuk ditinjau.
The -ppilihan memberitahu Git untuk melestarikan gabungan. Hal ini mencegah Git melinierisasi komitmen yang dibuat ulang. Ini penting jika, misalnya, Anda menggabungkan cabang fitur menjadi master. Tanpa -p, setiap komit pada cabang fitur akan diduplikasi mastersebagai bagian dari linierisasi yang dilakukan oleh git rebase. Ini akan membuat riwayat perkembangan lebih sulit untuk ditinjau, bukan lebih mudah.
Waspadalah : git rebasemungkin tidak melakukan apa yang Anda harapkan, jadi tinjau hasilnya sebelum mendorong. Sebagai contoh:
git log --graph --oneline --decorate --date-order --color --boundary @{u}..
Saya lebih suka pendekatan ini git pull --rebasekarena alasan berikut:
- Ini memungkinkan Anda untuk melihat komit upstream yang masuk sebelum Anda mengubah riwayat Anda untuk memasukkannya.
- Ini memungkinkan Anda untuk meneruskan opsi
-p( --preserve-merges) git rebasejika Anda perlu melakukan rebase pada penggabungan yang disengaja (misalnya, menggabungkan cabang fitur yang sudah didorong ke master).
Singkatan: git upbukangit pull
Untuk mempermudah melakukan hal di atas, saya sarankan membuat alias bernama up:
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
Sekarang yang perlu Anda lakukan untuk memperbarui cabang Anda adalah menjalankan:
git up
bukannya git pull. Jika Anda mendapatkan kesalahan karena cabang lokal Anda menyimpang dari cabang hulu, itu isyarat Anda untuk melakukan rebase.
Mengapa tidak git pull --rebase?
Berlari git pull --rebasesetara dengan berlari git fetchdiikuti dengan git rebase. Ini mencoba untuk mempercepat ke komit upstream baru, tetapi jika itu tidak memungkinkan maka itu akan me-rebase komit lokal Anda ke komit upstream baru. Ini biasanya OK, tapi hati-hati:
- Rebase adalah topik lanjutan, dan Anda harus memahami implikasinya sebelum melakukan rebasing.
git pull --rebasetidak memberi Anda kesempatan untuk memeriksa komit sebelum memasukkannya. Tergantung pada apa yang berubah hulu, itu sangat mungkin bahwa rebase adalah salah operasi-a rebase --onto, merge, reset, atau push -fmungkin lebih tepat daripada polos rebase.
- Saat ini tidak mungkin untuk meneruskan
--preserve-mergeske operasi rebase, jadi setiap penggabungan yang disengaja dari cabang fitur akan dilinearisasi, mengulang (dan dengan demikian menggandakan) semua cabang fitur yang berkomitmen.
"Memperbaiki" komit penggabungan yang ada yang dibuat oleh git pull
Jika Anda belum mendorong komit penggabungan yang dibuat oleh git pull, Anda dapat menghapus kembali komit penggabungan. Dengan asumsi Anda belum membuat penggabungan yang disengaja (misalnya, menggabungkan cabang fitur yang sudah didorong ke cabang Anda saat ini), berikut ini yang harus dilakukan:
git rebase @{u}
Perintah di atas memberitahu Git untuk memilih semua komit non-gabungan yang dapat dijangkau dari HEAD(komit saat ini), dikurangi semua komitmen yang dapat dijangkau dari @{u}(yang merupakan singkatan dari "cabang upstream", yaitu, origin/masterjika HEADada master), putar ulang (cherry-pick ) di atas cabang upstream, lalu pindahkan referensi cabang saat ini untuk menunjukkan hasil dari pemutaran ulang komit. Ini secara efektif memindahkan komitmen non-penggabungan ke komit upstream terbaru, yang menghilangkan penggabungan yang dibuat oleh git pull.
Jika Anda memiliki komit penggabungan yang disengaja, Anda tidak ingin menjalankannya git rebase @{u}karena itu akan memutar ulang semuanya dari cabang lain. Menangani kasus ini jauh lebih rumit, oleh karena itu sebaiknya digunakan git updan dihindari git pullsama sekali. Anda mungkin harus menggunakan resetuntuk membatalkan penggabungan yang dibuat oleh pulldan kemudian melakukannya git rebase -p @{u}. The -pargumen untuk git rebasetidak bekerja andal untuk saya, sehingga Anda mungkin akhirnya harus menggunakan resetuntuk membatalkan penggabungan disengaja, memperbarui cabang lokal Anda untuk @{u}, dan kemudian mengulang gabungan disengaja (yang sakit jika ada banyak merge berbulu konflik).