Git pull menghasilkan pesan "Gabung cabang" yang tidak relevan di log komit

110

Saya bekerja dengan pengembang lain dalam sebuah proyek, dan kami menggunakan Github sebagai repo jarak jauh kami. Saya menggunakan Mac menggunakan git 1.7.7.3, dia menggunakan Windows menggunakan git 1.7.6.

Inilah yang terjadi

  1. Salah satu dari kami (sebut saja dia developer A, tapi tidak masalah yang mana) mendorong satu set commit ke GitHub.
  2. Yang lainnya (pengembang B) membuat beberapa komitmen lokal.
  3. B melakukan a git pull.
  4. B melakukan a git push.
  5. Melihat log riwayat komit, saya melihat Gabungkan cabang 'master' dari github.com:foo/bar

Log komit dikotori dengan pesan "Gabungkan cabang" dari waktu ke waktu, dan juga menunjukkan pengembang B sebagai melakukan perubahan yang dibuat oleh pengembang A. Satu-satunya cara yang kami temukan untuk mencegah masalah ini adalah dengan melakukan git pull --rebaselangkah 3, tetapi saya tidak tahu efek samping apa yang akan ditimbulkan oleh rebasing. Ini pertama kalinya saya mengerjakan repo git multi-developer, jadi apakah ini hanya perilaku normal? Ada pemikiran tentang cara mengatasi masalah ini?

mshafrir.dll
sumber
2
Anda dapat melihat log tanpa penggabungan dengangit log --no-merges
wjandrea

Jawaban:

88

Komitmen yang Anda lihat baik-baik saja. A pullberjalan secara efektif git fetchdan kemudian git mergepenggabungan biasanya terjadi saat Anda menjalankan git pull.

Alternatif untuk menggunakan rebasing daripada penggabungan dimungkinkan, tetapi biasanya Anda harus menghindarinya. Rebasing memungkinkan Anda menyimpan riwayat linier, tetapi juga menghapus informasi apa pun tentang percabangan yang awalnya terjadi. Ini juga akan menyebabkan riwayat cabang saat ini ditulis ulang, membuat ulang semua komit yang tidak terdapat dalam cabang target (dalam kasus Anda, remote). Karena komit yang dibuat ulang adalah komit yang berbeda , ini dapat menyebabkan banyak kebingungan saat mengembangkan bersama dengan yang lain, terutama saat orang sudah memeriksa bagian dari komit tersebut sebelum ditulis ulang (misalnya dengan cabang fitur). Jadi sebagai aturan praktis, Anda tidak boleh menulis ulang komit apa pun yang sudah didorong.

Komit yang Anda lihat ada untuk menggabungkan dua (atau lebih) cabang. Tidak masalah untuk memiliki komit yang tidak melakukan apa-apa selain menggabungkan beberapa cabang. Bahkan itu membuatnya sangat jelas saat Anda memiliki komit gabungan yang menggabungkan cabang saat melihat riwayat. Dibandingkan dengan rebasing, penggabungan juga memungkinkan Anda melihat riwayat asli secara efektif saat dikembangkan, termasuk cabang sebenarnya yang hidup berdampingan.

Singkat cerita: Ya, memiliki komit gabungan tidak apa-apa dan Anda tidak perlu mengkhawatirkannya.

