Bekerja pada cabang dengan ketergantungan pada cabang lain yang sedang ditinjau

65

Bagaimana git membantu menangani skenario di bawah ini:

Saya memiliki tugas yang dibagi menjadi 2 bagian: tugas backend dan tugas frontend. Saya membuat permintaan tarik untuk menggabungkan perubahan backend dan menunggu untuk digabung (dan mengatasi umpan balik). Sambil menunggu, saya tidak bisa benar-benar bekerja pada perubahan frontend karena itu tergantung pada perubahan backend dan itu belum tersedia di cabang master.

Apa cara terbaik untuk menarik perubahan ke cabang perubahan frontend dari cabang perubahan backend saat sedang ditinjau?

sul4bh
sumber
14
Yah biasanya, antarmuka proyek back end harus didefinisikan dengan jelas. Jadi ketika memulai implementasi front end Anda, seharusnya tidak mengganggu Anda, jika logika back end masih ditinjau, karena Anda dapat menggunakan mock up.
Herr Derb
17
@HerrDerb Oh anak musim panas yang manis ...
gardenhead
4
Mengapa Anda tidak dapat menulisnya dengan kode backend Anda yang belum ditinjau?
user253751
Apakah tim Anda memiliki semacam teknik yang disepakati untuk menangani situasi ini? Jika tidak, mungkin Anda harus menyetujui hal seperti ini, karena ini adalah situasi yang cukup umum.
Radu Murzea
Tidak ada. Itulah alasan mengapa saya menanyakan pertanyaan ini. Saya mendapat saran yang sangat bagus. Saya akan mencoba saran dan melihat bagaimana mereka bekerja untuk saya.
sul4bh

Jawaban:

42

Saya terkadang memiliki masalah ini. Git sangat fleksibel. Inilah salah satu cara Anda dapat melakukannya.

Cabang pertama Anda featureAsiap ditinjau.

Cabang kedua Anda featureBsedang dalam pengembangan dan tergantung pada kode di featureAcabang tersebut.

Gabungkan featureAcabang ke featureBcabang.

Jika Anda membuat perubahan pada featureAcabang maka Anda harus menggabungkan featureAcabang ke featureBcabang lagi untuk memasukkan perubahan.

Anda juga harus memastikan untuk bergabung featureAke dalam trunk utama terlebih dahulu, jika tidak ketika Anda menggabungkan featureBke trunk utama Anda secara tidak sengaja juga akan bergabung featureA. Setelah featureAdigabungkan ke dalam bagasi utama Anda dapat menyingkirkan featureAcabang karena featureBhanya tergantung pada bagasi utama sekarang.

Saya lebih suka ketika cabang fitur saya tidak saling bergantung tetapi kadang-kadang mereka melakukannya dan Anda harus menggunakannya.

Mat
sumber
Ini masuk akal. Apakah ini memungkinkan untuk membatalkan penggabungan featureAke featureBjika perlu?
sul4bh
8
Tidak ada operasi yang dibatalkan tetapi seperti @ 9000 menyebutkan, Anda bisa membuat cabang baru dan memilih komit yang Anda inginkan dari featureAitu jika Anda harus memulai dari awal lagi. Ada baiknya menganggap cabang Git sebagai disposable. Mereka murah dan mudah, Anda selalu dapat membuat cabang baru. Anda bahkan bisa membuat cabang uji dari featureBcabang Anda jika Anda ingin bermain-main dengan sesuatu yang Anda tidak yakin, dan kemudian memo itu jika tidak berhasil, atau gabungkan kembali ke featureBcabang Anda jika itu benar.
Matt
9
Penggabungan akan membuat kekacauan yang akan sulit (bukan tidak mungkin) untuk dibatalkan. Saya akan memasang kembali cherry-pick atau rebase (yaitu: cherry-pick semuanya di featureA di dasar featureB). Lihat jawaban 9000.
Pierre.Sassoulas
1
Ini menciptakan sejarah yang kompleks yang akan menjadi masalah selama bertahun-tahun yang akan datang setiap kali seseorang ingin memahami kode apa yang diubah untuk featureA dan featureB
Ian
2
jika featureA diperbarui, featureB harus diubah kembali tidak digabung
Lyndon White
42

Tunggu, lewati penggabungan

Untuk pendekatan ini, Anda tidak ingin menggabungkan feature_ake dalam feature_bberulang kali.

