Bagaimana mengubah beberapa komitmen di Git untuk mengubah penulis

180

Saya telah membuat serangkaian commit di Git dan saya menyadari sekarang bahwa saya lupa mengatur nama pengguna dan properti email pengguna dengan benar (mesin baru). Saya belum mendorong komit ini ke repositori saya, jadi bagaimana saya bisa memperbaiki komit ini sebelum melakukannya (hanya 3 komit terbaru di cabang master)?

Saya telah melihat git resetdan git commit -C <id> --reset-author, tetapi saya tidak berpikir saya berada di jalur yang benar.

pauldoo
sumber
1
Alasan lain Anda mungkin ingin mengubah properti email adalah kesalahan github ini: remote: error: GH007: Your push would publish a private email address.... `! master [ditolak jauh] -> master (push ditolak karena batasan privasi email) `.
craq

Jawaban:

232

Rebase / ubah tampaknya tidak efisien, ketika Anda memiliki kekuatan cabang-filter di ujung jari Anda:

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(berpisah lintas garis untuk kejelasan, tetapi tidak perlu)

Pastikan untuk memeriksa hasilnya ketika Anda selesai, untuk memastikan bahwa Anda tidak mengubah apa pun yang Anda tidak bermaksud!

Cascabel
sumber
keberatan menjelaskan ini sedikit lebih? tidak yakin apa itu cabang filter
max pleaner
1
@maxpleaner git filter-branch --helpcukup mudah :)
alediaferia
3
lihat juga help.github.com/articles/changing-author-info , yang juga menambahkan --tag-name-filter catke filter-branchdalam rangka untuk tag bermigrasi ke sejarah baru. Ini juga menggunakan --branches --tagsalih-alih --all, yang hanya menulis ulang riwayat cabang dan tag dan meninggalkan lainnya refssendiri (meskipun itu mungkin tidak membuat banyak perbedaan kecuali misalnya Anda menggunakan git-notes)
Tobias Kienzler
12
untuk melakukan ini hanya pada dua komitmen terakhir, saya diganti -- --alldenganHEAD~1..HEAD
nmz787
1
@ nmz787 Berapa banyak log yang ditampilkan jika Anda melakukannya git log HEAD~2..HEAD?
Jona
148

Pendekatan rebase interaktif cukup bagus ketika digunakan bersama dengan exec. Anda dapat menjalankan perintah shell apa pun terhadap komit tertentu atau semua komit dalam rebase.

Pertama atur pengaturan git author Anda

git config --global user.name "John Doe"
git config --global user.email [email protected]

Kemudian untuk mengatur ulang penulis untuk semua komit setelah SHA yang diberikan

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"

Ini akan memunculkan editor Anda untuk mengonfirmasi perubahan. Yang perlu Anda lakukan di sini adalah menyimpan dan keluar dan itu akan melalui setiap komit dan menjalankan perintah yang ditentukan dalam flag -x.

Per komentar Dave @ di bawah ini, Anda juga dapat mengubah penulis sambil mempertahankan stempel waktu asli dengan:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <[email protected]>' -CHEAD"
Alex
sumber
3
Terima kasih telah memperkenalkan saya pada opsi -x. Cukup mengagumkan! untuk opsi -i saya menggunakan HEAD ~ 4 untuk memperbaiki alamat email saya pada 4 commit terakhir saya. bekerja seperti pesona.
Brad Hein
2
Ini jauh lebih sederhana daripada filter-branchjika Anda hanya ingin memperbaiki komit terakhir Anda :). Namun perlu dicatat, bahwa ini mengubah cap waktu komit.
luator
24
Untuk mengubah penulis tetapi mempertahankan stempel waktu asli, gunakangit rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <[email protected]>' -CHEAD"
Dave
2
@Connor git logjuga menunjukkan kepengarangan lama untuk saya, tetapi status git dengan benar mengidentifikasi komitmen baru dan setelah dipaksa, mereka seperti yang saya maksudkan.
Dan M.
6
Untuk rebase semua komit termasuk penggunaan root: git rebase -i --root …alih-alih melewati SHA.
gfullam
80

Untuk mengubah penulis hanya untuk komit terakhir:

git commit --amend --author 'Author Name <[email protected]>' --no-edit

Misalkan Anda hanya ingin mengubah penulis untuk komit N terakhir:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

CATATAN

  • yang --no-editmerek bendera yakin git commit --amendtidak meminta konfirmasi tambahan
  • Ketika Anda menggunakan git rebase -i, Anda dapat secara manual memilih komit tempat untuk mengubah penulis,

file yang Anda edit akan terlihat seperti ini:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
Chris Maes
sumber
1
untuk semua komitmen dari root. git rebase -i - root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE' --no-edit"
Ashish Negi
1
Saya sarankan untuk menambahkan opsi --rebase-merges(pendek -r), untuk menjaga topologi cabang Anda tetap utuh jika mengandung beberapa penggabungan.
donquixote
4

Ini metode didokumentasikan oleh github untuk tujuan ini. Langkah-langkahnya adalah:

  1. Buka terminal dan buat tiruan kosong dari repo Anda
git clone --bare https://github.com/user/repo.git
cd repo
  1. Mengedit script berikut (menggantikan OLD_EMAIL, CORRECT_EMAIL, dan CORRECT_NAME)
#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
  1. Salin / rekatkan skrip ke terminal Anda dan tekan enter untuk menjalankannya.
  2. Dorong perubahan Anda dengan git push --force --tags origin 'refs/heads/*'dan Anda selesai!
stevec
sumber
Saya mengikuti instruksi yang sama pada GitHub yang Anda referensikan, dan GitHub terlihat sekarang. Namun, saya seorang pemula Git dan tidak yakin cara menyinkronkan repo lokal saya setelah itu. Ketika saya menarik saya mendapatkan kesalahan "menolak untuk menggabungkan sejarah yang tidak terkait" yang sama yang disebutkan dalam jawaban lain. Saya pikir saya perlu mengulangi terhadap sejarah komit baru, tapi saya sangat menghargai langkah-langkah yang lebih spesifik.
enigment
@ enigment jika Anda senang dengan repo yang ada di github, Anda dapat menghapus (atau mungkin pindah ke lokasi lain) folder yang Anda miliki secara lokal dan cukup mengkloning dari github
stevec
Terima kasih, saya tahu, tapi itu tidak seperti cara GitHub / Git yang idiomatis.
enigment
0

Jika Anda merasa tidak aman untuk merendahkan dan mengubah, Anda bisa melakukannya dengan cara ini. Pada saat yang sama Anda juga akan menyetel konfigurasi global yang mungkin ingin Anda lakukan.

git reset HEAD~ (batalkan komit terakhir)

git config --global user.name "Your Name"

git config --global user.email [email protected]

git commit -m "message"

Edison
sumber