menyodok
sumber
2
Jawaban yang sangat bagus. Saya sendiri mencoba gaya rebase karena direkomendasikan di beberapa pedoman kontribusi proyek open source, dan itu menimbulkan masalah bagi saya. Seorang anggota baru di tim juga memiliki hal yang sama. Saya pikir opsi rebase bukan untuk tim yang bekerja bersama sepanjang hari, tetapi benar untuk proyek yang memiliki kontributor utama dan kontributor lain yang baru saja mengirimkan tambalan. Mereka seharusnya baik-baik saja saat mengambil repo utama dan mengubah peringkat perubahannya tepat sebelum mengeluarkan permintaan tarik.
Meligy
2
@sTodorov Jika tidak ada perubahan baru, maka fetch-part dari tarikan tidak akan melakukan apa-apa, tetapi penggabungan masih dijalankan. Jadi jika cabang lokal Anda saat ini tidak up-to-date, itu akan menggabungkan perubahan baru ke dalam cabang Anda. Dan jika tidak dapat melakukan penggabungan maju cepat (jika Anda memiliki komitmen divergen), maka itu akan membuat komit penggabungan.
aduk
28
Jawaban ini membuatnya tampak seperti menggunakan rebase seperti yang dijelaskan OP berbahaya, tetapi sebenarnya tidak. Rebasing pada langkah 3 tidak menulis ulang seluruh histori. Hanya komit lokal yang belum didorong yang ditulis ulang dengan diterapkan kembali di atas HEAD baru (komit terbaru didorong ke cabang itu). Ini mencegah komit penggabungan asing dan tidak memiliki efek samping lain.
bob esponja
1
@bobesponja Semua komit yang tidak berada di cabang jarak jauh yang ditarik akan ditulis ulang. Ini dapat mencakup komit yang diterbitkan dari cabang lain, misalnya dengan cabang fitur, yang mungkin sudah diakses orang lain sebelumnya. Karena itu, ya, melakukan rebasing tanpa memikirkan apa yang Anda rebase agak berbahaya.
aduk
1
@bobesponja Ya, jika Anda menerbitkan cabang fitur Anda lebih awal (karena orang lain mengerjakannya, atau hanya sebagai cadangan), maka Anda tidak boleh mem-rebase karena orang lain mungkin sudah mengambilnya. Rebasing kemudian — seperti yang Anda katakan sendiri — bertentangan dengan pedoman rebasing yang saya nyatakan dalam jawaban saya. Namun, jika Anda tidak memublikasikan komit Anda, maka rebasing baik-baik saja jika Anda mau dan tidak keberatan dengan riwayat linier. Tetapi itu tergantung pada cara Anda bekerja, jadi jawaban umum adalah menghindarinya kecuali jika benar-benar aman. Btw. Saya merevisi jawaban saya, jadi jika masalah teratasi, saya akan sangat menghargai jika Anda menghapus suara negatif Anda.
aduk
48

Jawaban ini telah direvisi, karena pemahaman, diagram, dan kesimpulan saya salah.


git pullmenyebabkan merge commit karena git sedang menggabungkan. Ini dapat diubah dengan mengatur cabang Anda untuk menggunakan rebase daripada merge. Menggunakan rebase daripada merge on a pull memberikan histori yang lebih linier ke repositori bersama. Di sisi lain, komit gabungan menunjukkan upaya pengembangan paralel di cabang.

Misalnya, dua orang bekerja di cabang yang sama. Cabang dimulai sebagai:

...->C1

Orang pertama menyelesaikan pekerjaannya dan mendorong ke cabang:

...->C1->C2

Orang kedua menyelesaikan pekerjaan mereka dan ingin mendorong, tetapi tidak bisa karena mereka perlu memperbarui. Repositori lokal untuk orang kedua terlihat seperti:

...->C1->C3

Jika tarikan diatur untuk digabungkan, repositori orang kedua akan terlihat seperti ini.

...->C1->C3->M1
      \      /
       ->C2->

Dimana M1 adalah komit gabungan. Sejarah cabang baru ini akan didorong ke repo. Jika sebaliknya, tarikan diatur ke rebase, repo lokal akan terlihat seperti:

...->C1->C2->C3

Tidak ada komit gabungan. Sejarah telah dibuat lebih linier.

Kedua pilihan tersebut mencerminkan sejarah cabang tersebut. git memungkinkan Anda untuk memilih riwayat mana yang Anda sukai.

Memang ada tempat di mana rebase dapat menyebabkan masalah dengan cabang yang jauh. Ini bukan salah satu dari kasus tersebut. Kami lebih suka menggunakan rebase karena ini menyederhanakan riwayat cabang yang sudah rumit serta menunjukkan versi riwayat yang berhubungan dengan repositori bersama.

Anda dapat menyetel branch.autosetuprebase = selalu agar git secara otomatis membuat cabang jarak jauh Anda sebagai rebase, bukan master.

git config --global branch.autosetuprebase always

Pengaturan ini menyebabkan git secara otomatis membuat pengaturan konfigurasi untuk setiap cabang jarak jauh:

branch.<branchname>.rebase=true

Anda dapat menyetelnya sendiri untuk cabang jarak jauh Anda yang sudah disiapkan.

git config branch.<branchname>.rebase true

Saya ingin berterima kasih kepada @LaurensHolst karena telah mempertanyakan dan mengejar pernyataan saya sebelumnya. Saya pasti telah belajar lebih banyak tentang bagaimana git bekerja dengan komit pull and merge.