Rebasing telah disebutkan dalam jawaban lain, tetapi hanya untuk rebasing master. Apa yang ingin Anda lakukan dalam kasus Anda adalah:

  • Mulai feature_bdari Anda feature_a, yaitu:

    git checkout feature_a
    git checkout -b feature_b
    
  • Setiap kali feature_aperubahan saat menunggu untuk digabungkan master, Anda rebase feature_b di atasnya:

    ... commit something onto feature_a ...
    git checkout feature_b
    git rebase feature_a
    
  • Akhirnya, segera setelah feature_adigabungkan master, Anda hanya mendapatkan yang baru masterdan rebase feature_ake atasnya untuk yang terakhir kali:

    git checkout master
    git pull origin master
    git checkout feature_b
    git rebase --onto master feature_a feature_b
    

    Rebase akhir ini akan mencangkokkan semua komit yang menggantung dari feature_akomit (yang sekarang tidak relevan karena telah digabungkan ke dalam master) langsung ke master. feature_bCabang Anda sekarang sederhana, standar langsung dari master.

EDIT: terinspirasi dari komentar, sedikit kepala di atas: jika Anda perlu membuat beberapa perubahan yang memengaruhi kedua fitur, maka pastikan untuk membuatnya feature_a(dan kemudian rebase seperti yang ditunjukkan). Jangan tidak membuatnya dalam dua komit yang berbeda di kedua cabang, bahkan jika mungkin menggoda; seperti feature_abagian dari sejarah feature_b, memiliki satu perubahan dalam dua komit yang berbeda akan secara semantik salah dan mungkin mengarah pada konflik atau "kebangkitan" kode yang tidak diinginkan, kemudian.

AnoE
sumber
2
Dengan rebasing feature_abeberapa kali, nanti Anda mungkin akan mengalami masalah, ketika feature_aitu sendiri telah direstrukturisasi sementara itu. Sebagai hasil dari menjalankan git checkout feature_b; git rebase feature_aAnda mungkin mendapatkan konflik atau komit lucu yang mengandung komit mengembalikan perubahan baru feature_a. Ini biasanya dipecahkan dengan menggunakan --interactivedan melewatkan komit yang diambil dari versi lama dari cabang lain (saya harus melakukan ini beberapa kali baru-baru ini).
maaartinus
@maaartinus, terima kasih untuk kepala-up, saya belum mengalami masalah seperti itu sendiri. Seperti rebasehalnya banyak langkah individual daripada langkah sederhana merge, pasti ada peluang yang jauh lebih tinggi untuk menciptakan konflik; di sisi lain mergehanya semantik yang benar-benar salah untuk dilakukan dalam kasus ini.
AnoE
Saya kira, mergeakan memiliki masalah yang sama atau lebih buruk (konflik tidak seburuk mendapatkan perubahan yang tidak diinginkan). Saya melihat cabang sebagai urutan perubahan yang diinginkan yang didahului oleh banyak perubahan yang tidak terkait (secara logis milik cabang yang berbeda). Ketika berulang kali rebasing dengan cabang yang sama, saya selalu menghapus perubahan yang tidak terkait karena saya tahu mereka akan tetap masuk (mungkin dalam bentuk yang diperbarui) dan itu berfungsi dengan baik.
maaartinus
1
@maaartinus, saya telah menambahkan adendum kecil tentang ini (untuk secara konsisten membuat perubahan yang perlu masuk ke kedua cabang hanya di cabang dasar, bukan dalam dua komitmen yang berbeda).
AnoE
Teknik yang bagus. Begitulah cara saya selalu melakukannya juga. git rebase --ontoFTW: D
Radu Murzea
29

Anda sudah memiliki cabang tempat setiap cabang fitur Anda bergantung, dan yang terus berubah. Itu disebut master.

Cara khas agar cabang fitur tetap sinkron masteradalah tetap di atasnya. Ketika masterberubah, Anda biasanya git fetch origin master:master && git rebase masterdi direktori kerja cabang Anda.

Anda dapat melakukan hal yang sama dengan cabang fitur lain: tetap ambil dan rebasing di atasnya.

Jika, untuk beberapa alasan, Anda akan perlu untuk memindahkan perubahan pada cabang yang berbeda, Anda dapat ceri-memilih Anda komit, yang tidak pernah dicampur dengan komit cabang lain.

