Tarik semua komitmen dari cabang, dorong komitmen tertentu ke yang lain

102

Saya memiliki cabang berikut:

  • master
  • production

dan cabang jarak jauh berikut:

  • origin/master
  • origin/production

Saya memiliki skrip yang mengambil origin/mastercabang dan mendapatkan perbedaan dari apa yang berubah dari pengambilan terakhir saya ( log -p master..origin/master). Lalu saya bergabung origin/master.

Komit yang ditemukan didorong ke alat peninjau kode.

Saya ingin mendorong komitmen yang berhasil - dan hanya mereka - ke cabang produksi, dan tentu saja ke origin/production.

Bagaimana saya bisa melakukannya?

Juga, saya memiliki 2 skrip yang sedang berjalan: yang mengambil dari origin/master, memasukkan detail komit ke database, dan menggabungkan, dan yang lainnya yang sedang saya tulis yang harus mendorong komit yang berhasil.

Saya ingin 2 skrip tersebut berjalan sambil menghindari kondisi balapan / konflik penggabungan. Karena saya hanya ingin bekerja dengan komitmen tertentu, mungkin ada cara untuk menghilangkan komitmen yang tidak saya inginkan?

Sylvain
sumber
Apa yang Anda maksud dengan 'komitmen sukses'?
bdonlan
salah satu yang telah ditinjau dan ditandai sebagai berhasil. tidak terlalu penting di sini, yang penting ada komitmen yang ingin saya pertahankan dan dorong ke cabang lain, dan komitmen lain yang ingin saya singkirkan / abaikan.
Sylvain

Jawaban:

313

Istilah yang menurut saya Anda cari adalah 'cherry pick'. Artinya, ambil satu komit dari tengah satu cabang dan tambahkan ke yang lain:

A-----B------C
 \
  \
   D

menjadi

A-----B------C
 \
  \
   D-----C'

Ini, tentu saja, dapat dilakukan dengan perintah git cherry-pick.

Masalah dengan komit ini adalah bahwa git menganggap komit untuk menyertakan semua riwayat sebelumnya - jadi, jika Anda memiliki tiga komit seperti ini:

A-----B-----C

Dan coba singkirkan B, Anda harus membuat komit yang sama sekali baru seperti:

A-----------C'

Dimana C 'memiliki ID SHA-1 yang berbeda. Demikian juga, mengambil ceri komit dari satu cabang ke cabang lain pada dasarnya melibatkan pembuatan tambalan, kemudian menerapkannya, sehingga kehilangan sejarah dengan cara itu juga.

Perubahan ID komit ini merusak fungsi penggabungan git antara lain (meskipun jika digunakan dengan hemat ada heuristik yang akan membahas ini). Lebih penting lagi, ia mengabaikan ketergantungan fungsional - jika C benar-benar menggunakan fungsi yang ditentukan dalam B, Anda tidak akan pernah tahu.

Mungkin cara yang lebih baik untuk menangani ini adalah dengan memiliki cabang yang lebih berbutir halus. Artinya, alih-alih hanya memiliki 'master', memiliki 'featureA', 'bugfixB', dll. Lakukan peninjauan kode pada seluruh cabang dalam satu waktu - di mana setiap cabang sangat terfokus pada hanya melakukan satu hal - lalu gabungkan itu satu cabang setelah selesai. Ini adalah alur kerja yang dirancang untuk git, dan kegunaannya :)

Jika Anda bersikeras berurusan dengan hal-hal di tingkat tambalan, Anda mungkin ingin melihat darcs - ini menganggap repositori sebagai satu set tambalan, dan dengan demikian pengambilan ceri menjadi operasi mendasar. Namun ini memiliki masalah tersendiri, seperti sangat lambat :)

Sunting: Juga, saya tidak yakin saya mengerti pertanyaan kedua Anda, tentang dua skrip. Mungkin Anda bisa mendeskripsikannya lebih detail, mungkin sebagai pertanyaan terpisah agar tidak membingungkan?

bdonlan.dll
sumber
Tentang pertanyaan kedua saya, saya hanya ingin memastikan bahwa proses pengambilan perubahan (skrip pertama) dan mendorong komitmen yang diberikan ke lokasi lain (skrip ke-2) dapat bekerja tanpa memiliki kondisi balapan / konflik penggabungan, saat bekerja dengan cabang yang berbeda. Tapi pada akhirnya saya rasa itu tidak masalah karena saya bisa menggabungkan 2 skrip menjadi satu sehingga 2 skrip tidak bekerja secara bersamaan :)
Sylvain
9
"Perubahan ID komit ini merusak antara lain fungsi penggabungan git" @bdonlan tolong jelaskan bagaimana fungsi penggabungan direm. Apa artinya?
Narek
5
@Narek Dia mungkin berarti bahwa perubahan dalam komit C 'akan berbenturan dengan perubahan yang sama di komit C ketika Anda akan menggabungkan cabang kedua. Itulah konsekuensi dari kehilangan sejarah di balik commit C.
bytefu
1
"Dan cobalah untuk menyingkirkan B" - mengapa Anda mencoba untuk menyingkirkan B?
d512
3
@ user1334007, maksudnya sebelum itu dulu ABC. Sekarang, karena ceri Anda memilih C, cabang Anda adalah AD-C ', yang tidak lagi mengandung' B '.
AnneTheAgile
1

Saya menyadari ini adalah pertanyaan lama, tetapi direferensikan di sini: Bagaimana menggabungkan komit tertentu di Git

Karenanya, jawaban yang lebih baru: Gunakan cabang fitur dan permintaan tarik.

Ini terlihat seperti, di mana fA adalah komit dengan fitur A, dan fB adalah komit dengan fitur B:

            fA   fC (bad commit, don't merge)
           /  \ /
master ----A----B----C
                \  /
                 fB

Permintaan tarik dikaitkan dengan fungsionalitas GitHub, tetapi sebenarnya yang saya maksud adalah seseorang memiliki tanggung jawab untuk menggabungkan cabang fitur menjadi master.

MattJenko
sumber