Git: Bagaimana cara menekan semua commit di cabang

315

Saya membuat cabang baru masterdengan:

git checkout -b testbranch

Saya membuat 20 komitmen ke dalamnya.

Sekarang saya ingin menekan 20 komit itu. Saya melakukannya dengan:

git rebase -i HEAD~20

Bagaimana jika saya tidak tahu berapa banyak yang melakukan? Apakah ada cara untuk melakukan sesuatu seperti:

git rebase -i all on this branch
pengguna3803850
sumber
6
Anda dapat melakukan git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2dyang akan melakukan rebase interaktif di mana komit adalah komit terakhir yang tetap tidak berubah
denns
@denns Menggunakan metode ini dengan komit terakhir di cabang tempat Anda memulai kembali dari berfungsi fantastis. Terima kasih banyak!
Joshua Pinter

Jawaban:

395

Cara lain untuk menekan semua komit Anda adalah mengatur ulang indeks untuk dikuasai:

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

Ini tidak sempurna karena itu menyiratkan Anda tahu dari mana cabang "cabang Anda" berasal.
Catatan: menemukan bahwa cabang asal tidak mudah / tidak mungkin dengan Git ( cara visual seringkali paling mudah , seperti yang terlihat di sini ).


EDIT: Anda harus menggunakan git push --force


Karlotcha Hoa menambahkan dalam komentar :

Untuk reset, bisa Anda lakukan

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[Itu] secara otomatis menggunakan cabang Anda saat ini.
Dan jika Anda menggunakannya, Anda juga bisa menggunakan alias, karena perintahnya tidak bergantung pada nama cabang .

VONC
sumber
2
Lebih baik checkout untuk berkomitmen di mana YourBranchsaat ini. Ini akan tetap YourBranchutuh saat Anda melakukannyareset
Eugen Konkov
1
@Abdurrahim Atau buka git bash, dan Anda dapat menyalin-menempelkan perintah ini!
VonC
3
Untuk pengaturan ulang, Anda dapat melakukannya git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))untuk secara otomatis menggunakan cabang tempat Anda berada saat ini. Dan jika Anda menggunakannya, Anda juga bisa menggunakan alias, karena perintahnya tidak bergantung pada nama cabang.
Karlotcha Hoa
1
@Druska Untuk kasus percabangan simlpe, tidak, itu akan berfungsi dengan baik.
VonC
1
@ Shimmy ya, asalkan Anda memaksakan dorongan setelah reset: git push --force(dan peringatkan kolega Anda jika Anda beberapa orang bekerja di cabang itu)
VonC
112

Periksa cabang yang ingin Anda hancurkan semua komit menjadi satu komit. Katakanlah namanya feature_branch,.

git checkout feature_branch

Langkah 1:

Lakukan soft reset Anda origin/feature_branchdengan mastercabang lokal Anda (tergantung pada kebutuhan Anda, Anda dapat mengatur ulang dengan asal / master juga). Ini akan mengatur ulang semua komitmen tambahan di Anda feature_branch, tetapi tanpa mengubah perubahan file apa pun secara lokal.

git reset --soft master

Langkah 2:

Tambahkan semua perubahan di direktori git repo Anda, ke komit baru yang akan dibuat. Dan lakukan hal yang sama dengan pesan.

git add -A && git commit -m "commit message goes here"

shanky
sumber
6
Ini adalah solusi paling andal bagi saya - tidak menyebabkan kesalahan rebase atau menggabungkan konflik.
ANTARA
1
Peringatan: git add -A add SEMUA yang Anda miliki di folder lokal - ke cabang.
David H
suka solusi ini! inilah yang saya inginkan!
jacoballenwood
1
Solusi terbaik untuk noob - tidak merusak dan hanya momen oops mungkin terlalu banyak memeriksa seperti rahasia aplikasi dll, yang seharusnya tidak masalah jika Anda memiliki file gitignore yang tepat
kkarakk
@NSduToit Jawaban singkat: Tidak, Anda tidak perlu melakukannya. Setelah melakukan langkah-langkah yang disebutkan di atas dalam jawaban saya, Anda akan berakhir dengan satu komit dengan beberapa perubahan kode. Anda dapat menganggapnya sama seperti komit lainnya dengan beberapa perubahan kode. Anda dapat mendorongnya ke cabang jarak jauh Anda tanpa -fbendera.
Shanky
110

Apa yang Anda lakukan sangat rentan kesalahan. Kerjakan saja:

git rebase -i master

yang secara otomatis akan rebase hanya komitmen cabang Anda ke master terbaru saat ini.

Eevee
sumber
5
terima kasih, saya mengerti, tetapi mengapa sistem saya rawan kesalahan
user3803850
10
Mungkin karena mudah mendapatkan nomor yang salah?
Daniel Scott
13
Setuju ini adalah solusi terbaik Anda. tetapi ikuti tautan ini karena lebih baik menjelaskan apa yang perlu Anda lakukan.
Christo
3
Alih-alih menekan komit, Anda bisa menggabungkan cabang untuk dikuasai dan melakukan git reset ke asal / master untuk membatalkan tahapan semua komit. Itu akan memungkinkan Anda melakukan kode yang tidak commit -am "the whole thing!"
dipentaskan yang
2
@nurettin Saya pikir reset origin/mastermetode ini benar-benar buruk karena hanya sama dengan membuat komit langsung pada master - tidak ada sejarah 'menggabungkan cabang', tidak ada opsi permintaan tarik. Jawaban oleh @WaZaA jauh lebih sesuai dengan alur kerja normal git saya pikir
Drenai
79