9000
sumber
Tapi saya pikir skenarionya adalah fitur-b membutuhkan kode yang ada di fitur-a, bercabang dari master tidak akan sangat membantu. Di mana saya harus mulai? Haruskah saya bercabang dari fitur-a dan menjaga mereka tetap sinkron sampai fitur-a diintegrasikan kembali dengan master, dan kemudian rebase dari master ke fitur-b?
Sinaesthetic
@Sinesthetic: Tentu saja Anda dapat feature-bmengandalkan feature-a, dan melakukan rebase dari waktu ke waktu seperti feature-ayang berubah. Ini adalah cara khas untuk membuat perubahan besar dapat diamati: pisah menjadi part-A(berdasarkan master), part-B(berdasarkan part-A), dan lebih banyak lagi jika diperlukan. Kemudian buat permintaan tarik untuk setiap bagian, dan pengulas lebih mudah melihat bagian yang lebih kecil dan dikelompokkan secara logis.
9000
Apakah masalah jika saya rebase bagian-b dengan bagian-a vs bagian-b dengan master dalam hal PR? Saya hanya ingin memastikan bahwa perubahan saya tidak menampilkan perubahan bagian-a seperti perubahan di bagian-b. Juga, jika saya menggabungkan vs rebase, bagaimana itu akan mempengaruhi bagian-b PR? Setiap kali saya pikir saya mengerti efeknya, saya mendapatkan hasil yang berbeda lol
Sinaesthetic
5

Dalam kasus ini di mana tugas frontend memiliki ketergantungan kritis pada kode backend, dan Anda ingin mulai bekerja di frontend sebelum backend diselesaikan dan diterima pada master, saya hanya akan memulai tugas frontend sebagai cabang fitur yang keluar dari backend branch, daripada bercabang frontend pada master.

Cabang fitur yang cukup lama perlu menggabungkan perubahan dari master secara berkala (untuk memastikan Anda merekonsiliasi penggabungan atau konflik semantik sebagai bagian dari pekerjaan pengembangan di cabang fitur, bukan sebagai bagian dari "review, qa, merge- untuk menguasai "proses). Jadi Anda melakukannya di cabang ujung depan Anda, dan ketika pekerjaan backend telah diterima untuk dikuasai, Anda akan mendapatkan perubahan kecil apa pun yang dilakukan pada backend sebagai bagian dari tinjauan / penerimaan secara otomatis, dengan rute yang sama dengan yang Anda inginkan. dapatkan perubahan kode lainnya pada master.

Jika ternyata cabang backend membutuhkan lebih banyak pekerjaan dan terus berubah selama periode waktu sebelum digabungkan untuk dikuasai (katakanlah jika masalah utama ditemukan selama peninjauan), maka Anda mungkin ingin melakukan penggabungan berkala secara langsung dari cabang backend ke cabang frontend (jadi Anda tidak terus mendasarkan semua pekerjaan frontend Anda pada kode backend usang). Ini mudah jika Anda adalah satu-satunya pengembang yang melakukan kedua fitur (karena Anda tahu jika Anda sendiri membuat perubahan besar), tetapi bahkan jika kedua fitur tersebut akhirnya dikerjakan secara paralel oleh pengembang yang berbeda, itu harus baik-baik saja; Anda hanya perlu tetap berkomunikasi (yang perlu Anda lakukan, jika Anda mengerjakan tugas secara paralel di mana satu memiliki ketergantungan kritis terhadap yang lain).

Jika ternyata seluruh cabang backend perlu ditinggalkan dan tidak akan pernah digabung (sepertinya ini akan menjadi masalah yang cukup besar yang jarang terjadi), maka Anda baik-baik saja memilih komitmen Anda ke cabang baru yang berasal dari master tanpa kerja backend, atau Anda menerapkan komit terbalik yang menghapus semua kode backend ke cabang frontend. Tapi seperti yang saya lihat, akan lebih mungkin untuk menghentikan pekerjaan frontend sampai Anda tahu apa yang akan menggantikan backend yang Anda buang, dan kemudian memutuskan apa yang harus dilakukan.

Ben
sumber
2

Saya tidak melihat masalah di sini.

Anda sudah memiliki ini setiap waktu dengan mastercabang Anda , yang terus berubah saat fitur dikembangkan dan kemudian digabung.

Jadi, dalam contoh konkret Anda, Anda pertama kali membuat feature_xxx_backendcabang dan mengembangkan perubahan backend. Ketika ini selesai, cabang akan meninjau dan akan digabung menjadi mastersetelah review selesai.

Jadi, cukup mulai cabang lain feature_yyy_frontend,. Anda mungkin ingin bercabang langsung feature_xxx_backend, sehingga Anda sudah memiliki perubahan-perubahan itu di branc Anda. kemudian cukup mengembangkan fitur frontend asif cabang master.

Ketika feature_xxx_backendcabang berubah, misalnya karena ada hal-hal yang muncul selama peninjauan yang perlu ditekankan, lakukan saja perubahan ini dan gabungkan mereka ke dalam feature_yyy_frontendcabang. Kemudian lanjutkan di cabang frontend.

