Bagaimana saya bisa menekan komit X terakhir saya bersama menjadi satu komit menggunakan Git?
Bagaimana saya bisa menekan komit X terakhir saya bersama menjadi satu komit menggunakan Git?
Jawaban:
Gunakan git rebase -i <after-this-commit>dan ganti "pilih" pada komit kedua dan selanjutnya dengan "squash" atau "fixup", seperti yang dijelaskan dalam manual .
Dalam contoh ini, <after-this-commit>apakah hash SHA1 atau lokasi relatif dari KEPALA cabang saat ini dari mana komit dianalisis untuk perintah rebase. Misalnya, jika pengguna ingin melihat 5 commit dari HEAD saat ini di masa lalu perintahnya adalah git rebase -i HEAD~5.
<after-this-commit>?
<after-this-commit>komit X + 1 yaitu induk dari komit tertua yang ingin Anda squash.
rebase -ipendekatan ini dan reset --softadalah, rebase -imemungkinkan saya untuk mempertahankan pembuat komit, sementara reset --softmemungkinkan saya untuk berkomitmen kembali. Kadang-kadang saya perlu menekan komitmen untuk melakukan tarik namun mempertahankan informasi penulis. Terkadang saya perlu mengatur ulang lunak pada komit saya sendiri. Terpilih untuk kedua jawaban yang bagus.
Anda dapat melakukan ini dengan cukup mudah tanpa git rebaseatau git merge --squash. Dalam contoh ini, kita akan menekan 3 komit terakhir.
Jika Anda ingin menulis pesan komit baru dari awal, ini sudah cukup:
git reset --soft HEAD~3 &&
git commit
Jika Anda ingin mulai mengedit pesan komit baru dengan gabungan dari pesan komit yang ada (yaitu mirip dengan apa yang git rebase -iakan dimulai dengan daftar instruksi pick / squash / squash / ... / squash ), maka Anda perlu mengekstrak pesan-pesan itu dan meneruskannya mereka untuk git commit:
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
Kedua metode tersebut menekan tiga komit terakhir menjadi satu komit baru dengan cara yang sama. Soft reset hanya menunjukkan kembali HEAD ke komit terakhir yang tidak ingin Anda tekan. Baik indeks maupun pohon kerja tidak tersentuh oleh soft reset, meninggalkan indeks dalam keadaan yang diinginkan untuk komit baru Anda (yaitu sudah memiliki semua perubahan dari komit yang akan Anda “buang”).
git rebase --squash-recent, atau bahkan git commit --amend-many.
branch@{upstream}(atau hanya @{upstream}untuk cabang saat ini; dalam kedua kasus, bagian terakhir dapat disingkat menjadi @{u}; lihat pembagian git ). Ini mungkin berbeda dari Anda “lalu mendorong komit” (misalnya jika seseorang mendorong sesuatu yang dibangun di atas dorongan terbaru Anda dan kemudian Anda diambil itu), tetapi tampaknya seperti itu mungkin dekat dengan apa yang Anda inginkan.
push -ftetapi sebaliknya itu indah, terima kasih.
git push --forcesetelah itu sehingga dibutuhkan komit
Anda dapat menggunakan git merge --squashini, yang sedikit lebih elegan daripada git rebase -i. Misalkan Anda berada di master dan Anda ingin memeras 12 komit terakhir menjadi satu.
PERINGATAN: Pertama-tama pastikan Anda melakukan pekerjaan Anda — periksa apakah git statussudah bersih (karena git reset --hardakan membuang perubahan yang dipentaskan dan tidak dipentaskan)
Kemudian:
# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12
# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}
# Commit those squashed changes. The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit
The dokumentasi untukgit merge menggambarkan --squashpilihan secara lebih rinci.
Pembaruan: satu-satunya keuntungan nyata dari metode ini daripada yang lebih sederhana yang git reset --soft HEAD~12 && git commitdisarankan oleh Chris Johnsen dalam jawabannya adalah bahwa Anda mendapatkan pesan komit yang dipopulasi dengan setiap pesan komit yang Anda hancurkan.
git rebase -i, tetapi Anda tidak memberikan alasan mengapa. Untuk sementara, saya menganggap ini karena menurut saya sebenarnya yang terjadi adalah sebaliknya dan ini adalah peretasan; tidakkah Anda melakukan lebih banyak perintah daripada yang diperlukan hanya untuk memaksa git mergemelakukan salah satu hal yang git rebasesecara khusus dirancang untuk?
git merge --squashjuga lebih mudah digunakan dalam skrip. Pada dasarnya, alasannya adalah bahwa Anda tidak memerlukan "interaktivitas" git rebase -isama sekali untuk ini.
git merge --squashadalah lebih kecil kemungkinannya untuk menghasilkan konflik penggabungan dalam menghadapi gerakan / penghapusan / penggantian nama dibandingkan dengan rebasing, terutama jika Anda bergabung dari cabang lokal. (Penafian: berdasarkan hanya pada satu pengalaman, koreksi saya jika ini tidak benar dalam kasus umum!)
HEAD@{1}hanya berada di sisi yang aman misalnya ketika alur kerja Anda terganggu selama satu jam oleh pemadaman listrik dll.
Saya sarankan menghindari git resetjika memungkinkan - terutama untuk pemula Git. Kecuali jika Anda benar-benar perlu mengotomatiskan proses berdasarkan sejumlah komitmen, ada cara yang kurang eksotis ...
git merge --squash (working branch name)git commitPesan komit akan dipopulasi berdasarkan squash.
gitkuntuk memberi label pada baris kode yang Anda tekan dan juga memberi label pada basis yang akan digunakan squash. Dalam kasus normal, kedua label ini sudah ada, sehingga langkah (1) dapat dilewati.
git branch your-feature && git reset --hard HEAD~Ncara yang paling nyaman. Namun, itu melibatkan git reset lagi, yang coba dihindari oleh jawaban ini.
Berdasarkan jawaban Chris Johnsen ,
Tambahkan alias "squash" global dari bash: (atau Git Bash di Windows)
git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'
... atau menggunakan Prompt Perintah Windows:
git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
Sekarang Anda ~/.gitconfigharus mengandung alias ini:
[alias]
squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
Pemakaian:
git squash N
... Yang secara otomatis terjepit bersama dengan Nkomitmen terakhir , inklusif.
Catatan: Pesan komit yang dihasilkan adalah kombinasi dari semua komit terjepit, secara berurutan. Jika Anda tidak puas dengan itu, Anda selalu git commit --amenddapat memodifikasinya secara manual. (Atau, edit alias agar sesuai dengan selera Anda.)
git squash -m "New summary."dan telah Nmenentukan secara otomatis jumlah komit yang tidak dicopot.
git commit --amenduntuk lebih lanjut mengubah pesan, tetapi alias ini memungkinkan Anda memiliki awal yang baik tentang apa yang seharusnya ada dalam pesan komit.
Berkat posting blog praktis ini saya menemukan bahwa Anda dapat menggunakan perintah ini untuk menekan 3 komit terakhir:
git rebase -i HEAD~3
Ini berguna karena berfungsi bahkan ketika Anda berada di cabang lokal tanpa informasi pelacakan / repo jarak jauh.
Perintah akan membuka editor rebase interaktif yang kemudian memungkinkan Anda untuk menyusun ulang, squash, reword, dll seperti biasa.
Menggunakan editor rebase interaktif:
Editor rebase interaktif menunjukkan tiga komit terakhir. Batasan ini ditentukan oleh HEAD~3saat menjalankan perintah git rebase -i HEAD~3.
Komit terbaru,, HEADditampilkan pertama kali pada baris 1. Baris yang dimulai dengan #komentar / dokumentasi.
Dokumentasi yang ditampilkan cukup jelas. Pada baris mana pun Anda dapat mengubah perintah dari pickmenjadi perintah pilihan Anda.
Saya lebih suka menggunakan perintah fixupkarena ini "menekan" komit berubah menjadi komit pada baris di atas dan membuang pesan komit.
Karena komit pada baris 1 adalah HEAD, dalam kebanyakan kasus Anda akan membiarkan ini sebagai pick. Anda tidak dapat menggunakan squashatau fixupkarena tidak ada komit lain untuk memeras komit ke.
Anda juga dapat mengubah urutan komitmen. Ini memungkinkan Anda untuk menekan atau memperbaiki komit yang tidak berdekatan secara kronologis.
Contoh praktis sehari-hari
Saya baru-baru ini melakukan fitur baru. Sejak itu, saya telah melakukan dua perbaikan bug. Tapi sekarang saya telah menemukan bug (atau mungkin hanya kesalahan ejaan) di fitur baru yang saya komit. Menyebalkan sekali! Saya tidak ingin komit baru mencemari riwayat komit saya!
Hal pertama yang saya lakukan adalah memperbaiki kesalahan dan membuat komit baru dengan komentar squash this into my new feature!.
Saya kemudian menjalankan git logatau gitkdan mendapatkan SHA komit dari fitur baru (dalam hal ini 1ff9460).
Selanjutnya, saya membawa editor rebase interaktif dengan git rebase -i 1ff9460~. The ~setelah komit SHA memberitahu editor untuk memasukkan yang komit dalam editor.
Selanjutnya, saya memindahkan komit yang berisi perbaikan ( fe7f1e0) ke bawah komit fitur, dan berubah pickmenjadi fixup.
Saat menutup editor, perbaikannya akan dimasukkan ke dalam fitur commit dan riwayat komit saya akan terlihat bagus dan bersih!
Ini bekerja dengan baik ketika semua komit adalah lokal, tetapi jika Anda mencoba untuk mengubah komit yang sudah didorong ke remote Anda benar-benar dapat menyebabkan masalah bagi pengembang lain yang telah memeriksa cabang yang sama!
pickbaris 1. Jika Anda memilih squashatau fixupuntuk komit pada baris 1, git akan menampilkan pesan yang mengatakan "kesalahan: tidak dapat 'memperbaiki' tanpa komit sebelumnya". Maka itu akan memberi Anda opsi untuk memperbaikinya: "Anda dapat memperbaikinya dengan 'git rebase --edit-todo' dan kemudian jalankan 'git rebase --continue'." atau Anda dapat membatalkan dan memulai dari awal: "Atau Anda dapat membatalkan rebase dengan 'git rebase --abort'."
Jika Anda menggunakan TortoiseGit, Anda dapat fungsinya Combine to one commit:
Show LogCombine to one commitdari menu konteksFungsi ini secara otomatis menjalankan semua langkah git tunggal yang diperlukan. Sayangnya hanya tersedia untuk Windows.
Untuk melakukan ini, Anda dapat menggunakan perintah git berikut.
git rebase -i HEAD~n
n (= 4 di sini) adalah jumlah komit terakhir. Maka Anda mendapat opsi berikut,
pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....
Perbarui seperti di bawah picksatu komit dan squashyang lainnya ke yang terbaru,
p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....
Untuk detail klik pada Tautan
Berdasarkan artikel ini saya menemukan metode ini lebih mudah untuk usecase saya.
Cabang 'dev' saya berada di depan 'origin / dev' sebanyak 96 komit (jadi komit ini belum didorong ke remote).
Saya ingin memeras komitmen ini menjadi satu sebelum mendorong perubahan. Saya lebih suka mereset cabang ke status 'asal / dev' (ini akan membuat semua perubahan dari 96 komit tidak dipentaskan) dan kemudian melakukan perubahan sekaligus:
git reset origin/dev
git add --all
git commit -m 'my commit message'
Di cabang yang ingin Anda gabungkan komit, jalankan:
git rebase -i HEAD~(n number of commits back to review)
contoh:
git rebase -i HEAD~1
Ini akan membuka editor teks dan Anda harus mengganti 'pick' di depan setiap komit dengan 'squash' jika Anda ingin komit ini digabungkan. Dari dokumentasi:
Misalnya, jika Anda ingin menggabungkan semua komit menjadi satu, 'pilih' adalah komit pertama yang Anda buat dan semua yang akan datang (ditempatkan di bawah yang pertama) harus disetel ke 'squash'. Jika menggunakan vim, gunakan : x dalam mode sisipkan untuk menyimpan dan keluar dari editor.
Kemudian untuk melanjutkan rebase:
git rebase --continue
Untuk lebih lanjut tentang ini dan cara-cara lain untuk menulis ulang riwayat komit Anda lihat posting bermanfaat ini
--continuedan vim :x.
git addkonfigurasi yang benar dalam file Anda yang Anda gunakan git rebase --continueuntuk pindah ke komit berikutnya dan mulai bergabung. :xadalah salah satu perintah yang akan menyimpan perubahan file saat menggunakan vim, lihat ini
Jawaban Anomies bagus, tapi saya merasa tidak aman tentang hal ini jadi saya memutuskan untuk menambahkan beberapa tangkapan layar.
Lihat di mana Anda berada git log. Yang paling penting, cari hash dari commit pertama yang tidak ingin Anda hancurkan. Jadi hanya:
Jalankan git rebase -i [your hash], dalam kasus saya:
$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d
Dalam kasus saya, saya ingin menekan semua komit yang pertama kali. Pemesanan adalah dari pertama hingga terakhir, demikian juga sebaliknya git log. Dalam kasus saya, saya ingin:
Jika Anda hanya memilih satu komit dan menghancurkan sisanya, Anda dapat menyesuaikan satu pesan komit:
Itu dia. Setelah Anda menyimpan ini ( :wq), Anda selesai. Lihatlah dengan git log.
git log
1) Identifikasi hash pendek komit
# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....
Di sini pun git log --onelinebisa digunakan untuk mendapatkan hash pendek.
2) Jika Anda ingin melakukan squash (menggabungkan), lakukan dua komit terakhir
# git rebase -i deab3412
3) Ini membuka nanoeditor untuk digabung. Dan sepertinya di bawah ini
....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....
4) Ubah nama kata pickuntuk squashyang hadir sebelum abcd1234. Setelah ganti nama itu harus seperti di bawah ini.
....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....
5) Sekarang simpan dan tutup nanoeditor. Tekan ctrl + odan tekan Enteruntuk menyimpan. Dan kemudian tekan ctrl + xuntuk keluar dari editor.
6) Kemudian nanoeditor kembali terbuka untuk memperbarui komentar, jika perlu memperbaruinya.
7) Sekarang tergencet dengan sukses, Anda dapat memverifikasinya dengan memeriksa log.
# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....
8) Sekarang dorong untuk repo. Catatan untuk menambahkan +tanda sebelum nama cabang. Ini berarti dorongan paksa.
# git push origin +master
Catatan: Ini didasarkan pada penggunaan git on ubuntushell. Jika Anda menggunakan os yang berbeda ( Windowsatau Mac) maka perintah di atas sama kecuali editor. Anda mungkin mendapatkan editor yang berbeda.
git add <files>
--fixupopsi dan OLDCOMMITharus di mana kita perlu menggabungkan (squash) komit ini.git commit --fixup=OLDCOMMIT
Sekarang ini menciptakan komit baru di atas KEPALA dengan fixup1 <OLDCOMMIT_MSG>.
OLDCOMMIT.git rebase --interactive --autosquash OLDCOMMIT^
Di sini ^berarti komitmen sebelumnya untuk OLDCOMMIT. rebasePerintah ini membuka jendela interaktif pada editor (vim atau nano) bahwa kita tidak perlu melakukan apa-apa cukup simpan dan keluar sudah cukup. Karena opsi yang diteruskan ke ini akan secara otomatis memindahkan komit terbaru ke komit lama dan mengubah operasi ke fixup(setara dengan squash). Kemudian rebase berlanjut dan selesai.
--amenddapat digunakan dengan git-commit. # git log --pretty=oneline --abbrev-commit
cdababcd Fix issue B
deab3412 Fix issue A
....
# git add <files> # New changes
# git commit --amend
# git log --pretty=oneline --abbrev-commit
1d4ab2e1 Fix issue B
deab3412 Fix issue A
....
Di sini, --amendgabungkan perubahan baru ke komit terakhir cdababcddan hasilkan ID komit baru1d4ab2e1
Untuk memeras 10 komit terakhir menjadi 1 komit tunggal:
git reset --soft HEAD~10 && git commit -m "squashed commit"
Jika Anda juga ingin memperbarui cabang jarak jauh dengan komit terjepit:
git push -f
Jika Anda berada di cabang jarak jauh (disebut feature-branch) yang diklon dari Golden Repository ( golden_repo_name), maka inilah teknik untuk memecah komit Anda menjadi satu:
Lihat repo emas
git checkout golden_repo_name
Buat cabang baru darinya (golden repo) sebagai berikut
git checkout -b dev-branch
Squash bergabung dengan cabang lokal Anda yang sudah Anda miliki
git merge --squash feature-branch
Komit perubahan Anda (ini akan menjadi satu-satunya komit yang masuk di dev-branch)
git commit -m "My feature complete"
Dorong cabang ke repositori lokal Anda
git push origin dev-branch
Apa yang bisa benar-benar nyaman:
Temukan hash komit yang ingin Anda tekan, katakan d43e15.
Sekarang gunakan
git reset d43e15
git commit -am 'new commit name'
Ini adalah super-duper Kludgy, tetapi dalam semacam cara yang keren, jadi saya hanya akan melemparkannya ke atas ring:
GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo
Terjemahan: berikan "editor" baru untuk git yang, jika nama file yang akan diedit adalah git-rebase-todo(prompt rebase interaktif) mengubah semua kecuali "pilih" menjadi "squash", dan jika tidak, akan menghasilkan vim - sehingga saat Anda diminta untuk mengedit pesan komit terjepit, Anda mendapatkan vim. (Dan jelas saya menekan lima commit terakhir di branch foo, tetapi Anda bisa mengubahnya sesuka Anda.)
Saya mungkin akan melakukan apa yang disarankan Mark Longair .
Jika Anda ingin memadatkan setiap komit ke dalam komit tunggal (mis. Saat merilis proyek untuk pertama kalinya), coba:
git checkout --orphan <new-branch>
git commit
Saya pikir cara termudah untuk melakukan ini adalah dengan membuat cabang baru dari master dan melakukan gabungan --squash dari cabang fitur.
git checkout master
git checkout -b feature_branch_squashed
git merge --squash feature_branch
Maka Anda memiliki semua perubahan yang siap untuk dilakukan.
Satu kalimat sederhana yang selalu berfungsi, mengingat Anda saat ini berada di cabang yang ingin Anda squash, master adalah cabang tempat asalnya, dan komit terbaru berisi pesan komit dan penulis yang ingin Anda gunakan:
git reset --soft $(git merge-base HEAD master) && git commit --reuse-message=HEAD@{1}
jika misalnya Anda ingin menekan 3 komit terakhir ke komit tunggal di cabang (repositori jarak jauh) di misalnya: https://bitbucket.org
Apa yang saya lakukan adalah
(MASTER)
Fleetwood Mac Fritz
║ ║
Add Danny Lindsey Stevie
Kirwan Buckingham Nicks
║ ╚═══╦══════╝
Add Christine ║
Perfect Buckingham
║ Nicks
LA1974══════════╝
║
║
Bill <══════ YOU ARE EDITING HERE
Clinton (CHECKED OUT, CURRENT WORKING DIRECTORY)
Dalam riwayat https://github.com/fleetwood-mac/band-history repositori yang sangat singkat ini, Anda telah membuka permintaan tarik untuk menggabungkan komitmen Bill Clinton ke komit asli ( MASTER) Fleetwood Mac.
Anda membuka permintaan tarik dan di GitHub Anda melihat ini:
Empat komitmen:
Berpikir bahwa tidak ada yang mau membaca riwayat repositori lengkap. (Sebenarnya ada repositori, klik tautan di atas!) Anda memutuskan untuk menghancurkan komit ini. Jadi kamu pergi dan lari git reset --soft HEAD~4 && git commit. Maka kamugit push --force ke GitHub untuk membersihkan PR Anda.
Dan apa yang terjadi? Anda baru saja membuat komitmen tunggal yang mendapatkan dari Fritz ke Bill Clinton. Karena Anda lupa bahwa kemarin Anda mengerjakan versi Buckingham Nicks dari proyek ini. Dan git logtidak cocok dengan yang Anda lihat di GitHub.
git checkoutmerekagit reset --softitugit commitbengkok itu langsung dari dari ke kegit rebase -i HEAD^^
di mana jumlah ^ adalah X
(dalam hal ini, tekan dua komit terakhir)
Selain jawaban luar biasa lainnya, saya ingin menambahkan bagaimana git rebase -iselalu membingungkan saya dengan perintah komit - lebih lama ke yang lebih baru atau sebaliknya? Jadi ini adalah alur kerja saya:
git rebase -i HEAD~[N], dengan N adalah jumlah komit yang ingin saya gabung, mulai dari yang terbaru . Jadi git rebase -i HEAD~5berarti "squash the 5 commit terakhir menjadi yang baru";Bagaimana dengan jawaban untuk pertanyaan yang terkait dengan alur kerja seperti ini?
merge --squashsetelah PR, tetapi tim berpikir itu akan memperlambat proses.)Saya belum melihat alur kerja seperti itu di halaman ini. (Itu mungkin mataku.) Jika aku mengertirebase dengan benar, banyak penggabungan akan membutuhkan beberapa resolusi konflik . Aku bahkan tidak mau memikirkan hal itu!
Jadi, ini sepertinya bekerja untuk kita.
git pull mastergit checkout -b new-branchgit checkout -b new-branch-tempgit checkout new-branchgit merge --squash new-branch-temp // menempatkan semua perubahan di panggunggit commit 'one message to rule them all'git pushSaya menemukan solusi yang lebih umum bukan untuk menentukan komit 'N', melainkan cabang / komit-id yang ingin Anda tekan di atas. Ini lebih rentan kesalahan daripada menghitung komit hingga komit tertentu — cukup tentukan tag secara langsung, atau jika Anda benar-benar ingin menghitung, Anda dapat menentukan HEAD ~ N.
Dalam alur kerja saya, saya memulai cabang, dan komit pertama saya di cabang itu merangkum tujuan (yaitu biasanya apa yang akan saya dorong sebagai pesan 'final' untuk fitur ke repositori publik.) Jadi ketika saya selesai, semua Yang ingin saya lakukan adalah git squash masterkembali ke pesan pertama dan kemudian saya siap untuk mendorong.
Saya menggunakan alias:
squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i
Ini akan membuang sejarah yang tergencet sebelum melakukannya — ini memberi Anda kesempatan untuk memulihkan dengan mengambil ID komit lama dari konsol jika Anda ingin kembali. (Pengguna Solaris mencatat bahwa ia menggunakan -iopsi sed GNU , pengguna Mac dan Linux tidak masalah dengan ini.)
git squash mastersaat kami diperiksa pada budak. apa yang akan terjadi akankah kita menyembunyikan konflik?
Dalam pertanyaan itu bisa jadi ambigu apa yang dimaksud dengan "terakhir".
misalnya git log --graphmenghasilkan yang berikut (disederhanakan):
* commit H0
|
* merge
|\
| * commit B0
| |
| * commit B1
| |
* | commit H1
| |
* | commit H2
|/
|
Kemudian komit terakhir berdasarkan waktu adalah H0, bergabung, B0. Untuk menekan mereka, Anda harus rebase cabang gabungan Anda di komit H1.
Masalahnya adalah bahwa H0 mengandung H1 dan H2 (dan umumnya lebih banyak melakukan sebelum penggabungan dan setelah percabangan) sementara B0 tidak. Jadi, Anda harus mengelola perubahan dari setidaknya H0, menggabungkan, H1, H2, B0.
Dimungkinkan untuk menggunakan rebase tetapi dengan cara yang berbeda maka dalam jawaban lain disebutkan:
rebase -i HEAD~2
Ini akan menunjukkan kepada Anda opsi pilihan (sebagaimana disebutkan dalam jawaban lain):
pick B1
pick B0
pick H0
Masukkan squash alih-alih pilih ke H0:
pick B1
pick B0
s H0
Setelah menyimpan dan keluar, rebase akan menerapkan komit setelah H1. Itu berarti bahwa itu akan meminta Anda untuk menyelesaikan konflik lagi (di mana HEAD akan menjadi H1 pada awalnya dan kemudian mengumpulkan komitmen saat mereka diterapkan).
Setelah rebase akan selesai, Anda dapat memilih pesan untuk H0 dan B0 terjepit:
* commit squashed H0 and B0
|
* commit B1
|
* commit H1
|
* commit H2
|
PS Jika Anda baru saja melakukan reset ke BO: (misalnya, menggunakan reset --mixedyang dijelaskan secara lebih rinci di sini https://stackoverflow.com/a/18690845/2405850 ):
git reset --mixed hash_of_commit_B0
git add .
git commit -m 'some commit message'
kemudian Anda menekan B0 perubahan H0, H1, H2 (kehilangan sepenuhnya berkomitmen untuk perubahan setelah bercabang dan sebelum bergabung.