Git: Kesalahan "Tidak bisa 'squash' tanpa commit sebelumnya" saat rebase

102

Saya memiliki yang berikut dalam teks agenda dari git rebase -i HEAD~2:

pick 56bcce7 Closes #2774
pick e43ceba Lint.py: Replace deprecated link

# Rebase 684f917..e43ceba onto 684f917 (2 command(s))
#
...

Sekarang, ketika saya mencoba memadamkan yang pertama ( 56bcce7) dan memilih yang kedua dengan menambahkan "s" sebelum yang pertama, saya mendapatkan kesalahan berikut:

Cannot 'squash' without a previous commit

Bisakah seseorang menjelaskan kepada saya apa artinya, dan bagaimana cara melakukannya?

Saya ingin menghentikan commit pertama ( 56bcce7) dan "pilih dan reword" e43cebacommit kedua ( )

Dawny33
sumber
1
Ubah HEAD ~ 2 menjadi HEAD ~ 3 jika Anda benar-benar ingin squash.
ElpieKay
1
Dan mungkin menggunakan --root, jika HEAD ~ 2 adalah komit pertama Anda: stackoverflow.com/a/598788/2444812
Sybille Peters

Jawaban:

89

Rebase interaktif menampilkan komit dalam urutan terbalik dari apa yang biasa Anda gunakan saat menggunakan git log.git rebase -imemutar ulang komit yang dipilih dalam urutan (top-down) yang tepat seperti yang tercantum dalam file instruksi rebase yang disimpan. Saat squashing, komit yang dipilih untuk squashing digabungkan dengan komit yang mendahuluinya dalam daftar (diedit), yaitu komit dari baris sebelumnya. Dalam kasus Anda - tidak ada komit sebelumnya untuk 56bcce7 . Anda harus melakukan salah satu dari berikut ini

  • git rebase -i HEAD~3 (jika Anda ingin squash 56bcce7 dalam 684f917)
  • Jika Anda bermaksud menggabungkan 56bcce7dengan e43ceba, dan e43cebatidak bergantung pada 56bcce7, maka cukup susun ulang:

    r e43ceba Lint.py: Replace deprecated link
    s 56bcce7 Closes #2774
    

    UPDATE : Jawaban Gus bawah ini menyarankan cara yang lebih baik untuk melakukan hal yang sama, tanpa mengatur ulang kedua komitmen tersebut:

    r 56bcce7 Closes #2774
    s e43ceba Lint.py: Replace deprecated link
    

    Ini akan memadatkan / menggabungkan dua komitmen menjadi satu. Ketika rebase interaktif meminta pesan komit yang ditulis ulang 56bcce7, berikan pesan komit yang menjelaskan penyatuan 56bcce7dan e43ceba.

Leon
sumber
1
Saya ingin 56bcce7 masuk e43ceba. Jadi, bagaimana cara melakukan Langkah 1 di sini?
Dawny33
86

Saya memiliki masalah serupa yang saya selesaikan sebagai berikut:

Ini adalah grup komit yang ingin saya squash:

1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Seperti yang Anda lihat, saya menginginkan no. 4, tetapi 1, 2 dan 3 tidak memiliki komitmen sebelumnya untuk digencet . Karenanya Cannot 'squash' tanpa kesalahan commit sebelumnya .

Solusi saya adalah menggunakan ropsi untuk# r, reword = use commit, but edit the commit message

Jadi daftar komitmen saya terlihat seperti ini:

1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Setelah menyimpan, shell interaktif meminta saya untuk menulis ulang komit yang dipilih.

Setelah itu, log komit saya menghasilkan satu komit yang menghasilkan riwayat komit yang lebih bersih.

Gus
sumber
2
seperti saya jika Anda mendapat kesalahan karena Anda tidak memilih komitmen apa pun untuk menulis ulang atau memilih dan mendapatkan kesalahan yang disebutkan (pertanyaan), Anda perlu melakukan git rebase --edit-tododan memperbaiki merujuk jawaban ini dan kemudian melakukannyagit rebase --continue
biksu tua
Jawaban ini singkat dan langsung pada intinya, sangat membantu, terima kasih
gonzofish
20

Saya mengalami masalah ini dan alasan mengapa hal itu terjadi dalam kasus saya adalah, Anda tidak dapat menekan komitmen lama ke komit baru. Berikut adalah contoh yang mengatakan Anda memiliki 3 komit:

1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Sekarang jika Anda mengatakan git rebase -i HEAD~3dan Anda melakukan sesuatu seperti

1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back

Ini akan menghasilkan kesalahan:

error: tidak bisa 'squash' tanpa komit sebelumnya Anda dapat memperbaiki ini dengan 'git rebase --edit-todo' dan kemudian jalankan 'git rebase --continue'. Atau Anda dapat membatalkan rebase dengan 'git rebase --abort'.

Solusi:

Saat melakukan squashing, Anda harus melakukan squash baru-baru ini ke yang lama, bukan sebaliknya, sehingga dalam contoh akan menjadi seperti ini:

1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Ini akan berfungsi dengan baik, jika Anda ingin semua pesan komit Anda, saya akan menyarankan perbaikan daripada squash .

DvixExtract
sumber
5
Terima kasih- Saya jarang melakukan squash dan saran untuk memilih commit terlama adalah yang membantu saya melewati kesalahan git yang tidak membantu.
0x574F4F54
4

Squash dengan logika terbalik . Anda akan dapat memilih pesan komit yang diinginkan di langkah selanjutnya.

  • pickkomit pertama yang tidak Anda inginkan untuk pesan komit.
  • squashatau fixupkomit yang ingin Anda gabungkan, hingga komit yang memiliki pesan komit yang sebenarnya Anda inginkan.
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • konfirmasi perubahan (:x )
  • hapus pesan komit yang tidak Anda inginkan dan tinggalkan hanya pesan dari komit yang Anda inginkan (dalam hal ini:Lint.py: Replace deprecated link .
  • konfirmasi pilihan ( :x)

Semoga lebih jelas untuk seseorang ✌🏽

Kamafeather
sumber
2

Sebaiknya katakan di editor interaktif yang berisi komit, git selalu squash dari bawah ke atas dan kita harus meninggalkan entri "pilih" di atas untuk menerima squash dari bawah.

ekyu88
sumber
2

Saya baru saja mencoba pendekatan ini.

git log -n3

Ini akan menunjukkan 3 komit terakhir yang akan memberi saya gambaran tentang apa yang terbaru dan mana yang pergi sebelumnya. Sekarang dinyatakan rebasing,

git rebase -i HEAD ~ 3

Pilih komit terakhir yang di atasnya kita perlu menekan dua lainnya. Commit id yang dipilih sebagai base commit akan seperti ini,

pilih commit_id

Untuk dua commit id lainnya, ubah menjadi,

komit_id squash

atau sederhananya,

s commit_id

Tom Taylor
sumber
0

Saya juga sudah menemui masalah ini barusan, itu hanya ceroboh. Anda dapat menyelesaikan masalah seperti berikut: ketika Anda mencoba menekan yang pertama (56bcce7) dan memilih yang kedua, Anda harus menambahkan "s" sebelum baris kedua tetapi bukan yang pertama. Anda juga dapat mereferensikan situs web berikutnya: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html

pengguna8073722
sumber
1
Hai! Akan lebih baik jika Anda checkout Cara membuat contoh Minimal, Lengkap, dan Dapat Diverifikasi untuk usaha di masa mendatang di Stack overflow. -Terima kasih
Momin