Tanpa membuat cabang dan melakukan banyak pekerjaan funky pada cabang baru, apakah mungkin untuk memecah satu komit menjadi beberapa komit yang berbeda setelah berkomitmen pada repositori lokal?
Dokumen yang tertaut pada komentar di atas sangat bagus, lebih baik dijelaskan daripada jawaban di bawah ini.
Blaisorblade
2
Saya menyarankan penggunaan alias stackoverflow.com/a/19267103/301717 ini . Hal ini memungkinkan untuk membagi komit menggunakangit autorebase split COMMIT_ID
Jérôme Pouiller
Hal termudah untuk dilakukan tanpa rebase interaktif adalah (mungkin) membuat cabang baru mulai dari komit sebelum komit yang ingin Anda bagi, ceri-pilih-di komit, reset, simpanan, komit pemindahan file, aplikasikan simpanan simpanan dan melakukan perubahan, dan kemudian bergabung dengan cabang sebelumnya atau memilih-ceri komitmen yang diikuti. (Kemudian alihkan nama cabang sebelumnya ke kepala saat ini.) (Mungkin lebih baik untuk mengikuti saran MBO dan melakukan rebase interaktif.) (Disalin dari 2010 jawaban di bawah)
William Pursell
1
Saya mengalami masalah ini setelah saya tanpa sengaja terjepit dua komit saat rebase di komit sebelumnya. Cara untuk memperbaikinya adalah untuk checkout terjepit komit, git reset HEAD~, git stash, maka git cherry-pickyang pertama melakukan dalam labu, lalu git stash pop. Kasing ceri saya cukup spesifik di sini, tapi git stashdan git stash popcukup berguna untuk orang lain.
Pertama, mulailah dengan direktori kerja bersih: git statusseharusnya tidak menunjukkan modifikasi, penghapusan, atau penambahan yang tertunda.
Sekarang, Anda harus memutuskan komit yang ingin Anda bagi.
A) Memisahkan komit terbaru
Untuk memisahkan komit terbaru Anda, pertama:
$ git reset HEAD~
Sekarang lakukan potongan secara individual dengan cara biasa, menghasilkan komitmen sebanyak yang Anda butuhkan.
B) Membagi komit lebih jauh ke belakang
Ini membutuhkan rebasing , yaitu penulisan ulang sejarah. Untuk menemukan komit yang benar, Anda memiliki beberapa pilihan:
Jika tiga komit kembali, maka
$ git rebase -i HEAD~3
di mana 3berapa banyak komit kembali itu.
Jika lebih jauh ke belakang di pohon daripada yang ingin Anda hitung, maka
$ git rebase -i 123abcd~
di mana 123abcdSHA1 dari komit yang ingin Anda pisahkan.
Jika Anda berada di cabang yang berbeda (mis., Cabang fitur) yang Anda rencanakan untuk digabungkan menjadi master:
$ git rebase -i master
Saat Anda mendapatkan layar edit rebase, temukan komit yang ingin Anda pisahkan. Di awal baris itu, ganti pickdengan edit( esingkatnya). Simpan buffer dan keluar. Rebase sekarang akan berhenti tepat setelah komit yang ingin Anda edit. Kemudian:
$ git reset HEAD~
Komit potongan secara individual dengan cara biasa, menghasilkan komitmen sebanyak yang Anda butuhkan
Terima kasih atas jawaban ini. Saya ingin memiliki beberapa file yang sebelumnya dilakukan di area pementasan, jadi instruksi untuk saya sedikit berbeda. Sebelum aku bisa git rebase --continue, aku benar-benar harus git add (files to be added), git commit, maka git stash(untuk file yang tersisa). Setelah itu git rebase --continue, saya biasa git checkout stash .mendapatkan file yang tersisa
Eric Hu
18
Jawaban manojlds sebenarnya memiliki tautan ini ke dokumentasi di git-scm , yang juga menjelaskan proses pemisahan commit dengan sangat jelas.
56
Anda juga akan ingin memanfaatkan git add -puntuk menambahkan hanya sebagian file, mungkin dengan eopsi untuk mengedit diffs untuk hanya melakukan sebagian dari sebongkah. git stashjuga berguna jika Anda ingin melanjutkan pekerjaan tetapi menghapusnya dari komit saat ini.
Craig Ringer
2
Jika Anda ingin memecah dan menyusun ulang komit, yang ingin saya lakukan adalah memecah dulu dan kemudian menyusun ulang secara terpisah menggunakan git rebase -i HEAD^3perintah lain . Dengan cara ini jika perpecahan menjadi buruk, Anda tidak harus membatalkan banyak pekerjaan.
David M. Lloyd
4
@ kralyk File-file yang baru dilakukan di HEAD akan dibiarkan di disk setelah git reset HEAD~. Mereka tidak tersesat.
Dalam mode interaktif, Anda dapat menandai komit dengan tindakan "edit". Namun, ini tidak berarti bahwa git rebase mengharapkan hasil edit ini tepat satu komit. Memang, Anda dapat membatalkan komit, atau Anda dapat menambahkan komit lainnya. Ini dapat digunakan untuk membagi komit menjadi dua:
Mulai rebase interaktif dengan git rebase -i <commit>^, di mana <commit>komit yang ingin Anda bagi. Faktanya, rentang komit apa pun akan dilakukan, asalkan berisi komit itu.
Tandai komit yang ingin Anda bagi dengan tindakan "edit".
Ketika datang untuk mengedit komit itu, jalankan git reset HEAD^. Efeknya adalah bahwa KEPALA digulung ulang oleh satu, dan indeks mengikuti. Namun, pohon yang bekerja tetap sama.
Sekarang tambahkan perubahan ke indeks yang ingin Anda miliki di komit pertama. Anda dapat menggunakan git add(mungkin secara interaktif) atau git gui(atau keduanya) untuk melakukan itu.
Komit indeks sekarang-saat ini dengan pesan komit apa pun yang sesuai sekarang.
Ulangi dua langkah terakhir hingga pohon kerja Anda bersih.
Kata peringatan: dengan pendekatan ini saya kehilangan pesan komit.
user420667
11
@ user420667 Ya, tentu saja. Kami adalah resetting komit, setelah semua - pesan disertakan. Hal bijaksana yang harus dilakukan, jika Anda tahu Anda akan membagi komit tetapi ingin menyimpan sebagian / semua pesannya, adalah mengambil salinan pesan itu. Jadi, git showkomit sebelum rebaseing, atau jika Anda lupa atau lebih suka ini: kembali lagi nanti melalui reflog. Tidak ada satupun yang benar-benar akan "hilang" sampai sampah dikumpulkan dalam 2 minggu atau apa pun.
underscore_d
4
~dan ^hal-hal yang berbeda, bahkan pada Windows. Anda masih menginginkan tanda sisir ^, jadi Anda hanya perlu menghindarinya sesuai dengan kulit Anda. Di PowerShell, itu HEAD`^. Dengan cmd.exe, Anda dapat melipatgandakannya menjadi seperti HEAD^^. Di sebagian besar (semua?) Kerang, Anda bisa dikelilingi dengan tanda kutip suka "HEAD^".
AndrewF
7
Anda juga bisa melakukannya git commit --reuse-message=abcd123. Pilihan singkat untuk itu adalah -C.
j0057
41
Gunakan git rebase --interactiveuntuk mengedit komit sebelumnya, jalankan git reset HEAD~, lalu git add -ptambahkan beberapa, lalu buat komit, lalu tambahkan lagi dan buat komit lain, sebanyak yang Anda suka. Setelah selesai, jalankan git rebase --continue, dan Anda akan memiliki semua komit sebelumnya di tumpukan Anda.
Penting : Perhatikan bahwa Anda dapat bermain-main dan membuat semua perubahan yang Anda inginkan, dan tidak perlu khawatir kehilangan perubahan lama, karena Anda selalu dapat menjalankan git refloguntuk menemukan titik di proyek Anda yang berisi perubahan yang Anda inginkan, (sebut saja a8c4ab) , lalu git reset a8c4ab.
Berikut serangkaian perintah untuk menunjukkan cara kerjanya:
mkdir git-test; cd git-test; git init
sekarang tambahkan file A
vi A
tambahkan baris ini:
one
git commit -am one
kemudian tambahkan baris ini ke A:
two
git commit -am two
kemudian tambahkan baris ini ke A:
three
git commit -am three
sekarang file A terlihat seperti ini:
one
two
three
dan git logpenampilan kami seperti berikut (well, saya gunakangit log --pretty=oneline --pretty="%h %cn %cr ---- %s"
bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one
Katakanlah kita ingin membagi komit kedua two,.
git rebase --interactive HEAD~2
Ini memunculkan pesan yang terlihat seperti ini:
pick 2b613bc two
pick bfb8e46 three
Ubah yang pertama pickmenjadi yang emengedit komit itu.
git reset HEAD~
git diff menunjukkan kepada kami bahwa kami baru saja membatalkan komitmen yang kami buat untuk komitmen kedua:
diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two
Mari tahap perubahan itu, dan tambahkan "dan yang ketiga" ke baris dalam file A.
git add .
Ini biasanya merupakan titik selama rebase interaktif tempat kami menjalankan git rebase --continue, karena kami biasanya hanya ingin kembali ke tumpukan komit untuk mengedit komit sebelumnya. Tapi kali ini, kami ingin membuat komitmen baru. Jadi kita akan lari git commit -am 'two and a third'. Sekarang kita edit file Adan tambahkan baris two and two thirds.
git add .git commit -am 'two and two thirds'git rebase --continue
Kami memiliki konflik dengan komit kami three, jadi mari kita selesaikan:
Kami akan berubah
one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three
untuk
one
two and a third
two and two thirds
three
git add .; git rebase --continue
Sekarang git log -ppenampilan kami seperti ini:
commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 13:57:00 2013 -0700
three
diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
one
two and a third
two and two thirds
+three
commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 14:07:07 2013 -0700
two and two thirds
diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
one
two and a third
+two and two thirds
commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 14:06:40 2013 -0700
two and a third
diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two and a third
commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 13:56:40 2013 -0700
one
diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one
Jawaban sebelumnya telah mencakup penggunaan git rebase -iuntuk mengedit komit yang ingin Anda bagi, dan mengkomitnya dalam beberapa bagian.
Ini berfungsi dengan baik ketika memisahkan file menjadi komit yang berbeda, tetapi jika Anda ingin memecah perubahan pada file individual, ada lagi yang perlu Anda ketahui.
Setelah mencapai komit yang ingin Anda bagi, gunakan rebase -idan tandai untuk itu edit, Anda memiliki dua opsi.
Setelah menggunakan git reset HEAD~, buka tambalan satu per satu menggunakan git add -puntuk memilih yang Anda inginkan di setiap komit
Edit copy pekerjaan untuk menghapus perubahan yang tidak Anda inginkan; melakukan negara sementara itu; dan kemudian menarik kembali komit penuh untuk putaran berikutnya.
Opsi 2 berguna jika Anda membagi komit besar, karena memungkinkan Anda memeriksa bahwa versi sementara membangun dan berjalan dengan baik sebagai bagian dari penggabungan. Ini hasil sebagai berikut.
Setelah menggunakan rebase -idan editmengkomit, gunakan
git reset --soft HEAD~
untuk membatalkan komit, tetapi biarkan file berkomitmen dalam indeks. Anda juga dapat melakukan reset campuran dengan menghilangkan --soft, tergantung pada seberapa dekat dengan hasil akhir komit awal Anda. Satu-satunya perbedaan adalah apakah Anda memulai dengan semua perubahan yang dipentaskan atau dengan mereka semua tidak dipentaskan.
Sekarang masuk dan edit kode. Anda dapat menghapus perubahan, menghapus file yang ditambahkan, dan melakukan apa pun yang Anda inginkan untuk membangun komit pertama dari seri yang Anda cari. Anda juga dapat membangunnya, menjalankannya, dan mengonfirmasi bahwa Anda memiliki kumpulan sumber yang konsisten.
Setelah Anda bahagia, tahap / hapus stage file yang diperlukan (saya suka menggunakan git guiini), dan komit perubahan melalui UI atau baris perintah
git commit
Itu komit pertama yang dilakukan. Sekarang Anda ingin mengembalikan copy pekerjaan Anda ke status setelah komit yang Anda bagi, sehingga Anda dapat mengambil lebih banyak perubahan untuk komit berikutnya. Untuk menemukan sha1 dari komit yang Anda edit, gunakan git status. Di beberapa baris pertama dari status Anda akan melihat perintah rebase yang sedang dijalankan, di mana Anda dapat menemukan sha1 dari komit asli Anda:
$ git status
interactive rebase in progress; onto be83b41
Last commands done (3 commands done):
pick 4847406 US135756: add debugging to the file download code
e 65dfb6a US135756: write data and download from remote
(see more in file .git/rebase-merge/done)
...
Dalam hal ini, komit yang saya edit memiliki sha1 65dfb6a. Mengetahui hal itu, saya dapat memeriksa konten komit di direktori kerja saya menggunakan bentuk git checkoutyang mengambil komit dan lokasi file. Di sini saya gunakan .sebagai lokasi file untuk mengganti seluruh copy pekerjaan:
git checkout 65dfb6a .
Jangan sampai ketinggalan titik di ujungnya!
Ini akan memeriksa, dan menampilkan, file-file tersebut setelah komit yang Anda edit, tetapi relatif terhadap komit sebelumnya yang Anda buat, jadi setiap perubahan yang sudah Anda komit tidak akan menjadi bagian dari komit.
Anda dapat melanjutkan sekarang dan komit apa adanya untuk menyelesaikan pemisahan, atau berkeliling lagi, menghapus beberapa bagian dari komit sebelum membuat komit sementara lainnya.
Jika Anda ingin menggunakan kembali pesan komit asli untuk satu atau lebih komit, Anda dapat menggunakannya langsung dari file kerja rebase:
git commit --file .git/rebase-merge/message
Akhirnya, setelah Anda melakukan semua perubahan,
git rebase --continue
akan melanjutkan dan menyelesaikan operasi rebase.
Terima kasih!!! Ini harus menjadi jawaban yang diterima. Akan menyelamatkan saya banyak waktu dan rasa sakit hari ini. Ini satu-satunya jawaban di mana hasil dari komit akhir membawa Anda ke status yang sama dengan komit yang sedang diedit.
Doug Coburn
1
Saya suka cara Anda menggunakan pesan komit asli.
Salamandar
Menggunakan opsi 2, ketika saya melakukannya git checkout *Sha I'm Editing* .selalu mengatakan Updated 0 paths from *Some Sha That's Not In Git Log*dan tidak memberikan perubahan.
Dalam mode interaktif, Anda dapat menandai komit dengan tindakan "edit". Namun, ini tidak berarti bahwa git rebasemengharapkan hasil edit ini tepat satu komit. Memang, Anda dapat membatalkan komit, atau Anda dapat menambahkan komit lainnya. Ini dapat digunakan untuk membagi komit menjadi dua:
Mulai rebase interaktif dengan git rebase -i <commit>^, di mana <commit>komit yang ingin Anda bagi. Faktanya, rentang komit apa pun akan dilakukan, asalkan berisi komit itu.
Tandai komit yang ingin Anda bagi dengan tindakan "edit".
Ketika datang untuk mengedit komit itu, jalankan git reset HEAD^. Efeknya adalah bahwa KEPALA digulung ulang oleh satu, dan indeks mengikuti. Namun, pohon yang bekerja tetap sama.
Sekarang tambahkan perubahan ke indeks yang ingin Anda miliki di komit pertama. Anda dapat menggunakan git add(mungkin secara interaktif) atau git gui (atau keduanya) untuk melakukan itu.
Komit indeks sekarang-saat ini dengan pesan komit apa pun yang sesuai sekarang.
Ulangi dua langkah terakhir hingga pohon kerja Anda bersih.
Lanjutkan rebase dengan git rebase --continue.
Jika Anda tidak benar-benar yakin bahwa revisi menengah konsisten (mereka mengkompilasi, lulus testuite, dll.) Anda harus menggunakan git stashuntuk menyembunyikan perubahan yang belum berkomitmen setelah setiap komit, menguji, dan mengubah komit jika perbaikan diperlukan .
Di bawah Windows, ingat ^adalah karakter pelarian untuk baris perintah: itu harus dua kali lipat. Sebagai contoh, masalah git reset HEAD^^bukan git reset HEAD^.
Frédéric
@ Frédéric: s Saya tidak pernah mengalami ini. Setidaknya di PowerShell, ini bukan masalahnya. Kemudian gunakan ^dua kali reset dua komit di atas KEPALA saat ini.
Farway
@ Farway, coba di baris perintah klasik. PowerShell adalah binatang yang sangat berbeda, karakter pelariannya adalah backtilt.
Frédéric
Untuk meringkas: "HEAD^"di cmd.exe atau PowerShell, HEAD^^di cmd.exe, HEAD`^di PowerShell. Ini berguna untuk mempelajari tentang bagaimana shell - dan shell khusus Anda - bekerja (yaitu, bagaimana sebuah perintah berubah menjadi bagian-bagian individual yang dapat diteruskan ke program) sehingga Anda dapat menyesuaikan perintah secara online menjadi karakter yang tepat untuk shell Anda. (Tidak spesifik untuk Windows.)
AndrewF
11
Sekarang di TortoiseGit terbaru di Windows Anda dapat melakukannya dengan sangat mudah.
Buka dialog rebase, konfigurasikan , dan lakukan langkah-langkah berikut.
Klik kanan komit yang ingin Anda bagi dan pilih " Edit" (di antara pick, squash, delete ...).
Klik "Start " untuk memulai rebasing.
Setelah sampai pada komit untuk dibelah, centang tombol " Edit/Split" dan klik " Amend" secara langsung. Dialog komit terbuka.
Batalkan pilihan file yang ingin Anda tempatkan pada komit terpisah.
Edit pesan komit, lalu klik "commit ".
Sampai ada file untuk dikomit, dialog komit akan terbuka lagi dan lagi. Ketika tidak ada lagi file untuk dikomit, itu masih akan bertanya apakah Anda ingin menambahkan satu lagi komitmen.
Memberikan sedikit lebih banyak konteks tentang bagaimana mendekati isu vs hanya memberikan RTFM akan sedikit lebih membantu.
Jordan Dea-Mattson
8
Harap perhatikan ada juga git reset --soft HEAD^. Ini mirip dengan git reset(yang defaultnya --mixed) tetapi tetap mempertahankan isi indeks. Sehingga jika Anda telah menambahkan / menghapus file, Anda sudah memilikinya dalam indeks.
Berikut adalah cara membagi satu komit di IntelliJ IDEA , PyCharm , PhpStorm dll
Di jendela Log kontrol versi, pilih komit yang ingin Anda bagi, klik kanan dan pilih Interactively Rebase from Here
tandai yang ingin Anda bagi sebagai edit, klikStart
Rebasing
Anda akan melihat tag kuning ditempatkan yang berarti bahwa KEPALA diatur ke komit itu. Klik kanan komit itu, pilihUndo Commit
Sekarang komit tersebut kembali ke area pementasan, Anda kemudian dapat mengkomitnya secara terpisah. Setelah semua perubahan dilakukan, komitmen lama menjadi tidak aktif.
Hal termudah untuk dilakukan tanpa rebase interaktif adalah (mungkin) membuat cabang baru mulai dari komit sebelum komit yang ingin Anda bagi, ceri-pilih-di komit, reset, simpanan, komit pemindahan file, aplikasikan simpanan simpanan dan melakukan perubahan, dan kemudian bergabung dengan cabang sebelumnya atau memilih-ceri komitmen yang diikuti. (Kemudian alihkan nama cabang sebelumnya ke kepala saat ini.) (Mungkin lebih baik untuk mengikuti saran MBO dan melakukan rebase interaktif.)
menurut SO standar hari ini ini harus memenuhi syarat sebagai bukan jawaban; tetapi ini masih bisa bermanfaat bagi orang lain, jadi jika Anda tidak keberatan, silakan pindahkan ini ke komentar dari pos asli
YakovL
@YakovL Sepertinya masuk akal. Atas dasar tindakan minimal, saya tidak akan menghapus jawaban, tapi saya tidak akan keberatan jika orang lain melakukannya.
William Pursell
ini akan jauh lebih mudah daripada semua rebase -isaran. Saya pikir ini tidak mendapatkan banyak perhatian karena kurangnya format apa pun. Mungkin Anda bisa memeriksanya, sekarang Anda memiliki poin 126k dan mungkin tahu caranya. ;)
erikbwork
2
Saya pikir itu cara terbaik yang saya gunakan git rebase -i. Saya membuat video untuk menunjukkan langkah-langkah untuk membagi komit: https://www.youtube.com/watch?v=3EzOz7e1ADI
Sudah lebih dari 8 tahun, tetapi mungkin seseorang akan merasa terbantu. Saya bisa melakukan trik tanpa rebase -i. Idenya adalah untuk memimpin git ke kondisi yang sama sebelum Anda melakukannya git commit:
# first rewind back (mind the dot,# though it can be any valid path,# for instance if you want to apply only a subset of the commit)
git reset --hard <previous-commit>.# apply the changes
git checkout <commit-you-want-to-split># we're almost there, but the changes are in the index at the moment,# hence one more step (exactly as git gently suggests):# (use "git reset HEAD <file>..." to unstage)
git reset
Setelah ini, Anda akan melihat ini mengkilap Unstaged changes after reset:dan repo Anda dalam keadaan seperti Anda akan melakukan semua file ini. Mulai sekarang Anda dapat dengan mudah melakukan itu lagi seperti biasa. Semoga ini bisa membantu.
git autorebase split COMMIT_ID
git reset HEAD~
,git stash
, makagit cherry-pick
yang pertama melakukan dalam labu, lalugit stash pop
. Kasing ceri saya cukup spesifik di sini, tapigit stash
dangit stash pop
cukup berguna untuk orang lain.Jawaban:
git rebase -i
akan melakukannya.Pertama, mulailah dengan direktori kerja bersih:
git status
seharusnya tidak menunjukkan modifikasi, penghapusan, atau penambahan yang tertunda.Sekarang, Anda harus memutuskan komit yang ingin Anda bagi.
A) Memisahkan komit terbaru
Untuk memisahkan komit terbaru Anda, pertama:
Sekarang lakukan potongan secara individual dengan cara biasa, menghasilkan komitmen sebanyak yang Anda butuhkan.
B) Membagi komit lebih jauh ke belakang
Ini membutuhkan rebasing , yaitu penulisan ulang sejarah. Untuk menemukan komit yang benar, Anda memiliki beberapa pilihan:
Jika tiga komit kembali, maka
di mana
3
berapa banyak komit kembali itu.Jika lebih jauh ke belakang di pohon daripada yang ingin Anda hitung, maka
di mana
123abcd
SHA1 dari komit yang ingin Anda pisahkan.Jika Anda berada di cabang yang berbeda (mis., Cabang fitur) yang Anda rencanakan untuk digabungkan menjadi master:
Saat Anda mendapatkan layar edit rebase, temukan komit yang ingin Anda pisahkan. Di awal baris itu, ganti
pick
denganedit
(e
singkatnya). Simpan buffer dan keluar. Rebase sekarang akan berhenti tepat setelah komit yang ingin Anda edit. Kemudian:Komit potongan secara individual dengan cara biasa, menghasilkan komitmen sebanyak yang Anda butuhkan
sumber
git rebase --continue
, aku benar-benar harusgit add (files to be added)
,git commit
, makagit stash
(untuk file yang tersisa). Setelah itugit rebase --continue
, saya biasagit checkout stash .
mendapatkan file yang tersisagit add -p
untuk menambahkan hanya sebagian file, mungkin dengane
opsi untuk mengedit diffs untuk hanya melakukan sebagian dari sebongkah.git stash
juga berguna jika Anda ingin melanjutkan pekerjaan tetapi menghapusnya dari komit saat ini.git rebase -i HEAD^3
perintah lain . Dengan cara ini jika perpecahan menjadi buruk, Anda tidak harus membatalkan banyak pekerjaan.git reset HEAD~
. Mereka tidak tersesat.Dari manual git-rebase (bagian KOMIT TETAP)
sumber
~
bukan^
.reset
ting komit, setelah semua - pesan disertakan. Hal bijaksana yang harus dilakukan, jika Anda tahu Anda akan membagi komit tetapi ingin menyimpan sebagian / semua pesannya, adalah mengambil salinan pesan itu. Jadi,git show
komit sebelumrebase
ing, atau jika Anda lupa atau lebih suka ini: kembali lagi nanti melaluireflog
. Tidak ada satupun yang benar-benar akan "hilang" sampai sampah dikumpulkan dalam 2 minggu atau apa pun.~
dan^
hal-hal yang berbeda, bahkan pada Windows. Anda masih menginginkan tanda sisir^
, jadi Anda hanya perlu menghindarinya sesuai dengan kulit Anda. Di PowerShell, ituHEAD`^
. Dengan cmd.exe, Anda dapat melipatgandakannya menjadi sepertiHEAD^^
. Di sebagian besar (semua?) Kerang, Anda bisa dikelilingi dengan tanda kutip suka"HEAD^"
.git commit --reuse-message=abcd123
. Pilihan singkat untuk itu adalah-C
.Gunakan
git rebase --interactive
untuk mengedit komit sebelumnya, jalankangit reset HEAD~
, lalugit add -p
tambahkan beberapa, lalu buat komit, lalu tambahkan lagi dan buat komit lain, sebanyak yang Anda suka. Setelah selesai, jalankangit rebase --continue
, dan Anda akan memiliki semua komit sebelumnya di tumpukan Anda.Penting : Perhatikan bahwa Anda dapat bermain-main dan membuat semua perubahan yang Anda inginkan, dan tidak perlu khawatir kehilangan perubahan lama, karena Anda selalu dapat menjalankan
git reflog
untuk menemukan titik di proyek Anda yang berisi perubahan yang Anda inginkan, (sebut sajaa8c4ab
) , lalugit reset a8c4ab
.Berikut serangkaian perintah untuk menunjukkan cara kerjanya:
mkdir git-test; cd git-test; git init
sekarang tambahkan file
A
vi A
tambahkan baris ini:
one
git commit -am one
kemudian tambahkan baris ini ke A:
two
git commit -am two
kemudian tambahkan baris ini ke A:
three
git commit -am three
sekarang file A terlihat seperti ini:
dan
git log
penampilan kami seperti berikut (well, saya gunakangit log --pretty=oneline --pretty="%h %cn %cr ---- %s"
Katakanlah kita ingin membagi komit kedua
two
,.git rebase --interactive HEAD~2
Ini memunculkan pesan yang terlihat seperti ini:
Ubah yang pertama
pick
menjadi yange
mengedit komit itu.git reset HEAD~
git diff
menunjukkan kepada kami bahwa kami baru saja membatalkan komitmen yang kami buat untuk komitmen kedua:Mari tahap perubahan itu, dan tambahkan "dan yang ketiga" ke baris dalam file
A
.git add .
Ini biasanya merupakan titik selama rebase interaktif tempat kami menjalankan
git rebase --continue
, karena kami biasanya hanya ingin kembali ke tumpukan komit untuk mengedit komit sebelumnya. Tapi kali ini, kami ingin membuat komitmen baru. Jadi kita akan larigit commit -am 'two and a third'
. Sekarang kita edit fileA
dan tambahkan baristwo and two thirds
.git add .
git commit -am 'two and two thirds'
git rebase --continue
Kami memiliki konflik dengan komit kami
three
, jadi mari kita selesaikan:Kami akan berubah
untuk
git add .; git rebase --continue
Sekarang
git log -p
penampilan kami seperti ini:sumber
Jawaban sebelumnya telah mencakup penggunaan
git rebase -i
untuk mengedit komit yang ingin Anda bagi, dan mengkomitnya dalam beberapa bagian.Ini berfungsi dengan baik ketika memisahkan file menjadi komit yang berbeda, tetapi jika Anda ingin memecah perubahan pada file individual, ada lagi yang perlu Anda ketahui.
Setelah mencapai komit yang ingin Anda bagi, gunakan
rebase -i
dan tandai untuk ituedit
, Anda memiliki dua opsi.Setelah menggunakan
git reset HEAD~
, buka tambalan satu per satu menggunakangit add -p
untuk memilih yang Anda inginkan di setiap komitEdit copy pekerjaan untuk menghapus perubahan yang tidak Anda inginkan; melakukan negara sementara itu; dan kemudian menarik kembali komit penuh untuk putaran berikutnya.
Opsi 2 berguna jika Anda membagi komit besar, karena memungkinkan Anda memeriksa bahwa versi sementara membangun dan berjalan dengan baik sebagai bagian dari penggabungan. Ini hasil sebagai berikut.
Setelah menggunakan
rebase -i
danedit
mengkomit, gunakanuntuk membatalkan komit, tetapi biarkan file berkomitmen dalam indeks. Anda juga dapat melakukan reset campuran dengan menghilangkan --soft, tergantung pada seberapa dekat dengan hasil akhir komit awal Anda. Satu-satunya perbedaan adalah apakah Anda memulai dengan semua perubahan yang dipentaskan atau dengan mereka semua tidak dipentaskan.
Sekarang masuk dan edit kode. Anda dapat menghapus perubahan, menghapus file yang ditambahkan, dan melakukan apa pun yang Anda inginkan untuk membangun komit pertama dari seri yang Anda cari. Anda juga dapat membangunnya, menjalankannya, dan mengonfirmasi bahwa Anda memiliki kumpulan sumber yang konsisten.
Setelah Anda bahagia, tahap / hapus stage file yang diperlukan (saya suka menggunakan
git gui
ini), dan komit perubahan melalui UI atau baris perintahItu komit pertama yang dilakukan. Sekarang Anda ingin mengembalikan copy pekerjaan Anda ke status setelah komit yang Anda bagi, sehingga Anda dapat mengambil lebih banyak perubahan untuk komit berikutnya. Untuk menemukan sha1 dari komit yang Anda edit, gunakan
git status
. Di beberapa baris pertama dari status Anda akan melihat perintah rebase yang sedang dijalankan, di mana Anda dapat menemukan sha1 dari komit asli Anda:Dalam hal ini, komit yang saya edit memiliki sha1
65dfb6a
. Mengetahui hal itu, saya dapat memeriksa konten komit di direktori kerja saya menggunakan bentukgit checkout
yang mengambil komit dan lokasi file. Di sini saya gunakan.
sebagai lokasi file untuk mengganti seluruh copy pekerjaan:Jangan sampai ketinggalan titik di ujungnya!
Ini akan memeriksa, dan menampilkan, file-file tersebut setelah komit yang Anda edit, tetapi relatif terhadap komit sebelumnya yang Anda buat, jadi setiap perubahan yang sudah Anda komit tidak akan menjadi bagian dari komit.
Anda dapat melanjutkan sekarang dan komit apa adanya untuk menyelesaikan pemisahan, atau berkeliling lagi, menghapus beberapa bagian dari komit sebelum membuat komit sementara lainnya.
Jika Anda ingin menggunakan kembali pesan komit asli untuk satu atau lebih komit, Anda dapat menggunakannya langsung dari file kerja rebase:
Akhirnya, setelah Anda melakukan semua perubahan,
akan melanjutkan dan menyelesaikan operasi rebase.
sumber
git checkout *Sha I'm Editing* .
selalu mengatakanUpdated 0 paths from *Some Sha That's Not In Git Log*
dan tidak memberikan perubahan.git rebase --interactive
dapat digunakan untuk membagi komit menjadi komit yang lebih kecil. The Git docs pada rebase memiliki panduan singkat dari proses - Komit Memisahkan :sumber
^
adalah karakter pelarian untuk baris perintah: itu harus dua kali lipat. Sebagai contoh, masalahgit reset HEAD^^
bukangit reset HEAD^
.^
dua kali reset dua komit di atas KEPALA saat ini."HEAD^"
di cmd.exe atau PowerShell,HEAD^^
di cmd.exe,HEAD`^
di PowerShell. Ini berguna untuk mempelajari tentang bagaimana shell - dan shell khusus Anda - bekerja (yaitu, bagaimana sebuah perintah berubah menjadi bagian-bagian individual yang dapat diteruskan ke program) sehingga Anda dapat menyesuaikan perintah secara online menjadi karakter yang tepat untuk shell Anda. (Tidak spesifik untuk Windows.)Sekarang di TortoiseGit terbaru di Windows Anda dapat melakukannya dengan sangat mudah.
Buka dialog rebase, konfigurasikan , dan lakukan langkah-langkah berikut.
Edit
" (di antara pick, squash, delete ...).Start
" untuk memulai rebasing.Edit/Split
" dan klik "Amend
" secara langsung. Dialog komit terbuka.commit
".Sangat membantu, terima kasih TortoiseGit!
sumber
Anda dapat melakukan rebase interaktif
git rebase -i
. Halaman manual memiliki apa yang Anda inginkan:http://git-scm.com/docs/git-rebase#_splitting_commits
sumber
Harap perhatikan ada juga
git reset --soft HEAD^
. Ini mirip dengangit reset
(yang defaultnya--mixed
) tetapi tetap mempertahankan isi indeks. Sehingga jika Anda telah menambahkan / menghapus file, Anda sudah memilikinya dalam indeks.Ternyata sangat berguna jika komit raksasa.
sumber
Berikut adalah cara membagi satu komit di IntelliJ IDEA , PyCharm , PhpStorm dll
Di jendela Log kontrol versi, pilih komit yang ingin Anda bagi, klik kanan dan pilih
Interactively Rebase from Here
tandai yang ingin Anda bagi sebagai
edit
, klikStart Rebasing
Anda akan melihat tag kuning ditempatkan yang berarti bahwa KEPALA diatur ke komit itu. Klik kanan komit itu, pilih
Undo Commit
Sekarang komit tersebut kembali ke area pementasan, Anda kemudian dapat mengkomitnya secara terpisah. Setelah semua perubahan dilakukan, komitmen lama menjadi tidak aktif.
sumber
Hal termudah untuk dilakukan tanpa rebase interaktif adalah (mungkin) membuat cabang baru mulai dari komit sebelum komit yang ingin Anda bagi, ceri-pilih-di komit, reset, simpanan, komit pemindahan file, aplikasikan simpanan simpanan dan melakukan perubahan, dan kemudian bergabung dengan cabang sebelumnya atau memilih-ceri komitmen yang diikuti. (Kemudian alihkan nama cabang sebelumnya ke kepala saat ini.) (Mungkin lebih baik untuk mengikuti saran MBO dan melakukan rebase interaktif.)
sumber
rebase -i
saran. Saya pikir ini tidak mendapatkan banyak perhatian karena kurangnya format apa pun. Mungkin Anda bisa memeriksanya, sekarang Anda memiliki poin 126k dan mungkin tahu caranya. ;)Saya pikir itu cara terbaik yang saya gunakan
git rebase -i
. Saya membuat video untuk menunjukkan langkah-langkah untuk membagi komit: https://www.youtube.com/watch?v=3EzOz7e1ADIsumber
Jika Anda memiliki ini:
Di mana Anda telah melakukan beberapa konten di komit B:
Tetapi Anda ingin membagi B menjadi C - D, dan dapatkan hasil ini:
Anda dapat membagi konten seperti ini misalnya (konten dari direktori berbeda di berbagai komitmen) ...
Setel ulang cabang kembali ke komit sebelum yang dibelah:
Buat komit pertama (C):
Buat komit kedua (D):
sumber
Sudah lebih dari 8 tahun, tetapi mungkin seseorang akan merasa terbantu. Saya bisa melakukan trik tanpa
rebase -i
. Idenya adalah untuk memimpin git ke kondisi yang sama sebelum Anda melakukannyagit commit
:Setelah ini, Anda akan melihat ini mengkilap
Unstaged changes after reset:
dan repo Anda dalam keadaan seperti Anda akan melakukan semua file ini. Mulai sekarang Anda dapat dengan mudah melakukan itu lagi seperti biasa. Semoga ini bisa membantu.sumber
Referensi cepat dari perintah yang diperlukan, karena pada dasarnya saya tahu apa yang harus dilakukan tetapi selalu lupa sintaks yang tepat:
Penghargaan untuk posting blog Emmanuel Bernard .
sumber