Pertanyaan Bagaimana cara memodifikasi commit tertentu di git?
Saya biasanya mengajukan daftar komitmen untuk ditinjau. Jika saya punya:
HEAD
Commit3
Commit2
Commit1
Saya tahu bahwa saya dapat memodifikasi komit dengan kepala git commit --amend
, tapi bagaimana saya bisa memodifikasi Commit1
, mengingat bahwa itu bukan HEAD
melakukan?
1700
2017-07-27 05:19
asal
Jawaban:
Anda dapat menggunakan git rebase, misalnya, jika Anda ingin memodifikasi kembali untuk melakukan bbc643cd
, lari
$ git rebase --interactive 'bbc643cd^'
Di editor default, ubah pick
untuk edit
di garis yang komit Anda ingin memodifikasi. Buat perubahan Anda dan kemudian lakukan dengan pesan yang sama seperti sebelumnya:
$ git commit --all --amend --no-edit
untuk mengubah komit, dan setelah itu
$ git rebase --continue
untuk kembali ke komit sebelumnya.
PERINGATAN: Perhatikan bahwa ini akan mengubah SHA-1 yang melakukan serta semua anak - dengan kata lain, ini menulis ulang sejarah dari titik itu ke depan. Anda dapat mematahkan repo melakukan ini jika Anda mendorong menggunakan perintah git push --force
2232
2017-07-27 05:28
Gunakan rebase interaktif yang mengagumkan:
git rebase -i @~9 # Show the last 9 commits in a text editor
Temukan komitmen yang Anda inginkan, ubah pick
untuk e
(edit
), dan simpan dan tutup file. Git akan memundurkan ke commit itu, memungkinkan Anda untuk:
- menggunakan
git commit --amend
untuk melakukan perubahan, atau
- menggunakan
git reset @~
untuk membuang commit terakhir, tetapi tidak mengubah file (yaitu membawa Anda ke titik di mana Anda mengedit file, tetapi belum melakukannya).
Yang terakhir ini berguna untuk melakukan hal-hal yang lebih kompleks seperti membagi menjadi beberapa komit.
Lalu lari git rebase --continue
, dan Git akan memutar ulang perubahan selanjutnya di bagian atas komitmen Anda yang dimodifikasi. Anda mungkin diminta untuk memperbaiki beberapa konflik gabungan.
catatan: @
adalah singkatan untuk HEAD
, dan ~
adalah commit sebelum commit yang ditentukan.
Baca lebih lanjut tentang menulis ulang sejarah dalam dokumen Git.
Jangan takut untuk melakukan rebase
ProTip: Jangan takut untuk bereksperimen dengan perintah "berbahaya" yang menulis ulang riwayat * - Git tidak menghapus commit Anda selama 90 hari secara default; Anda dapat menemukannya di reflog:
$ git reset @~3 # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started
* Hati-hati untuk opsi seperti --hard
dan --force
meskipun - mereka dapat membuang data.
* Juga, jangan menulis ulang sejarah di cabang mana pun Anda berkolaborasi.
Di banyak sistem, git rebase -i
akan membuka Vim secara default. Vim tidak berfungsi seperti kebanyakan editor teks modern, jadi lihatlah cara melakukan rebase menggunakan Vim. Jika Anda lebih suka menggunakan editor yang berbeda, ubahlah dengan git config --global core.editor your-favorite-text-editor
.
304
2018-04-29 17:50
Interaktif rebase dengan --autosquash
adalah sesuatu yang sering saya gunakan ketika saya harus memperbaiki sebelumnya melakukan lebih dalam dalam sejarah. Pada dasarnya ini mempercepat proses yang diilustrasikan oleh jawaban ZelluX, dan sangat berguna ketika Anda memiliki lebih dari satu komitmen yang perlu Anda edit.
Dari dokumentasi:
--autosquash
Ketika pesan log commit dimulai dengan "squash! ..." (atau "fixup! ..."), dan ada komit yang judulnya dimulai dengan yang sama ..., secara otomatis memodifikasi daftar todo dari rebase -i sehingga commit ditandai untuk meremas datang tepat setelah komit dimodifikasi
Asumsikan Anda memiliki riwayat yang terlihat seperti ini:
$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1
dan Anda memiliki perubahan yang ingin Anda ubah ke Commit2 lalu komit perubahan Anda gunakan
$ git commit -m "fixup! Commit2"
atau Anda dapat menggunakan commit-sha sebagai ganti dari pesan commit, jadi "fixup! e8adec4
atau bahkan hanya awalan pesan komit.
Kemudian lakukan rebase interaktif pada commit sebelumnya
$ git rebase e8adec4^ -i --autosquash
editor Anda akan terbuka dengan komit yang sudah dipesan dengan benar
pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3
yang perlu Anda lakukan hanyalah menyimpan dan keluar
57
2017-09-29 17:59
Menjalankan:
$ git rebase --interactive commit_hash^
setiap ^
menunjukkan berapa banyak commit yang ingin Anda edit, jika hanya satu (hash komit yang Anda tentukan), maka Anda cukup menambahkan satu ^
.
Menggunakan Vim Anda mengubah kata-kata pick
untuk reword
untuk komit yang ingin Anda ubah, simpan dan berhenti (:wq
). Kemudian git akan meminta Anda dengan setiap commit yang Anda tandai sebagai reword sehingga Anda dapat mengubah pesan commit.
Setiap pesan komit Anda harus menyimpan dan berhenti (:wq
) untuk membuka pesan commit berikutnya
Jika Anda ingin keluar tanpa menerapkan perubahan, tekan :q!
EDIT: untuk menavigasi vim
Kau gunakan j
naik, k
ke bawah, h
ke kiri, dan l
untuk pergi ke kanan (semua ini masuk NORMAL
mode, tekan ESC
pergi ke NORMAL
mode).
Untuk mengedit teks, tekan i
sehingga Anda memasukkan INSERT
mode, tempat Anda memasukkan teks.
tekan ESC
untuk kembali ke NORMAL
mode :)
MEMPERBARUI: Ini tautan hebat dari daftar github Bagaimana cara membatalkan (hampir) apa pun dengan git
30
2017-07-02 19:11
Jika karena alasan tertentu Anda tidak menyukai editor interaktif, Anda dapat menggunakannya git rebase --onto
.
Katakanlah Anda ingin memodifikasi Commit1
. Pertama, cabang dari sebelum Commit1
:
git checkout -b amending [commit before Commit1]
Kedua, ambil Commit1
dengan cherry-pick
:
git cherry-pick Commit1
Sekarang, ubah perubahan Anda, buat Commit1'
:
git add ...
git commit --amend -m "new message for Commit1"
Dan akhirnya, setelah menyembunyikan perubahan lain, lakukan transplantasi sisa komitmen Anda master
di atas kamu
komit baru:
git rebase --onto amending Commit1 master
Baca: "rebase, ke cabang amending
, semua komit di antaranya Commit1
(tidak inklusif) dan master
(inklusif) ". Artinya, Commit2 dan Commit3, memotong Commit1 lama sepenuhnya. Anda hanya bisa memilihnya, tetapi cara ini lebih mudah.
Ingatlah untuk membersihkan cabang Anda!
git branch -d amending
12
2017-10-22 12:19
Datang ke pendekatan ini (dan itu mungkin persis sama dengan menggunakan rebase interaktif) tetapi bagi saya itu agak mudah.
Catatan: Saya menyajikan pendekatan ini demi ilustrasi tentang apa yang dapat Anda lakukan daripada alternatif sehari-hari. Karena memiliki banyak langkah (dan mungkin beberapa peringatan.)
Katakanlah Anda ingin mengubah komit 0
dan Anda sedang aktif feature-branch
some-commit---0---1---2---(feature-branch)HEAD
Checkout untuk ini berkomitmen dan membuat quick-branch
. Anda juga dapat mengkloning cabang fitur Anda sebagai titik pemulihan (sebelum memulai).
?(git checkout -b feature-branch-backup)
git checkout 0
git checkout -b quick-branch
Anda sekarang akan memiliki sesuatu seperti ini:
0(quick-branch)HEAD---1---2---(feature-branch)
Perubahan panggung, menyimpan semua yang lain.
git add ./example.txt
git stash
Lakukan perubahan dan periksa kembali feature-branch
git commit --amend
git checkout feature-branch
Anda sekarang akan memiliki sesuatu seperti ini:
some-commit---0---1---2---(feature-branch)HEAD
\
---0'(quick-branch)
Rebase feature-branch
ke quick-branch
(selesaikan setiap konflik di sepanjang jalan). Terapkan simpanan dan hapus quick-branch
.
git rebase quick-branch
git stash pop
git branch -D quick-branch
Dan Anda berakhir dengan:
some-commit---0'---1'---2'---HEAD(feature-branch)
Git tidak akan menduplikasi (walaupun saya tidak bisa benar-benar mengatakan sampai sejauh mana) 0 komit ketika melakukan rebase.
Catatan: semua commit hash diubah mulai dari commit yang semula kita inginkan untuk diubah.
6
2018-06-01 11:57
Untuk mendapatkan perintah non-interaktif, letakkan skrip dengan konten ini di PATH Anda:
#!/bin/sh
#
# git-fixup
# Use staged changes to modify a specified commit
set -e
cmt=$(git rev-parse $1)
git commit --fixup="$cmt"
GIT_EDITOR=true git rebase -i --autosquash "$cmt~1"
Gunakan dengan mementaskan perubahan Anda (dengan git add
) dan kemudian jalankan git fixup <commit-to-modify>
. Tentu saja, ini akan tetap interaktif jika Anda mengalami konflik.
4
2018-01-16 15:27