Cara sederhana lain untuk melakukan ini: buka cabang asal dan lakukan a merge --squash. Perintah ini tidak melakukan komit "terjepit". ketika Anda melakukannya, semua pesan komit dari Cabang Anda akan dikumpulkan.

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...
WaZaA
sumber
1
Benar. Saya menyebutkan perbedaan antara penggabungan --quash dan rebase -i di stackoverflow.com/a/2427520/6309
VonC
1
Ini berfungsi jika Anda tidak ingin squash ke cabang induk, cukup buat dan beralih ke cabang baru berdasarkan cabang induk dan lakukan penggabungan squash ke dalamnya.
Charlotte
Cheers mate, tip yang bagus!
Nestor Milyaev
bagus! saya membuat "temp" bercabang dari "master" terlebih dahulu untuk menekan "yourBranch" ke dalam, kemudian menggabungkan "temp" menjadi "master".
lazieburd
34

Dengan asumsi Anda bercabang dari master, Anda tidak perlu masuk yourBranchke langkah reset sepanjang waktu:

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

Penjelasan :

  • git rev-list --count HEAD ^mastermenghitung komit sejak Anda membuat cabang fitur dari master, f.ex. 20.
  • git reset --soft HEAD~20akan melakukan soft reset 20 komit terakhir. Ini meninggalkan perubahan Anda di file, tetapi menghapus komit.

Penggunaan :

Dalam .bash_profile saya, saya telah menambahkan alias untuk gisquashmelakukan ini dengan satu perintah:

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

Setelah mengatur ulang dan melakukan, Anda perlu melakukan a git push --force.

Petunjuk :

Jika Anda menggunakan Gitlab> = 11.0 Anda tidak perlu melakukan ini lagi karena memiliki opsi squashing ketika menggabungkan cabang. Opsi Gitlab Squashing

Tuan
sumber
15

Berdasarkan membaca beberapa pertanyaan Stackoverflow dan jawaban tentang squashing, saya pikir ini adalah liner yang bagus untuk menekan semua komit di cabang:

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

Ini dengan asumsi master adalah cabang dasar.

Travis Reeder
sumber
1
Terima kasih banyak, perusahaan memiliki banyak batasan pada tempatnya dan tidak dapat memulai kembali dengan cara yang biasa dengan editor karena tidak keras untuk menyimpan. Juga tidak dapat menggunakan fitur squash and merge di git karena cabang ini menuju ke Lead dev untuk digabung dan dia tidak menyukainya. 1 liner ini bekerja dan menyelamatkan sakit kepala. Pekerjaan yang mengagumkan.
L1ghtk3ira
10

Solusi untuk orang yang lebih suka mengklik:

  1. Instal sourcetree (gratis)

  2. Periksa seperti apa komitmen Anda. Kemungkinan besar Anda memiliki sesuatu yang mirip dengan ini masukkan deskripsi gambar di sini

  3. Klik kanan pada parent commit. Dalam kasus kami ini adalah cabang utama.

masukkan deskripsi gambar di sini

  1. Anda dapat menekan komit dengan yang sebelumnya dengan mengklik tombol. Dalam kasus kami, kami harus mengklik 2 kali. Anda juga dapat mengubah pesan komit masukkan deskripsi gambar di sini

  2. Hasilnya luar biasa dan kami siap untuk mendorong! masukkan deskripsi gambar di sini

Catatan: Jika Anda mendorong sebagian komitmen Anda ke jarak jauh Anda harus menggunakan dorongan paksa setelah squash

Marcin Szymczak
sumber
Terima kasih untuk ini!
Crystal
0

Solusi lain adalah menyimpan semua log komit ke file

log git> branch.log

Sekarang branch.log akan memiliki semua id komit sejak awal .. gulir ke bawah dan ambil komit pertama (ini akan sulit di terminal) menggunakan komit pertama

git reset --soft

semua komitmen akan terjepit

pranav
sumber
0

Reset git, sebagaimana disebutkan dalam banyak jawaban sebelumnya, sejauh ini merupakan cara terbaik dan paling sederhana untuk mencapai apa yang Anda inginkan. Saya menggunakannya dalam alur kerja berikut:

(di cabang pengembangan)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it
Marcus
sumber
0

Semua git ini direset, keras, lunak, dan semua yang disebutkan di sini mungkin bekerja (tidak bagi saya) jika Anda melakukan langkah-langkah dengan benar dan semacam jin.
Jika Anda adalah Joe smo rata-rata, coba ini:
Cara menggunakan git merge --squash?


Menyelamatkan hidup saya, dan akan saya pergi ke squash, telah menggunakan ini 4 kali sejak saya mengetahuinya. Sederhana, bersih dan pada dasarnya 1 comamnd. Singkatnya:


Jika Anda berada di cabang, sebut saja "my_new_feature" off mengembangkan dan permintaan tarik Anda memiliki 35 komitmen (atau berapa banyak) dan Anda ingin menjadi 1.

A. Pastikan cabang Anda mutakhir, Lanjutkan kembangkan, dapatkan yang terbaru, dan gabungkan serta selesaikan konflik dengan "my_new_feature"
(langkah ini benar-benar harus Anda ambil sesegera mungkin)

B. Dapatkan perkembangan terbaru dan percabangan ke cabang baru, sebut saja "my_new_feature_squashed"

C. sihir ada di sini.
Anda ingin mengambil pekerjaan Anda dari "my_new_feature" ke "my_new_feature_squashed"
Jadi lakukan saja (sementara di cabang baru Anda kami ciptakan mengembangkan):
git merge --squash my_new_feature

Semua perubahan Anda sekarang akan berada di cabang baru Anda, silakan mengujinya, lalu lakukan 1 komit tunggal Anda, dorong, PR baru dari cabang itu - dan tunggu pengulangan di hari berikutnya.
Apakah kamu tidak suka coding? :)

ItaiRoded
sumber