Apa cara terbaik (dan teraman) untuk menggabungkan cabang Git menjadi master?


2104

Cabang baru dari masterdibuat, kami menyebutnya test.

Ada beberapa pengembang yang berkomitmen masteratau membuat cabang lain dan kemudian bergabung master.

Katakanlah pekerjaan testsedang berlangsung beberapa hari dan Anda ingin terus testdiperbarui dengan komitmen di dalamnya master.

Saya akan lakukan git pull origin masterdari test.

Pertanyaan 1: Apakah ini pendekatan yang tepat? Pengembang lain dapat dengan mudah bekerja pada file yang sama seperti saya telah bekerja dengan baik.


Pekerjaan saya testselesai dan saya siap untuk menggabungkannya kembali master. Berikut adalah dua cara yang dapat saya pikirkan:

SEBUAH:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B:

git checkout test
git pull origin master
git checkout master
git merge test

Saya tidak menggunakan --rebasekarena dari pemahaman saya, rebase akan mendapatkan perubahan dari masterdan menumpuk milik saya di atas itu karena itu bisa menimpa perubahan yang dilakukan orang lain.

Pertanyaan 2: Mana dari dua metode ini yang benar? Apa bedanya di sana?

Tujuan dari semua ini adalah untuk menjaga testcabang saya diperbarui dengan hal-hal yang terjadi di dalam masterdan kemudian saya dapat menggabungkan mereka kembali dengan masterberharap untuk menjaga garis waktu ser lini mungkin.


18
tidak .. rebase tidak pernah menimpa, itu hanya berusaha mencapai sejarah yang lebih bersih. oleh reattach (atau palsu) sejarah ke titik akhir dari master
Junchen Liu

7
rebase tidak menimpa komitmen Anda. Ini membatalkan komit Anda, menerapkan komit di cabang master ke cabang tes Anda, lalu menerapkan komit Anda kembali untuk menguji.
zundi

Jawaban:


2994

Bagaimana saya akan melakukan ini

git checkout master
git pull origin master
git merge test
git push origin master

Jika saya memiliki cabang lokal dari yang jauh, saya tidak merasa nyaman dengan menggabungkan cabang lain dari yang ini dengan remote. Juga saya tidak akan mendorong perubahan saya, sampai saya senang dengan apa yang ingin saya dorong dan juga saya tidak akan mendorong semuanya, yang hanya untuk saya dan repositori lokal saya. Dalam uraian Anda tampaknya, itu testhanya untuk Anda? Jadi tidak ada alasan untuk mempublikasikannya.

git selalu berusaha menghargai perubahan Anda dan orang lain, dan demikian juga halnya --rebase. Saya rasa saya tidak bisa menjelaskannya dengan tepat, jadi lihatlah buku Git - Rebasing atau git-ready: Intro rebasing untuk penjelasan singkat. Ini fitur yang cukup keren


2
git merge testmemberi saya fatal: 'test' does not point to a commit. Saya harus mencari git logtitik komit di cabang tes, beralih kembali ke cabang master lalu lakukan git merge 0f37d3154abbf52a4cbbbb5109f08af6a7567234.
Duncanmoo

17
@Duncanmoo Yah, tentu saja cabang itu testharus ada. Tentu, Anda bisa menggunakan hash sebagai gantinya, tetapi biasanya lebih mudah menggunakan nama cabang. Secara internal itu hanya mengambil hash HEADcabang.
KingCrunch

44
@shanyangqu Untuk mendapatkan perubahan terbaru dari jarak jauh. Jika Anda bekerja sendiri dan hanya dengan satu sistem, tidak ada masalah. Tetapi ketika ada perubahan yang didorong dari sistem yang berbeda (mungkin dari pengembang yang berbeda) Anda akan melihat konflik segera setelah Anda mencoba untuk mendorong penggabungan Anda kembali (langkah ke-4). Satu-satunya solusi sekarang adalah menggabungkan master lokal Anda menjadi master remote, yang berakhir dengan "master gabungan yang jelek menjadi komit gabungan / master". Jadi itu selalu ide yang baik untuk melakukan tarikan sebelum penggabungan
KingCrunch

