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.


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!


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 johndoe@example.com

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 <new_address@example.com>' -CHEAD"

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 <new_address@example.com>' -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 <author.name@mail.com>' --no-edit

Misalkan Anda hanya ingin mengubah penulis untuk komit N terakhir:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --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 <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

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="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
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!

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 you@example.com

git commit -m "message"

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.