Pisahkan cabang git menjadi beberapa cabang untuk digabungkan menjadi master

Tim saya telah mengerjakan cabang prototipe dari master. Saya sekarang ingin mengambil pekerjaan itu, membaginya menjadi "cabang fitur" yang berbeda, dan menggabungkannya satu per satu menjadi master. Saya melihat beberapa cara untuk melakukan ini, tidak satu pun yang saya sukai:

1 - Buat cabang baru, Feature_1, di luar master. Salin kode secara manual dari Prototipe ke Feature_1. Ini berarti saya harus melacak apa yang telah saya salin ketika saya membuat Feature_N dan saya kehilangan riwayat.

2 - Buat cabang baru, Feature_1, di luar Prototipe. Entah bagaimana, kembalikan kode yang bukan bagian dari fitur pertama di Feature_1. Ini untuk menghindari berbohong kepada git (dan menyimpan riwayat), tetapi rasanya Feature_N akan berantakan untuk digabungkan karena saya akan memberi tahu master bahwa perubahan telah dikembalikan ketika saya mendorong Feature_1.

Apakah saya melewatkan cara yang lebih baik untuk melakukan ini?


person JoeB    schedule 30.10.2014    source sumber


Jawaban (2)


Jawaban @ Michael adalah hal yang baik jika komitmen Anda adalah komitmen fitur tunggal yang tidak berbagi ketergantungan dengan komitmen untuk fitur lainnya. Namun, jika Anda telah menggabungkan pekerjaan pada dua fitur dalam penerapan apa pun, Anda memerlukan rebase interaktif. Hal ini memungkinkan Anda untuk secara sewenang-wenang mendistribusikan kembali bongkahan perubahan dan melakukan batasan, dan ia melacak bongkahan mana yang belum dikomit ke cabang saat ini.

Jika perubahan fitur hanya kadang-kadang digabungkan menjadi penerapan dan tidak ada ketergantungan lintas fitur, untuk mempermudah pekerjaan, percobaan pertama saya adalah git rebase -i master prototype, bagi penerapan dengan bongkahan campuran menjadi dua penerapan, satu untuk masing-masing penerapan, lalu akhiri dengan pilihan ceri seperti pada jawaban Michael. Diberikan

A1-B2-C12-D2-E1-F12    prototype

di mana angka menandakan fitur mana yang berisi kode komit, untuk `git rebase -i master prototype yang akan Anda edit komit C12 dan F12,

pick A1
pick B2
edit C12
pick D2
pick E1
edit F12

(menggunakan hash setiap komit alih-alih tag ilustratifnya di sini).

Rebase akan berhenti setelah melakukan C12, dan Anda dapat git reset HEAD~ lalu git add --patch untuk menerapkan semua bongkahan fitur-1, git commit untuk membuat komit C1 di mana C12 berada, lalu git commit -a untuk menerapkan semua bongkahan yang tersisa dan membuat komit C2 setelahnya. Anda akan berakhir dengan

A1-B1-C1-C2-D2-E1-F1-F2

dan Anda kemudian dapat git checkout -b feature1 master; git cherry-pick A1 B1 C1 E1 F1 dan demikian pula untuk fitur2.

Dalam situasi yang lebih rumit, metode ini masih berfungsi hanya dengan sedikit perubahan. Rebase interaktif jauh lebih baik daripada yang di atas mungkin membuat Anda percaya, namun sejauh ini cara terbaik untuk mengetahuinya adalah dengan mengunjungi halaman manual selagi Anda masuk ke sana dan berebut beberapa orang untuk bersenang-senang. Lakukan itu, dan mungkin akan segera sampai pada titik di mana melakukan ini sebagai ritual prapublikasi sering kali lebih nyaman daripada mencoba membuat alur kerja Anda yang sebenarnya dapat dipublikasikan di setiap langkah kecil.

person jthill    schedule 30.10.2014
comment
jika Anda melakukan git reset HEAD~ maka Anda perlu melakukan git commit normal (tanpa --amend) setelahnya untuk membuat komit baru C1. Jika tidak, git commit --amend akan mengedit (mengubah) komit sebelumnya (B2 dalam contoh ini) dan Anda akan mendapatkan ...-B12-C2-.... Alternatifnya, Anda dapat mengatur ulang hanya satu file dengan git reset HEAD~ /path/to/file yang akan membiarkan sisa komit tetap di tempatnya, sehingga Anda kemudian dapat memodifikasinya dengan git commit --amend. - person iliis; 03.02.2021
comment
@iliis benar, seharusnya git read-tree @~ bukan git reset @~ atau biasa git commit bukan git commit --amend. Terima kasih telah menunjukkan hal ini, sudah diperbaiki. - person jthill; 03.02.2021

Buat dua cabang feature_1 dan feature_2 dari master dan pilih komit dari prototype di cabang fitur terkait:

git checkout -b feature_1 master
git cherry-pick <commit>
git cherry-pick <commit>
…

git checkout -b feature_2 master
git cherry feature_1 prototype | grep "^+" | cut -c3- | xargs git cherry-pick

Baris terakhir cherry mengambil semua komit dari prototype yang tidak ada di feature_1 ke dalam cabang saat ini, yaitu feature_2.

Saat Anda mengalami konflik, gunakan git status sebagai petunjuk bagaimana melanjutkan.

Lihat git-cherry-pick untuk dokumentasi lebih lanjut.

person Michael    schedule 30.10.2014
comment
Kami sebenarnya juga telah menemukan pilihan lain saat berdiskusi di sini, saya akan mencobanya. - person JoeB; 30.10.2014
comment
Apakah ada cara untuk melakukan ini jika belum ada perubahan yang dilakukan? - person Michael; 06.02.2018
comment
Buat cabang baru, gunakan git add --patch untuk menambahkan perubahan yang ingin Anda lakukan di cabang ini (+ git add untuk file baru), komit, simpan perubahan yang tersisa, checkout cabang baru berdasarkan master (git checkout -b feature_2 master), tambahkan dan komit perubahan Anda. - person Michael; 07.02.2018