Bagaimana cara squash melakukan git setelah mereka didorong?

551

Ini memberikan penjelasan yang baik tentang terjepitnya banyak komitmen:

http://git-scm.com/book/en/Git-Branching-Rebasing

tetapi tidak berfungsi untuk komit yang telah didorong. Bagaimana cara menekan beberapa commit terakhir di repo lokal dan jauh saya?

EDIT: Ketika saya melakukannya git rebase -i origin/master~4 master, simpan yang pertama sebagai pick, atur tiga lainnya sebagai squash, dan kemudian keluar (melalui cx cc di emacs), saya mendapatkan:

$ git rebase -i origin/master~4 master
# Not currently on any branch.
nothing to commit (working directory clean)

Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added"
$ git rebase -i origin/master~4 master
Interactive rebase already started

di mana 2f40 adalah pickkomit. Dan sekarang tidak ada dari 4 komit yang muncul git log. Saya berharap editor saya akan dimulai kembali sehingga saya bisa memasukkan pesan komit. Apa yang saya lakukan salah?

Loren
sumber

Jawaban:

781

Squash melakukan secara lokal dengan

git rebase -i origin/master~4 master

dan kemudian mendorong dengan paksa

git push origin +master

Perbedaan antara --forcedan+

Dari dokumentasi git push:

Catatan yang --forceberlaku untuk semua referensi yang didorong, karenanya menggunakannya dengan push.defaultset ke matchingatau dengan beberapa tujuan push yang dikonfigurasi remote.*.pushdapat menimpa referensi selain cabang saat ini (termasuk referensi lokal yang secara ketat berada di belakang mitra jarak jauh mereka). Untuk memaksakan dorongan hanya ke satu cabang, gunakan a + di depan refspec untuk mendorong (misalnya git push origin +masteruntuk memaksa dorongan ke mastercabang).

Alan Haggai Alavi
sumber
30
Anda juga dapatgit push --force origin master
Daenyth
7
Daenyth : Ya, tapi saya selalu lebih suka sintaks ini karena ini lebih pendek.
Alan Haggai Alavi
86
Dan tentu saja, sadari bahwa jika ada orang lain yang telah menarik dari repositori jarak jauh, Anda mungkin tidak ingin melakukan ini - jawabannya dalam hal ini adalah "Anda tidak."
Cascabel
10
Juga, saya pikir OP persis menyalin perintah git rebase -i origin/master, dan benar-benar ingin tahu bagaimana cara mengembalikan berkomitmen lebih jauh dari itu, misalnya git rebase -i origin/master~20 master.
Cascabel
6
gstackoverflow :+hanya memaksa refspec yang diawali olehnya. --forceakan memaksa semua refspec didorong. Silakan lihat jawaban yang diperbarui.
Alan Haggai Alavi
120

Di cabang saya bisa melakukannya seperti ini (untuk 4 komitmen terakhir)

git checkout my_branch
git reset --soft HEAD~4
git commit
git push --force origin my_branch
jakob-r
sumber
1
Melakukan ini dengan perintah lunak pada cabang yang sudah didorong akhirnya mendorong satu ton orang lain berkomitmen untuk saya.
cchamberlain
3
Di? Bagaimana bisa lebih dari 4? Bisakah Anda menguraikan?
jakob-r
Bahwa saya tidak yakin tetapi itu ada hubungannya dengan mencoba meremas komit yang sudah didorong. Sepertinya orang lain mengalami hal serupa di sini - stackoverflow.com/questions/5189560/…
cchamberlain
4
Saya akan menerima ini sebagai jawaban yang diharapkan. Lebih bersih yang menerima jawaban.
vikramvi
4
Ini adalah jawaban yang paling jelas dan dapat diterima hanya dalam 4 langkah
Ameya Salagre
45

Perbedaan kecil untuk jawaban yang diterima, tetapi saya mengalami banyak kesulitan terjepit dan akhirnya mendapatkannya.