Setelah peninjauan cabang backend selesai, itu akan digabung menjadi master. Pada titik ini, akan lebih bijaksana untuk rebase yang feature_yyy_frontendcabang ke master, sehingga pengulas hanya perlu meninjau baru perubahan yang cabang ini memberikan kontribusi untuk master, dan tidak perlu meninjau ulang perubahan yang dibuat untuk backend (yang telah disetujui ).

Ini juga dapat dilakukan ketika Anda memiliki dua, tiga atau lebih cabang tergantung. Jika Anda memiliki dua cabang fitur yang Anda andalkan, sederhana buatlah cabang turunan yang menggabungkan kedua fitur. Cabang dari sana, kembangkan fitur ketiga, gabungkan kedua cabang fitur di sepanjang jalan ketika masing-masing berubah. Ketika kedua fitur selesai dan digabung ke salah satu cabang yang diturunkan, rebase ke itu, atau jika mereka digabung menjadi master, rebase ke master.

Rebasing (seperti yang disarankan di atas) sangat kuat dan membantu menjaga log perubahan yang bersih, membuat ulasan menjadi lebih mudah.

Polygnome
sumber
2

Seperti yang disebutkan Polygnome, Anda sebenarnya bisa menggabungkan cabang frontend Anda dengan cabang backend Anda alih-alih master. Bahkan dengan pengaturan cabang saat ini yang Anda miliki sekarang, Anda dapat melakukannya:

git checkout frontend
git merge backend

atau sederhana

git merge backend frontend

Perlu diingat bahwa jika perubahan backend tidak diterima dan diperlukan lebih banyak pekerjaan, Anda harus menggabungkan pembaruan dari backend ke frontend untuk menghindari konflik. Setelah perubahan diterima ke master, Anda bisa rebase frontend Anda pada master untuk menyingkirkan komitmen backend merge.

Secara teknis Anda juga bisa melakukan semuanya dengan rebase, tetapi itu akan mengacaukan sejarah commit dari cabang frontend Anda. Dari mana saya berasal, ini dianggap praktik yang buruk. YMMV

Joris Meys
sumber
"Aneh bahwa tidak ada yang menyebutkan bahwa Anda benar-benar dapat menggabungkan cabang frontend Anda dengan cabang backend Anda, bukan master:" Ini telah disebutkan, misalnya dalam jawaban saya sendiri.
Polygnome
@Polygnome frontend tidak harus bercabang langsung dari backend. Keduanya bisa bercabang dari master juga, tetapi Anda masih bisa menggabungkannya. Jadi jawaban Anda sebenarnya tidak menyebutkan itu.
Joris Meys
Sebenarnya, jawaban saya tidak menyarankan Anda bercabang langsung dari backend, itu hanya berarti bahwa itu mungkin rute untuk pergi (karena Anda menggabungkan perubahan-perubahan itu ke cabang frontend lagian).
Polygnome
@ Polygnome maka saya salah mengerti jawaban Anda. Diperbarui khusus untuk Anda :-)
Joris Meys
Saya tidak tahu siapa yang menurunkan ini, tapi tolong katakan di mana saya salah, jadi saya bisa belajar sesuatu juga.
Joris Meys
1

Sebagian besar jawaban di sini dengan benar menjelaskan proses menggabungkan perubahan dari cabang kedua ke yang pertama, tetapi mereka tidak membahas cara meminimalkan jumlah konflik yang mungkin perlu Anda selesaikan.

Setiap kali Anda memiliki dua set perubahan besar yang ingin Anda tinjau secara individual (seperti featureAdan featureB), buat PR yang TIDAK dimaksudkan untuk digabungkan, tetapi untuk mengumpulkan umpan balik awal pada PoC featureA.

Orang-orang akan dapat memeriksanya dengan cepat (itu hanya PoC), dan tujuannya adalah untuk memvalidasi desain atau pendekatan umum.

Kemudian, Anda dapat terus bekerja pada fitur A, membuat permintaan tarik untuk itu dan cabang dan bekerja pada fitur B.

Perbedaan besar adalah bahwa sekarang Anda dapat berharap featureAuntuk tidak berubah secara radikal: desain dan pendekatan sudah divalidasi. Tinjauan kode dan perubahan yang diperlukan mungkin lebih halus dan lokal daripada "woops, Anda memerlukan pendekatan yang berbeda". Ini akan meminimalkan jumlah pekerjaan yang harus Anda lakukan untuk nanti menggabungkan featureBpada featureA's kode, terlepas dari metode yang Anda pilih.

Alfa
sumber