git pull
mungkin membuat komit. Jika Anda membuat komit lokal dan kemudian menjalankan git pull
setelah 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 --rebase
untuk mencegah hal ini terjadi di masa mendatang, tetapi rebasing memiliki risiko sendiri, dan saya sarankan untuk menghindarinya pull
sama 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 -p
mengunduh 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 -p
plum Argumen dihapus cabang hulu. Dengan demikian, jika foo
cabang tersebut terhapus di origin
repositori, git remote update -p
otomatis origin/foo
ref 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 -p
pilihan 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 master
sebagai bagian dari linierisasi yang dilakukan oleh git rebase
. Ini akan membuat riwayat perkembangan lebih sulit untuk ditinjau, bukan lebih mudah.
Waspadalah : git rebase
mungkin 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 --rebase
karena 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 rebase
jika Anda perlu melakukan rebase pada penggabungan yang disengaja (misalnya, menggabungkan cabang fitur yang sudah didorong ke master
).
Singkatan: git up
bukangit 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 --rebase
setara dengan berlari git fetch
diikuti 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 --rebase
tidak 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 -f
mungkin lebih tepat daripada polos rebase
.
- Saat ini tidak mungkin untuk meneruskan
--preserve-merges
ke 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/master
jika HEAD
ada 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 up
dan dihindari git pull
sama sekali. Anda mungkin harus menggunakan reset
untuk membatalkan penggabungan yang dibuat oleh pull
dan kemudian melakukannya git rebase -p @{u}
. The -p
argumen untuk git rebase
tidak bekerja andal untuk saya, sehingga Anda mungkin akhirnya harus menggunakan reset
untuk membatalkan penggabungan disengaja, memperbarui cabang lokal Anda untuk @{u}
, dan kemudian mengulang gabungan disengaja (yang sakit jika ada banyak merge berbulu konflik).