7
"Menurut uraianmu, tes itu hanya untukmu? Jadi tidak ada alasan untuk menerbitkannya." Anda mungkin ingin mendorong cabang lokal Anda ke server jika, misalnya, server itu menyediakan cadangan terhadap drive lokal Anda gagal atau jika Anda tidak memiliki cara lain untuk melakukan cadangan.
Eric

5
"... Juga aku tidak akan memaksakan perubahanku, sampai aku puas dengan apa yang ingin aku tekan ..." mengapa tidak mendorong demi memiliki kode yang didukung, kalau-kalau mesin lokal Anda mati dan hari-hari upaya hilang?
Rich Stone

400

Ini adalah pertanyaan yang sangat praktis, tetapi semua jawaban di atas tidak praktis.

Suka

git checkout master
git pull origin master
git merge test
git push origin master

Pendekatan ini memiliki dua masalah :

  1. Itu tidak aman, karena kita tidak tahu apakah ada konflik antara cabang uji dan cabang master.

  2. Itu akan "memeras" semua tes yang dilakukan menjadi satu gabungan komit pada master; artinya di cabang master, kita tidak bisa melihat semua log perubahan dari cabang uji.

Jadi, ketika kami menduga akan ada beberapa konflik, kami dapat melakukan operasi git berikut:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

Tes mergesebelumnya commit, hindari komitmen fast-forward oleh --no-ff,

Jika konflik ditemukan, kita dapat lari git statusuntuk memeriksa detail tentang konflik dan mencoba menyelesaikannya

git status

Begitu kita menyelesaikan konflik, atau jika tidak ada konflik, kita commitdan pushmereka

git commit -m 'merge test branch'
git push

Tetapi cara ini akan kehilangan histori perubahan yang dicatat dalam cabang uji, dan itu akan membuat cabang utama menjadi sulit bagi pengembang lain untuk memahami sejarah proyek.

Jadi metode terbaik adalah kita harus menggunakan rebasealih-alih merge(misalkan, saat ini, kita telah menyelesaikan konflik cabang).

Berikut ini adalah satu contoh sederhana, untuk operasi lanjutan, silakan merujuk ke http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

Yap, ketika Anda telah menyelesaikan bagian atasnya, semua komit dari cabang Uji akan dipindahkan ke kepala cabang Master. Manfaat utama rebasing adalah Anda mendapatkan sejarah proyek yang linier dan lebih bersih.

Satu-satunya hal yang perlu Anda hindari adalah: jangan pernah gunakan rebasedi cabang publik, seperti cabang utama.

Jangan pernah melakukan operasi seperti berikut:

git checkout master
git rebase -i test

Detail untuk https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

lampiran:


4
Saya setuju untuk memundurkan cabang tes untuk kemudian bergabung menjadi master adalah cara untuk maju. Bahkan jawaban lain benar, ini akan membuat sejarah perubahan uji cabang di kepala master sebagai auther menyebutkan "Anda mendapatkan proyek liner dan jauh lebih bersih" yang merupakan tujuan dari sistem kontrol versi.
le0diaz

16
Pernyataan "itu bukan satu cara yang aman, karena kita tidak tahu apakah ada konflik antara cabang uji dan cabang master" tidak benar: kita selalu dapat membatalkan penggabungan. Dan bahkan jika tidak ada konflik Anda selalu dapat membatalkan komit lokal terakhir selama tidak didorong. Tanpa pemahaman yang benar tentang git beberapa hal mungkin tampak sedikit menakutkan atau tidak jelas, tetapi "tidak aman" sama sekali tidak benar. Harap berhati-hati untuk tidak membingungkan orang lain dengan informasi yang salah.
Paul van Leeuwen

4
setuju dengan @PaulvanLeeuwen, ketika Anda git menggabungkan cabang uji menjadi master, Anda akan diberitahu tentang konflik, dan di situlah Anda akan masuk dan menggabungkan perubahan. Setelah selesai, Anda akan melakukan penggabungan dan mendorong kembali. Jika Anda menyesal atau tidak bisa menggabungkannya dengan benar, Anda selalu dapat membuang pekerjaan dan menarik dari master lagi. Jadi sudah pasti tidak aman ..
Juan

3
mengapa rebase -i?
MushyPeas

8
Rebasing secara inheren lebih tidak aman daripada bergabung. Mengusulkan rebasing sebagai opsi yang lebih aman untuk bergabung adalah salah. Rebasing adalah strategi yang valid, tetapi hadir dengan lebih banyak peringatan yang harus diwaspadai pengguna.
Ikke

