Pertanyaan Bagaimana caranya saya meringkaskan sejarah git saya?


Pertanyaan

Mengingat saya memiliki komitmen seperti berikut:

A - B - C - D - G - H
     \         /
      - E - F -

Bagaimana saya mendapatkan sejarah linear sempurna hanya mengikuti orang tua pertama?

Misalnya, saya ingin mendapatkan:

A - B - C - D - G'- H'

Diharapkan bahwa sha1 dari G dan H akan berubah, sebagaimana dicatat di atas. (Untuk alasan yang jelas). Jika sha1 untuk A, B, C, dan D berubah juga, maka saya ingin tahu mengapa.

Latar Belakang

Tujuannya adalah untuk menghindari potensi penggabungan komitmen yang akan timbul ketika melakukan git rebase -i yang naif.

Intinya adalah semoga mendapatkan wawasan tambahan untuk menentukan komit yang ada di cabang tertentu, misalnya, jika kita memiliki grafik berikut:

I - J - K - L - M
 \     /   /   / 
  - N - O - P -

Di mana N digabung menjadi K, tetapi O digabungkan dengan --strategy = ours menjadi L, dan P dilebur menjadi M.

Saya ingin dapat mengelompokkan ulang sejarah saya sehingga komitmen bermasalah semacam itu dapat diidentifikasi, dan diperiksa. Saya ingin memiliki pohon di mana dapat mengidentifikasi bahwa O tidak dimasukkan ke cabang hulu, bahkan jika saya berpotensi mengidentifikasi N dan P sebagai berpotensi hilang dari cabang hulu juga, dengan menggunakan git cherry, namun saran di sini akan dihargai .


18
2017-08-01 07:50


asal


Jawaban:


Seperti yang Anda katakan, perintah berikut berfungsi:

git filter-branch --parent-filter 'cut -f 2,3 -d " "'

Mengapa?

Masalah yang Anda tanyakan diselesaikan dengan mengubah setiap gabungan komit dengan komit sederhana: ini hanya akan menghapus cabang-cabang fitur yang digabung, karena mereka akan menjadi yatim piatu.

Setiap komitmen memiliki satu atau lebih orang tua berkomitmen. Gabungkan commit adalah yang mendapatkan lebih dari satu. Git menyimpan ini di setiap objek commit dari sejarah.

Itu git filter-branch perintah, dengan --parent-filter pilihan, memungkinkan untuk menulis ulang setiap orang tua komit, diteruskan ke filter sebagai -p SHA1, diulang jika ada lebih dari satu orang tua. Filter kami memotong induk dan memaksa setiap komit untuk memiliki orang tua tunggal.

Untuk bonus, berikut ini cara melakukannya secara manual pada komitmen yang tepat, dengan menciptakan kembali commit baru:

  • dapatkan pohon komit dan orang tua pertama

    tree=`git show -s --format=%T SHA1`
    parent=`git show -s --format=%P SHA1 | cut -d " " -f1`
    
  • buat komitmen baru dengan pohon yang sama, pesan yang sama, dan simpan hanya orang tua pertama sebagai leluhur

    git show -s --format=%B SHA1 | git commit-tree $tree -p $parent
    

18
2017-08-01 12:48



Lakukan secara manual dengan yang berikut:

git rebase -i D-sha1

Edit file agar G disetel ke "edit". Simpan "pilih" untuk H. Simpan dan tutup editor.

Sekarang Git memungkinkan Anda mengedit G commit, mari kita memodifikasinya menjadi gabungan gabungan komit F. Yang kamu ingin:

#cancel the merge commit and position HEAD to D
git reset --hard HEAD~
#squash merge and continue
git merge --squash F-sha1
git rebase --continue

Perhatikan bahwa Anda harus menyelesaikan konflik yang sama jika Anda harus di penggabungan pertama ...

Seperti yang Anda katakan Anda hanya akan memiliki SHA1 baru untuk G dan H.


5
2017-08-01 08:05