$ git rebase -i HEAD~4
  • Pada layar interaktif yang terbuka, ganti pick dengan squash di bagian atas untuk semua commit yang ingin Anda squash.
  • Simpan dan tutup editor melalui esc --> :wq

Dorong ke remote menggunakan:

$ git push origin branch-name --force
BLRBoy
sumber
2
singkat dan efektif, rumit:
terwxqian
22

Banyak masalah dapat dihindari dengan hanya membuat branchuntuk bekerja & tidak bekerja master:

git checkout -b mybranch

Pekerjaan berikut untuk remotekomit sudah didorong & campuran remotekomit didorong / localhanya komitmen:

# example merging 4 commits

git checkout mybranch
git rebase -i mybranch~4 mybranch

# at the interactive screen
# choose fixup for commit: 2 / 3 / 4

git push -u origin +mybranch

Saya juga punya beberapa catatan permintaan tarik yang mungkin bisa membantu.

Stuart Cardall
sumber
17

git rebase -i master

Anda akan membuat editor vm terbuka dan pesan seperti ini

Pick 2994283490 commit msg1
f 7994283490 commit msg2
f 4654283490 commit msg3
f 5694283490 commit msg4
#Some message 
#
#some more

Di sini saya telah mengubah pick untuk semua commit lainnya ke "f" (Singkatan untuk fixup).

git push -f origin feature/feature-branch-name-xyz

ini akan memperbaiki semua komit ke satu komit dan akan menghapus semua komit lainnya. Saya melakukan ini dan itu membantu saya.

Nupur
sumber
3

Saat Anda bekerja dengan Gitlab atau Github, Anda dapat mengalami masalah dengan cara ini. Anda menekan komitmen Anda dengan salah satu metode di atas. Pilihan saya adalah:

git rebase -i HEAD~4
or
git rebase -i origin/master

pilih squash atau fixup untuk komit Anda. Pada titik ini Anda akan memeriksa dengan status git. Dan pesannya bisa:

    On branch ABC-1916-remote
    Your branch and 'origin/ABC-1916' have diverged,
    and have 1 and 7 different commits each, respectively.
      (use "git pull" to merge the remote branch into yours)

Dan Anda bisa tergoda untuk menariknya. JANGAN LAKUKAN ITU atau Anda akan berada dalam situasi yang sama seperti sebelumnya.

Alih-alih mendorong ke asal Anda dengan:

git push origin +ABC-1916-remote:ABC-1916

Tanda + memungkinkan untuk memaksa push hanya ke satu cabang.

Alex
sumber
tidak ada yang salah dalam menarik, terutama jika Anda memiliki konflik mereka dapat diselesaikan lebih mudah daripada jika Anda memaksa push
Ray_Poly
2

Untuk meremukkan dua komit, yang salah satunya sudah didorong, pada cabang tunggal berikut ini berfungsi:

git rebase -i HEAD~2
    [ pick     older-commit  ]
    [ squash   newest-commit ]
git push --force

Secara default, ini akan mencakup pesan komit dari komit terbaru sebagai komentar pada komit yang lebih lama.

tangan lobster
sumber
2

1) git rebase -i HEAD~4

Untuk menguraikan: Ini berfungsi pada cabang saat ini; KEPALA ~ 4 berarti menekan empat commit terakhir; mode interaktif (-i)

2) Pada titik ini, editor membuka, dengan daftar commit, untuk mengubah commit kedua dan selanjutnya, mengganti pick dengan squash lalu menyimpannya.

output: Berhasil dibuat ulang dan diperbarui referensi / kepala / nama cabang.

3) git push origin refs/heads/branch-name --force

keluaran:

remote:
remote: To create a merge request for branch-name, visit:
remote: http://xxx/sc/server/merge_requests/new?merge_request%5Bsource_branch%5D=sss
remote:To ip:sc/server.git
 + 84b4b60...5045693 branch-name -> branch-name (forced update)
terwxqian
sumber