90

Baik rebase maupun gabungan tidak boleh menimpa perubahan siapa pun (kecuali jika Anda memilih untuk melakukannya saat menyelesaikan konflik).

Pendekatan biasa saat berkembang adalah

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

Ketika Anda siap untuk bergabung kembali menjadi master,

git checkout master
git log ..test # if you're curious
git merge test
git push

Jika Anda khawatir tentang melanggar sesuatu pada penggabungan, git merge --abortapakah ada untuk Anda.

Menggunakan dorongan dan kemudian menarik sebagai sarana penggabungan adalah konyol. Saya juga tidak yakin mengapa Anda mendorong tes ke tempat asal.


1
Proses ini akan meningkatkan jumlah komit, setiap kali Anda berpindah antar cabang, Anda harus mengkomit cabang Anda.
iBug

2
Apa? Apakah Anda mengatakan itu akan menambah jumlah komit setiap kali Anda berganti cabang? Atau apakah Anda mengatakan bahwa setiap kali Anda berganti cabang, Anda harus "melakukan cabang Anda"? Yang pertama tidak benar dan saya tidak yakin apa artinya yang kedua.
raylu

sebelum checkout, Anda harus mengkomit cabang. itulah yang saya katakan
iBug

11
Anda tidak: itu (salah satu hal) git stashadalah untuk.
msanford

1
Atau Anda dapat mengubah komit terakhir Anda (di cabang lokal) dan menjadikannya komitmen sempurna sebelum mendorong.
whihathac

42

Pertama-tama saya akan membuat cabang yang akan digabung sebersih mungkin. Jalankan tes Anda, pastikan statusnya sesuai keinginan Anda. Bersihkan komit baru dengan git squash .

Selain jawaban KingCrunches , saya sarankan untuk menggunakannya

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

Anda mungkin telah membuat banyak komitmen di cabang lain, yang seharusnya hanya satu komit di cabang utama. Untuk menjaga riwayat komit sebersih mungkin, Anda mungkin ingin memeras semua komit Anda dari cabang uji menjadi satu komit di cabang master (lihat juga: Git: Untuk squash atau tidak untuk squash? ). Kemudian Anda juga dapat menulis ulang pesan komit ke sesuatu yang sangat ekspresif. Sesuatu yang mudah dibaca dan dipahami, tanpa menggali ke dalam kode.

sunting: Anda mungkin tertarik

Jadi pada GitHub, saya akhirnya melakukan hal berikut untuk cabang fitur mybranch:

Dapatkan yang terbaru dari asal

$ git checkout master
$ git pull origin master

Temukan hash basis gabungan:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

Sekarang pastikan hanya yang pertama pick, sisanyas :

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

Selanjutnya pilih pesan komit yang sangat baik dan dorong ke GitHub. Buat permintaan tarik itu.

Setelah penggabungan permintaan tarik, Anda dapat menghapusnya secara lokal:

$ git branch -d mybranch

dan di GitHub

$ git push origin :mybranch

" yang seharusnya hanya satu komit di cabang utama ", yah belum tentu; Anda mungkin ingin menyimpan sejarah
Cocowalla

Tentu. Tapi kemudian jangan menekan komitmen
Martin Thoma

Saya pikir --first-parent tampaknya menjadi solusi terbaik. davidchudzicki.com/posts/first-parent
bkribbs

7

Utas lama, tapi saya belum menemukan cara saya melakukannya. Mungkin bermanfaat bagi seseorang yang bekerja dengan rebase dan ingin menggabungkan semua komitmen dari cabang (fitur) di atas master. Jika ada konflik di jalan, Anda dapat menyelesaikannya untuk setiap komit. Anda tetap memegang kendali penuh selama proses dan dapat membatalkan kapan saja.

Dapatkan Master dan Cabang terkini:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

Gabungkan Cabang di atas Master:

git checkout <branch_name>
git rebase master

Opsional: Jika Anda mengalami Konflik selama Rebase:

Pertama, atasi konflik dalam file. Kemudian:

git add .
git rebase --continue

Dorong Cabang rebased Anda:

git push origin <branch_name>

Sekarang Anda punya dua opsi:

  • A) Buat PR (misalnya pada GitHub) dan gabungkan di sana melalui UI
  • B) Kembali pada baris perintah dan menggabungkan cabang menjadi master
