Memahami dan menghafal parameter git rebase


11

Sejauh ini bagian git yang paling membingungkan adalah rebading ke cabang lain. Khususnya, argumen baris perintah yang membingungkan.

Setiap kali saya ingin rebase sepotong kecil dari satu cabang ke ujung yang lain, saya harus meninjau dokumentasi git rebase dan butuh sekitar 5-10 menit untuk memahami apa yang masing-masing dari 3 argumen utama seharusnya.

git rebase <upstream> <branch> --onto <newbase>

Apa aturan praktis yang baik untuk membantu saya mengingat apa yang masing-masing dari ketiga parameter ini harus ditetapkan, mengingat segala macam rebase ke cabang lain?

Ingatlah saya telah membaca dokumentasi git-rebase lagi, dan lagi, dan lagi, dan lagi (dan lagi), tetapi selalu sulit untuk dipahami (seperti kertas putih ilmiah yang membosankan atau sesuatu). Jadi pada titik ini saya merasa perlu melibatkan orang lain untuk membantu saya memahami hal itu.

Tujuan saya adalah saya tidak perlu meninjau dokumentasi untuk parameter dasar ini. Saya belum dapat menghafal mereka sejauh ini, dan saya sudah melakukan banyak sekali rebounds. Jadi agak tidak biasa bahwa saya bisa menghafal setiap perintah lain dan parameternya sejauh ini, tetapi tidak rebase dengan --onto.


Anda bisa mendefinisikan beberapa alias git untuk kasus penggunaan umum, atau mengetuk skrip wizard yang mengingatkan Anda tentang arti setiap parameter sebelum menjalankan perintah.
Rory Hunter

4
Ah, pilihan-pilihan perintah git yang membingungkan dan murni ini. Jadi secara intuitif untuk digunakan. Selalu menyenangkan.
JensG

Jawaban:


9

Mari kita lewati --ontosejenak. upstreamdan branchcukup mendasar, dan sebenarnya semacam meniru checkoutdan branch- argumen kedua adalah opsional:

git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>

(Selain, nama-nama argumen ini di rebase, "hulu" dan "cabang" tidak sangat deskriptif IMO Saya biasanya menganggap mereka seperti peachoftree,. <start>Dan <end>, yang adalah bagaimana saya akan menggunakan mereka: git rebase <start> <end>)

Ketika cabang kedua dihilangkan, hasilnya hampir sama dengan pertama memeriksa cabang itu dan kemudian melakukannya seolah-olah Anda tidak menentukan cabang itu. Pengecualiannya adalah branchyang tidak mengubah cabang Anda saat ini:

git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end>  && git rebase <start>

Sedangkan untuk memahami apa yang rebasedilakukan ketika dipanggil, saya pertama kali mulai dengan menganggapnya sebagai jenis penggabungan khusus. Ini tidak benar-benar, tetapi membantu ketika pertama kali mulai memahami rebase. Untuk meminjam contoh peachoftree:

A--B--F--G master
    \
     C--D--E feature

Sebuah git merge masterhasil ini:

A--B--F-----G master
    \        \
     C--D--E--H feature

Sementara a git rebase master(while on branch feature!) Menghasilkan ini:

A--B--F--G master
          \
           C'--D'--E' feature

Dalam kedua kasus, featuresekarang berisi kode dari keduanya masterdan feature. Jika Anda tidak aktif feature, argumen kedua dapat digunakan untuk beralih ke pintasan: git rebase master featureakan melakukan hal yang sama seperti di atas.


Sekarang, untuk yang spesial --onto. Bagian penting untuk diingat dengan ini adalah bahwa itu default <start>jika tidak ditentukan. Jadi di atas, jika saya tentukan --ontosecara spesifik, ini akan menghasilkan hal yang sama:

git rebase --onto master master
git rebase --onto master master feature

(Saya tidak menggunakan --ontotanpa menentukan <end>hanya karena mental lebih mudah diurai, bahkan berpikir keduanya sama jika sudah aktif feature.)

Untuk melihat mengapa --ontobermanfaat, berikut ini contoh yang berbeda. Katakanlah saya aktif featuredan melihat ada bug, yang kemudian saya mulai perbaiki - tetapi bercabang featurebukan masterkarena kesalahan:

A--B--F--G master
    \
     C--D--E feature
            \
             H--I bugfix

Yang saya inginkan adalah "memindahkan" komitmen ini bugfixagar tidak lagi bergantung feature. Seperti itu, segala jenis penggabungan atau rebase yang ditunjukkan di atas dalam jawaban ini akan mengambil tiga featurekomit bersama dengan dua bugfixkomit.

Misalnya git rebase master bugfixsalah. Kisaran <start>untuk <end>terjadi untuk memasukkan semua komit dari feature, yang diputar di atas master:

A--B--F--G master
    \     \
     \     C'--D'--E'--H'--I' bugfix
      \
       C--D--E feature

Apa yang kita benar-benar inginkan adalah kisaran komit dari featureke bugfixakan diputar di atas master. Itulah --ontogunanya - menentukan target "replay" yang berbeda dari cabang "start":

git rebase --onto master feature bugfix

A--B--F--G master
    \     \
     \     H'--I' bugfix
      \
       C--D--E feature

1

Hanya penyegaran, rebasing terutama untuk ketika Anda ingin riwayat komit Anda muncul linier jika dua cabang telah berkembang secara independen satu sama lain, pada dasarnya ia menulis ulang komit sejarah.

cara saya suka melakukannya adalah git rebase --onto <target branch> <start branch> <end branch>

di mana <target branch>cabang yang Anda rebound, <start branch>biasanya cabang dari mana <end branch>perpecahan dan <end branch>cabang Anda rebasing.

jika Anda mulai dengan

A--B--F--G master
    \
     C--D--E feature

dan lakukan

git rebase --onto master master feature

kamu akan mendapatkan

A--B--F--G master
          \
           C'--D'--E' feature

Satu hal yang baik untuk diketahui adalah bahwa <target branch>default untuk <start branch>Anda dapat melakukan rebase yang sama

git rebase --onto master feature

jika Anda memerlukan bantuan lebih lanjut, lihat Panduan Rebase tanpa air mata


Hasil Anda terlihat menyesatkan. rebase harus membiarkan mastercabang itu sendiri tidak berubah. Anda hanya mendapatkan 'fitur' untuk bercabang seperti G--C'--D'--E'saat mastermasih berhenti di G.
Frank

@ Sejujurnya, saya melakukan itu untuk menekankan seluruh sejarah linear, tetapi sekarang saya pikir Anda lebih baik. tetap.
peachoftree

1
Dapatkah Anda menunjukkan contoh di mana <target branch>dan <start branch>berbeda untuk membantu pembaca memahami kasus yang paling umum?
Rufflewind
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.