Saya sedang menulis skrip sederhana di komputer sekolah, dan melakukan perubahan pada Git (dalam repo yang ada di flashdisk saya, dikloning dari komputer saya di rumah). Setelah melakukan beberapa kali, saya menyadari bahwa saya melakukan hal-hal sebagai pengguna root.
Apakah ada cara untuk mengubah pembuat komitmen ini dengan nama saya?
git
version-control
git-filter-branch
git-rewrite-history
Flávio Amieiro
sumber
sumber
Jawaban:
Mengubah penulis (atau penglaju) akan membutuhkan penulisan ulang semua sejarah. Jika Anda setuju dengan itu dan berpikir itu layak maka Anda harus memeriksa cabang-filter git . Halaman manual berisi beberapa contoh untuk membantu Anda memulai. Perhatikan juga bahwa Anda dapat menggunakan variabel lingkungan untuk mengubah nama pembuat, pengalih, tanggal, dll. - lihat bagian "Variabel Lingkungan" dari halaman git man .
Secara khusus, Anda dapat memperbaiki semua nama penulis dan email yang salah untuk semua cabang dan tag dengan perintah ini (sumber: bantuan GitHub ):
sumber
git push --force --tags origin HEAD:master
CATATAN: Jawaban ini mengubah SHA1s, jadi berhati-hatilah menggunakannya pada cabang yang telah didorong. Jika Anda hanya ingin memperbaiki ejaan nama atau memperbarui email lama, git memungkinkan Anda melakukan ini tanpa menulis ulang riwayat menggunakan
.mailmap
. Lihat jawaban saya yang lain .Menggunakan Interaktif Rebase
Anda bisa melakukannya
Kemudian tandai semua komit buruk Anda sebagai "edit" di file rebase. Jika Anda juga ingin mengubah komit pertama Anda, Anda harus menambahkannya secara manual sebagai baris pertama dalam file rebase (ikuti format dari baris lain). Kemudian, ketika git meminta Anda untuk mengubah setiap commit, lakukan
edit atau tutup saja editor yang terbuka, lalu lakukan
untuk melanjutkan rebase.
Anda bisa melewatkan membuka editor sama sekali di sini dengan menambahkan
--no-edit
sehingga perintahnya adalah:Komit tunggal
Seperti yang dicatat oleh beberapa komentator, jika Anda hanya ingin mengubah komit terbaru, perintah rebase tidak diperlukan. Kerjakan saja
Ini akan mengubah penulis menjadi nama yang ditentukan, tetapi committer akan diatur ke pengguna yang dikonfigurasi di
git config user.name
dangit config user.email
. Jika Anda ingin mengatur committer ke sesuatu yang Anda tentukan, ini akan mengatur penulis dan committer:Catatan tentang Menggabungkan Komit
Ada sedikit cacat dalam respons awal saya. Jika ada komitmen gabungan antara saat ini
HEAD
dan Anda<some HEAD before all your bad commits>
, makagit rebase
akan meratakannya (dan omong-omong, jika Anda menggunakan permintaan tarik GitHub, akan ada banyak komitmen gabungan dalam riwayat Anda). Hal ini seringkali dapat menyebabkan sejarah yang sangat berbeda (karena perubahan duplikat mungkin "diubah"), dan dalam kasus terburuk, hal itu dapat menyebabkangit rebase
Anda meminta untuk menyelesaikan konflik penggabungan yang sulit (yang kemungkinan sudah diselesaikan dalam komitmen gabungan). Solusinya adalah dengan menggunakan-p
benderagit rebase
, yang akan mempertahankan struktur penggabungan sejarah Anda. Halaman untukgit rebase
memperingatkan bahwa menggunakan-p
dan-i
dapat menyebabkan masalah, tetapi dalamBUGS
bagian yang bertuliskan "Mengedit melakukan dan menulis ulang pesan komit mereka akan berfungsi dengan baik."Saya telah menambahkan
-p
perintah di atas. Untuk kasus di mana Anda baru saja mengubah komit terbaru, ini bukan masalah.sumber
git commit --amend --reset-author
juga berfungsi sekaliuser.name
danuser.email
dikonfigurasi dengan benar.<commit>
menggunakanuser.name
danuser.email
dari~/.gitconfig
: jalankangit rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit'
, simpan, keluar. Tidak perlu diedit!Anda juga dapat melakukan:
Catatan, jika Anda menggunakan perintah ini di prompt perintah Windows, maka Anda harus menggunakan
"
alih-alih'
:sumber
"A previous backup already exists in refs/original/ Force overwriting the backup with -f"
maaf tapi di mana-f
-flag akan berada ketika menjalankan skrip ini dua kali. Sebenarnya itu ada dalam jawaban Brian, maaf tentang gangguan tepat setelah cabang-filter adalah solusinya.Satu liner, tetapi berhati-hatilah jika Anda memiliki repositori multi-pengguna - ini akan mengubah semua komit untuk memiliki penulis dan pengangkat yang sama (baru).
Dengan linebreak di string (yang dimungkinkan dalam bash):
sumber
HEAD
di akhir perintah?git push --force --tags origin 'refs/heads/*'
setelah perintah yang disarankan$git push --force --tags origin 'refs/heads/master'
Ini terjadi ketika Anda tidak menginisialisasi $ HOME / .gitconfig. Anda dapat memperbaikinya sebagai:
diuji dengan git versi 1.7.5.4
sumber
--local
karya jugagit commit --amend --reset-author --no-edit
Perintah ini sangat berguna jika Anda membuat komit dengan informasi penulis yang salah, kemudian mengatur penulis yang benar setelah-the-fakta melaluigit config
. Menyimpan $$ saya sekarang ketika saya harus memperbarui email saya.Untuk satu komit:
(diekstraksi dari jawaban asmeurer's)
sumber
git help commit
,git commit --amend
perubahan komit di "ujung cabang saat ini" (yaitu KEPALA). Ini biasanya komit terbaru, tetapi Anda bisa membuatnya komit yang Anda inginkan dengan terlebih dahulu memeriksa komit itu dengangit checkout <branch-name>
ataugit checkout <commit-SHA>
.author
dan bukancommitter
Dalam kasus di mana hanya beberapa komit teratas memiliki penulis yang buruk, Anda dapat melakukan ini semua di dalam
git rebase -i
menggunakanexec
perintah dan--amend
komit, sebagai berikut:yang memberi Anda daftar komitmen yang dapat diedit:
Kemudian tambahkan
exec ... --author="..."
baris setelah semua baris dengan penulis yang buruk:simpan dan keluar dari editor (untuk menjalankan).
Solusi ini mungkin lebih panjang untuk diketik daripada yang lain, tetapi sangat dapat dikontrol - Saya tahu persis apa yang dilakukan.
Terima kasih kepada @asmeurer untuk ilhamnya.
sumber
exec git commit --amend --reset-author -C HEAD
?Someone else's commit
bukanmy bad commit 1
? Saya hanya mencobaHEAD^^
mengubah 2 komitmen terakhir, dan itu berfungsi dengan baik.git rebase -i HEAD^^^^^^
Anda juga dapat menulisgit rebase -i HEAD~6
Github memiliki solusi yang bagus , yaitu skrip shell berikut:
sumber
git reset --hard HEAD^
beberapa kali di repositori lokal lainnya untuk mendapatkan mereka ke versi sebelumnya,git pull
-dengan versi yang diubah, dan di sini saya tanpa baris yang mengandungunknown <[email protected]>
(harus suka default git).git push -f
. Juga, repo lokal harus dikloning kembali setelah ini.Seperti yang disebutkan oleh docgnome, menulis ulang sejarah itu berbahaya dan akan merusak gudang orang lain.
Tetapi jika Anda benar-benar ingin melakukan itu dan Anda berada dalam lingkungan bash (tidak ada masalah di Linux, di Windows, Anda dapat menggunakan git bash, yang disediakan dengan instalasi git), gunakan cabang-git filter :
Untuk mempercepat, Anda dapat menentukan rentang revisi yang ingin Anda tulis ulang:
sumber
--tag-name-filter cat
adalah opsi "membuatnya bekerja".--tag-name-filter cat
. Ini seharusnya merupakan perilaku default.Saat mengambil alih komitmen yang tidak dihapus dari penulis lain, ada cara mudah untuk menangani ini.
git commit --amend --reset-author
sumber
--no-edit
untuk membuat ini lebih mudah, karena umumnya kebanyakan orang hanya ingin memperbarui alamat email dan bukan pesan komitAnda dapat menggunakan ini sebagai alias sehingga Anda dapat melakukan:
atau selama 10 komit terakhir:
Tambahkan ke ~ / .gitconfig:
Sumber: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
Semoga bermanfaat.
sumber
[[ ]]
dengan tes yang kompatibel dengan sh[ ]
(kurung tunggal). Selain itu berfungsi dengan baik, terima kasih!Ini adalah versi @ Brian versi yang lebih rumit:
Untuk mengubah pembuat dan pengalih, Anda dapat melakukan ini (dengan linebreak di string yang dimungkinkan dalam bash):
Anda mungkin mendapatkan salah satu dari kesalahan ini:
(ini berarti cabang-filter lain telah dijalankan sebelumnya di repositori dan referensi cabang asli didukung di referensi / asli )
Jika Anda ingin memaksa menjalankan terlepas dari kesalahan ini, tambahkan
--force
bendera:Sedikit penjelasan tentang
-- --all
opsi mungkin diperlukan: Ini membuat cabang-filter bekerja pada semua revisi pada semua referensi (yang mencakup semua cabang). Ini berarti, misalnya, bahwa tag juga ditulis ulang dan terlihat pada cabang yang ditulis ulang."Kesalahan" yang umum adalah
HEAD
sebagai gantinya, yang berarti memfilter semua revisi hanya pada cabang saat ini . Dan kemudian tidak ada tag (atau referensi lainnya) akan ada di cabang yang ditulis ulang.sumber
Satu perintah untuk mengubah penulis untuk komit N terakhir:
CATATAN
--no-edit
merek bendera yakingit commit --amend
tidak meminta konfirmasi tambahangit rebase -i
, Anda dapat secara manual memilih komit tempat untuk mengubah penulis,file yang Anda edit akan terlihat seperti ini:
Anda masih dapat memodifikasi beberapa baris untuk melihat di mana Anda ingin mengubah penulis. Ini memberi Anda jalan tengah yang bagus antara otomatisasi dan kontrol: Anda melihat langkah-langkah yang akan berjalan, dan begitu Anda menyimpan semuanya akan diterapkan sekaligus.
sumber
git rebase -i master -x ...
git rebase -i <sha1 or ref of starting point>
edit
(ataue
)lilitkan dua perintah berikut hingga Anda telah memproses semua komitmen:
git commit --amend --reuse-message=HEAD --author="New Author <[email protected]>"
;git rebase --continue
Ini akan menyimpan semua informasi komit lainnya (termasuk tanggal). The
--reuse-message=HEAD
pilihan mencegah editor pesan dari launching.sumber
Saya menggunakan yang berikut ini untuk menulis ulang penulis untuk seluruh repositori, termasuk tag dan semua cabang:
Kemudian, seperti yang dijelaskan di halaman MAN cabang-filter , hapus semua referensi asli yang didukung oleh
filter-branch
(ini destruktif, cadangan dulu):sumber
--tag-name-filter cat
. Kalau tidak, tag Anda akan tetap berada di rantai komit asli. Jawaban lain gagal menyebutkan ini.Saya mengadaptasi solusi ini yang berfungsi dengan menelan sederhana
author-conv-file
(formatnya sama dengan git-cvsimport ). Ini bekerja dengan mengubah semua pengguna sebagaimana didefinisikan dalamauthor-conv-file
semua cabang.Kami menggunakan ini dalam hubungannya dengan
cvs2git
untuk memigrasi repositori kami dari cvs ke git.yaitu Sampel
author-conv-file
Naskah:
sumber
Saya harus menunjukkan bahwa jika satu-satunya masalah adalah bahwa penulis / email berbeda dari biasanya, ini bukan masalah. Perbaikan yang benar adalah dengan membuat file yang disebut
.mailmap
di dasar direktori dengan garis-garis sepertiDan sejak saat itu, perintah seperti
git shortlog
akan menganggap kedua nama itu sama (kecuali jika Anda secara khusus mengatakannya tidak demikian). Lihat http://schacon.github.com/git/git-shortlog.html untuk informasi lebih lanjut.Ini memiliki keunggulan dari semua solusi lain di sini karena Anda tidak perlu menulis ulang sejarah, yang dapat menyebabkan masalah jika Anda memiliki upstream, dan selalu merupakan cara yang baik untuk kehilangan data secara tidak sengaja.
Tentu saja, jika Anda melakukan sesuatu seperti diri Anda sendiri dan itu harus benar-benar orang lain, dan Anda tidak keberatan menulis ulang sejarah pada saat ini, mengubah penulis komit mungkin merupakan ide yang baik untuk tujuan atribusi (dalam hal ini saya mengarahkan Anda ke saya jawaban lain di sini).
sumber
Saya menemukan versi yang disajikan cara agresif, terutama jika Anda melakukan patch dari pengembang lain, ini pada dasarnya akan mencuri kode mereka.
Versi di bawah ini berfungsi pada semua cabang dan mengubah penulis dan komitter secara terpisah untuk mencegahnya.
Kudos to leif81 untuk semua opsi.
sumber
Ubah komit
author name & email
denganAmend
, lalu gantiold-commit with new-one
:Cara lain
Rebasing
:sumber
Cara tercepat dan termudah untuk melakukan ini adalah dengan menggunakan argumen --exec dari git rebase:
Ini akan membuat daftar todo yang terlihat seperti ini:
dan ini akan bekerja secara otomatis, yang berfungsi saat Anda memiliki ratusan komitmen.
sumber
Jika Anda adalah satu-satunya pengguna repositori ini, Anda dapat menulis ulang riwayat menggunakan salah satu
git filter-branch
(seperti svick menulis ), ataugit fast-export
/git fast-import
plus skrip filter (seperti yang dijelaskan dalam artikel yang dirujuk dalam jawaban docgnome ), atau rebase interaktif . Tetapi salah satu dari mereka akan mengubah revisi dari komit pertama yang diubah dan seterusnya; ini berarti masalah bagi siapa saja yang mendasarkan perubahannya pada pra-penulisan cabang Anda.PEMULIHAN
Jika pengembang lain tidak mendasarkan pekerjaan mereka pada versi pra-menulis ulang, solusi paling sederhana adalah mengkloning ulang (clone lagi).
Atau mereka dapat mencoba
git rebase --pull
, yang akan mempercepat jika tidak ada perubahan dalam repositori mereka, atau rebase cabang mereka di atas komit yang ditulis ulang (kami ingin menghindari penggabungan, karena itu akan membuat pra-penulisan ulang komit selamanya). Semua ini dengan asumsi bahwa mereka tidak memiliki pekerjaan; gunakangit stash
untuk menyembunyikan perubahan jika tidak.Jika pengembang lain menggunakan cabang fitur, dan / atau
git pull --rebase
tidak bekerja misalnya karena hulu tidak diatur, mereka harus rebase pekerjaan mereka di atas komit pasca-rewrite. Sebagai contoh tepat setelah mengambil perubahan baru (git fetch
), untukmaster
cabang berdasarkan / bercabang dariorigin/master
, orang perlu menjalankanIni
origin/master@{1}
adalah kondisi pra-penulisan ulang (sebelum mengambil), lihat gitrevision .Solusi alternatif adalah menggunakan referensi / ganti / mekanisme, tersedia di Git sejak versi 1.6.5. Dalam solusi ini Anda memberikan penggantian untuk komit yang memiliki email yang salah; lalu siapa pun yang mengambil ref 'ganti' (sesuatu seperti
fetch = +refs/replace/*:refs/replace/*
refspec di tempat yang tepat di mereka.git/config
) akan mendapatkan pengganti transparan, dan mereka yang tidak mengambil orang-orang ref akan melihat komit tua.Prosedurnya kira-kira seperti ini:
Temukan semua komit dengan email yang salah, misalnya menggunakan
Untuk setiap komit yang salah, buat komit pengganti, dan tambahkan ke objek database
Sekarang setelah Anda mengkoreksi komit dalam database objek, Anda harus memberi tahu git untuk secara otomatis dan transparan mengganti komit yang salah dengan mengkoreksi komit menggunakan
git replace
perintah:Akhirnya, daftarkan semua penggantian untuk memeriksa apakah prosedur ini berhasil
dan periksa apakah penggantian dilakukan
Anda tentu saja dapat mengotomatiskan prosedur ini ... well, semua kecuali menggunakan
git replace
yang tidak memiliki mode batch (belum), jadi Anda harus menggunakan shell loop untuk itu, atau mengganti "dengan tangan".TIDAK DIUJI! YMMV.
Perhatikan bahwa Anda mungkin menemukan beberapa sudut kasar saat menggunakan
refs/replace/
mekanisme: itu baru, dan belum diuji dengan sangat baik .sumber
Jika komit yang ingin Anda perbaiki adalah yang terbaru, dan hanya beberapa, Anda dapat menggunakan kombinasi dari
git reset
dangit stash
untuk mengembalikan komit mereka lagi setelah mengkonfigurasi nama dan email yang tepat.Urutannya akan seperti ini (untuk 2 komit yang salah, tidak ada perubahan yang tertunda):
sumber
Jika Anda menggunakan Eclipse dengan EGit, maka ada solusi yang cukup mudah.
Asumsi: Anda memiliki komit di cabang lokal 'local_master_user_x' yang tidak dapat didorong ke 'master' cabang jauh karena pengguna yang tidak valid.
sumber
Menggunakan rebase interaktif, Anda dapat menempatkan perintah amend setelah setiap komit yang ingin Anda ubah. Contohnya:
sumber
;-)
.Perhatikan bahwa git menyimpan dua alamat email yang berbeda, satu untuk committer (orang yang melakukan perubahan) dan satu lagi untuk penulis (orang yang menulis perubahan).
Informasi committer tidak ditampilkan di sebagian besar tempat, tetapi Anda dapat melihatnya dengan
git log -1 --format=%cn,%ce
(atau menggunakanshow
daripadalog
menentukan komit tertentu).Sementara mengubah pembuat komit terakhir Anda sesederhana
git commit --amend --author "Author Name <[email protected]>"
, tidak ada satu kalimat atau argumen untuk melakukan hal yang sama terhadap informasi committer.Solusinya adalah (untuk sementara, atau tidak) mengubah informasi pengguna Anda, kemudian mengubah komit, yang akan memperbarui pengalih ke informasi Anda saat ini:
sumber
path\to\repo\.git
. Saya belum yakin apa yang perlu Anda lakukan untuk menghapusnya sepenuhnya. Amend sayangnya (?) Tampaknya tidak menghapus.Kami telah mengalami masalah hari ini di mana karakter UTF8 dalam nama penulis menyebabkan masalah pada server build, jadi kami harus menulis ulang riwayat untuk memperbaikinya. Langkah-langkah yang diambil adalah:
Langkah 1: Ubah nama pengguna Anda di git untuk semua komitmen di masa mendatang, sesuai instruksi di sini: https://help.github.com/articles/setting-your-username-in-git/
Langkah 2: Jalankan skrip bash berikut:
Gambaran singkat: Periksa repositori Anda ke file temp, checkout semua cabang jarak jauh, jalankan skrip yang akan menulis ulang sejarah, lakukan dorongan paksa negara baru, dan beri tahu semua kolega Anda untuk melakukan rebase pull untuk mendapatkan perubahan.
Kami mengalami masalah dengan menjalankan ini pada OS X karena entah bagaimana mengacaukan akhir baris dalam pesan komit, jadi kami harus menjalankannya kembali pada mesin Linux setelahnya.
sumber
Masalah Anda sangat umum. Lihat " Menggunakan Mailmap untuk Memperbaiki Daftar Penulis di Git "
Demi kesederhanaan, saya telah membuat skrip untuk memudahkan proses: git-changemail
Setelah meletakkan skrip itu di jalur Anda, Anda dapat mengeluarkan perintah seperti:
Ubah kecocokan penulis pada cabang saat ini
Ubah pencocokan penulis dan penglaju di <branch> dan <branch2>. Lulus
-f
ke filter-branch untuk memungkinkan penulisan ulang cadanganTampilkan pengguna yang ada di repo
Ngomong-ngomong, setelah melakukan perubahan, bersihkan cadangan dari cabang-filter dengan: git-backup-clean
sumber
Coba ini. Ini akan melakukan hal yang sama seperti yang disebutkan di atas, tetapi secara interaktif.
Referensi: https://github.com/majdarbash/git-author-change-script
sumber
Saya ingin menambahkan Contoh saya juga. Saya ingin membuat bash_function dengan parameter yang diberikan.
ini bekerja di mint-linux-17.3
sumber
Jika Anda adalah satu-satunya pengguna repo ini atau Anda tidak peduli kemungkinan melanggar repo untuk pengguna lain, maka ya. Jika Anda telah mendorong komitmen ini dan ada di mana tempat lain dapat mengaksesnya, maka tidak, kecuali Anda tidak peduli tentang melanggar repo orang lain. Masalahnya adalah dengan mengubah komit ini, Anda akan menghasilkan SHA baru yang akan menyebabkan mereka diperlakukan sebagai komit yang berbeda. Ketika orang lain mencoba menarik komitmen yang diubah ini, sejarahnya berbeda dan kaboom.
Halaman ini http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html menjelaskan cara melakukannya. (Saya belum mencoba ini, YMMV)
sumber
refs/replace/
mekanisme.