git checkout master
git merge --no-ff <branch_name>
git push origin master

Selesai


6

Ini adalah alur kerja yang saya gunakan di pekerjaan saya dengan tim. Skenario seperti yang Anda gambarkan. Pertama, ketika saya selesai bekerja testsaya rebase dengan master untuk menarik apa pun yang telah ditambahkan ke master selama saya bekerja di testcabang.

git pull -r upstream master

Ini akan menarik perubahan untuk dikuasai sejak Anda bercabang testcabang dan menerapkannya, dan kemudian menerapkan perubahan yang Anda buat untuk menguji "di atas" kondisi master saat ini. Mungkin ada konflik di sini, jika orang lain telah membuat perubahan pada file yang sama yang telah Anda edit dalam pengujian. Jika ada, Anda harus memperbaikinya secara manual, dan melakukan. Setelah Anda selesai melakukannya, Anda akan baik untuk beralih ke cabang master dan bergabung testtanpa masalah.


3
git checkout master
git pull origin master
# Merge branch test into master
git merge test

Setelah penggabungan, jika file diubah, maka ketika Anda menggabungkannya akan melalui kesalahan "Selesaikan Konflik"

Jadi, Anda harus menyelesaikan semua konflik Anda terlebih dahulu, Anda harus melakukan lagi semua perubahan Anda dan kemudian mendorong

git push origin master

Ini lebih baik dilakukan siapa yang telah melakukan perubahan di cabang tes, karena dia tahu perubahan apa yang telah dilakukannya.


3

Saya akan menggunakan metode rebase. Terutama karena itu secara sempurna mencerminkan kasus Anda secara semantik, yaitu. yang ingin Anda lakukan adalah menyegarkan keadaan cabang Anda saat ini dan "berpura-pura" seolah-olah itu didasarkan pada yang terbaru.

Jadi, tanpa memeriksa master, saya akan:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

Tentu saja, hanya mengambil dari tempat asal tidak menyegarkan keadaan lokal Anda master(karena tidak melakukan penggabungan), tetapi sangat baik untuk tujuan kami - kami ingin menghindari beralih, demi menghemat waktu.


2

@Jawaban KingCrunch harus bekerja dalam banyak kasus. Salah satu masalah yang dapat muncul adalah Anda mungkin berada pada mesin yang berbeda yang perlu menarik yang terbaru dari pengujian. Jadi, saya sarankan menarik tes terlebih dahulu. Revisi terlihat seperti ini:

git checkout test
git pull
git checkout master
git pull origin master
git merge test
git push origin master

0

Anda harus memeriksa cabang untuk menarik, karena menarik berarti menggabungkan diri dengan master, dan Anda memerlukan pohon kerja untuk bergabung.

git checkout master
git pull

Tidak perlu memeriksa dulu; rebase melakukan hal yang benar dengan dua argumen

git rebase master test  

git checkout master
git merge test

git push secara default mendorong semua cabang yang ada di sini dan di remote

git push
git checkout test

0

Seperti judulnya "Cara terbaik", saya pikir itu ide yang baik untuk mempertimbangkan strategi kesabaran menggabungkan.

Dari: https://git-scm.com/docs/merge-strategies

Dengan opsi ini, 'merge-rekursif' menghabiskan sedikit waktu ekstra untuk menghindari mismerges yang kadang-kadang terjadi karena garis pencocokan yang tidak penting (mis. Kawat gigi dari fungsi yang berbeda). Gunakan ini ketika cabang yang akan digabung telah menyimpang secara liar. Lihat juga git-diff [1] --patience.

Pemakaian:

git fetch
git merge -s recursive -X patience origin/master

Git Alias

Saya selalu menggunakan alias untuk ini, misalnya jalankan sekali:

 git config --global alias.pmerge 'merge -s recursive -X patience'

Sekarang Anda bisa melakukannya:

git fetch
git pmerge origin/master


0

Saya akan menjawab sesuai mengembangkan dan fitur cabang,

jika Anda menggunakan fitur branch dan perlu memperbaruinya dengan perintah use use di bawah ini: git checkout mengembangkan fitur git pull git checkout / xyz git merge mengembangkan

Sekarang fitur Anda diperbarui dengan pengembangan Anda dapat mendorong perubahan Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.