Untuk informasi lebih lanjut tentang merge commits, Anda dapat membaca Berkontribusi pada Proyek di ProGit-Book . Bagian Tim Kecil Pribadi menunjukkan komitmen gabungan.

Bill Door
sumber
7
“Menggunakan rebase alih-alih merge on a pull memberikan riwayat yang benar ke repositori bersama. Menggunakan penggabungan memberikan sejarah yang salah. " - Apa alasan yang mendukung pernyataan yang agak berani ini? Tidak mungkin sejarah dengan penggabungan adalah 'sejarah palsu'. Ini adalah penggambaran yang akurat tentang urutan terjadinya sesuatu. Apa yang Anda lakukan dengan rebasing sebenarnya mengubah riwayat, untuk membuat versi yang sedikit lebih linier. Anda mengorbankan akurasi untuk estetika. Mungkin sesuatu yang lebih Anda sukai, tetapi tidak lebih jujur.
Laurens Holst
2
Menggunakan rebase dan bukan merge tidak mengorbankan akurasi demi estetika. Kami menggunakan --no-ff untuk penggabungan, jadi estetika bukanlah persyaratan. Akurasi adalah keinginan. Rebase memberikan akurasi itu.
Bill Door
2
Bagaimana sejarah rebased lebih akurat? Anda tidak mengklarifikasi ini, dan saya tidak melihat bagaimana jadinya.
Laurens Holst
1
Sejarah adalah cerminan waktu di mana komit terjadi di repo bersama . Suatu hari 1, repo bersama melihat commit C2. Pada hari ke 2, repo bersama melihat commit C3. Jika C3 datang sebelum C2 maka refleksi waktu tidak akan benar. C3 tidak datang sebelum C2. Semua rebase itu, lakukan adalah mengatur ulang komit pada repositori lokal untuk mencerminkan dengan benar riwayat yang ditunjukkan oleh repositori bersama.
Bill Door
6
Pertanyaan Anda membuat saya meninjau pemahaman saya tentang komit gabungan. Diagram saya salah. Saya merevisi diskusi. Kesimpulan saya juga salah. Sejarah rebase dan merge sama-sama benar. Anda bisa membuat pilihan sendiri.
Bill Door
11

Anda dapat melakukan:

git pull --rebase

Namun, ini akan selalu menempatkan perubahan Anda di atas kolaborator Anda. Tapi Anda tidak akan mendapatkan pesan gabungan yang mencemari.

rajin
sumber
9

Sebenarnya ada jawaban yang lebih sederhana untuk ini. Mintalah pengembang B melakukan penarikan SEBELUM membuat komitmennya. Ini akan mencegah komit penggabungan tersebut, karena disebabkan oleh riwayat yang Anda buat di repo lokal dari komit lokal Anda yang mencoba untuk menggabungkan dengan riwayat komit pada repo jarak jauh. Jika Anda mendapatkan pesan yang mengatakan sesuatu di sepanjang baris 'perubahan akan ditimpa' saat melakukan penarikan, itu berarti Anda berdua menyentuh file yang sama, jadi lakukan:

git stash
git pull
git stash pop

maka Anda dapat menyelesaikan konflik penggabungan jika ada.

Luke
sumber
Yang paling mengganggu dan mencemaskan adalah konflik gabungan. Saya lebih suka menghindarinya
Hijau
1
@Green Jika Anda khawatir tentang konflik penggabungan maka git pull pun tidak berbeda.
Zoso
Kecuali satu saat ketika Anda lupa di stashhadapan Anda pull. Ugh git mengharuskan saya untuk berada di puncak permainan saya sepanjang waktu.
linuxNoob
Perlu git pull --rebasemengintegrasikan perubahan jarak jauh sebelum perubahan lokal, apa pun.
vonbrand
7

Melakukan git pull akan memasukkan pesan "Merge branch", itulah yang dilakukannya. Dengan melakukan git pull, Anda telah menggabungkan cabang jarak jauh ke cabang lokal Anda.

Saat Anda melakukan git pull dan terjadi konflik, git log akan menampilkan pembaruan ke file yang konflik sebagai berasal dari pengguna yang menyelesaikan konflik. Saya berasumsi ini karena orang yang memperbaiki konflik melakukan kembali file tersebut.

Sejauh yang saya tahu, begitulah cara kerja git, dan tidak ada jalan lain.

Rebasing akan menghapus riwayat git, jadi Anda tidak akan dapat melihat saat penggabungan terjadi.

kclair.dll
sumber