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 -i
pendekatan ini dan reset --soft
adalah, rebase -i
memungkinkan saya untuk mempertahankan pembuat komit, sementara reset --soft
memungkinkan 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 rebase
atau 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 -i
akan 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 -f
tetapi sebaliknya itu indah, terima kasih.
git push --force
setelah itu sehingga dibutuhkan komit
Anda dapat menggunakan git merge --squash
ini, 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 status
sudah bersih (karena git reset --hard
akan 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 --squash
pilihan secara lebih rinci.
Pembaruan: satu-satunya keuntungan nyata dari metode ini daripada yang lebih sederhana yang git reset --soft HEAD~12 && git commit
disarankan 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 merge
melakukan salah satu hal yang git rebase
secara khusus dirancang untuk?
git merge --squash
juga lebih mudah digunakan dalam skrip. Pada dasarnya, alasannya adalah bahwa Anda tidak memerlukan "interaktivitas" git rebase -i
sama sekali untuk ini.
git merge --squash
adalah 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 reset
jika 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 commit
Pesan komit akan dipopulasi berdasarkan squash.
gitk
untuk 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~N
cara 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 ~/.gitconfig
harus 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 N
komitmen 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 --amend
dapat memodifikasinya secara manual. (Atau, edit alias agar sesuai dengan selera Anda.)
git squash -m "New summary."
dan telah N
menentukan secara otomatis jumlah komit yang tidak dicopot.
git commit --amend
untuk 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~3
saat menjalankan perintah git rebase -i HEAD~3
.
Komit terbaru,, HEAD
ditampilkan 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 pick
menjadi perintah pilihan Anda.
Saya lebih suka menggunakan perintah fixup
karena 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 squash
atau fixup
karena 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 log
atau gitk
dan 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 pick
menjadi 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!
pick
baris 1. Jika Anda memilih squash
atau fixup
untuk 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 Log
Combine to one commit
dari 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 pick
satu komit dan squash
yang 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
--continue
dan vim :x
.
git add
konfigurasi yang benar dalam file Anda yang Anda gunakan git rebase --continue
untuk pindah ke komit berikutnya dan mulai bergabung. :x
adalah 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 --oneline
bisa digunakan untuk mendapatkan hash pendek.
2) Jika Anda ingin melakukan squash (menggabungkan), lakukan dua komit terakhir
# git rebase -i deab3412
3) Ini membuka nano
editor untuk digabung. Dan sepertinya di bawah ini
....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....
4) Ubah nama kata pick
untuk squash
yang 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 nano
editor. Tekan ctrl + o
dan tekan Enter
untuk menyimpan. Dan kemudian tekan ctrl + x
untuk keluar dari editor.
6) Kemudian nano
editor 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 ubuntu
shell. Jika Anda menggunakan os yang berbeda ( Windows
atau Mac
) maka perintah di atas sama kecuali editor. Anda mungkin mendapatkan editor yang berbeda.
git add <files>
--fixup
opsi dan OLDCOMMIT
harus 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
. rebase
Perintah 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.
--amend
dapat 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, --amend
gabungkan perubahan baru ke komit terakhir cdababcd
dan 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 log
tidak cocok dengan yang Anda lihat di GitHub.
git checkout
merekagit reset --soft
itugit commit
bengkok 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 -i
selalu 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~5
berarti "squash the 5 commit terakhir menjadi yang baru";Bagaimana dengan jawaban untuk pertanyaan yang terkait dengan alur kerja seperti ini?
merge --squash
setelah 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 master
git checkout -b new-branch
git checkout -b new-branch-temp
git checkout new-branch
git merge --squash new-branch-temp
// menempatkan semua perubahan di panggunggit commit 'one message to rule them all'
git push
Saya 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 master
kembali 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 -i
opsi sed GNU , pengguna Mac dan Linux tidak masalah dengan ini.)
git squash master
saat 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 --graph
menghasilkan 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 --mixed
yang 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.