Git, tulis ulang nama pengguna dan email komit sebelumnya

170

Saya telah melakukan banyak komit ke sebuah proyek di Github, namun saya menyadari bahwa saya belum mengatur email yang tepat dan nama lengkap komuter di komputer yang saat ini saya gunakan untuk membuat komit dan oleh karena itu para pengguna avatar dan alamat email tidak ada disana

Bagaimana saya bisa menulis ulang semua email dan nama pengguna yang dilakukan sebelumnya?

JP Silvashy
sumber
9
kemungkinan rangkap dari Bagaimana cara mengubah pembuat komit di git?
givanse
Saya mengalaminya setelah mengubah alamat email di akun GitHub saya. Selain mendorong perubahan kode dari repo git lokal menggunakan antarmuka perintah git (dan bukan desktop GitHub), saya juga mengedit teks dan mengelola file langsung dari repo git jarak jauh menggunakan antarmuka web GitHub. Alamat email baru disebarkan hanya ke komitmen yang dihasilkan dari tindakan terakhir dan bukan yang pertama.
Robert John

Jawaban:

243

Anda dapat menambahkan alias ini:

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "

Untuk mengubah nama penulis:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

atau email hanya untuk 10 komitmen terakhir:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

Alias:

change-commits="!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" \$@; }; f "

Sumber: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

brauliobo
sumber
13
Juga git change-commits GIT_COMMITTER_EMAIL "[email protected]" "[email protected]"untuk mengubah email committer.
laurent
19
diperbaiki untuk "eval: [[: not found" di ubuntu dan tambahkan konfirmasichange-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
qxo
9
git: 'change-commit' bukan perintah git. Lihat 'git --help'. Berarti Anda belum menambahkan alias ke konfigurasi git Anda. misalnya git config -e
Wayne
2
Ini hanya membuat duplikat dari semua komitmen dengan email yang ingin saya ubah. Tampaknya tidak menulis ulang riwayat. @Olivier Verdier bekerja untuk saya.
Jake Wilson
6
Melakukannya dua kali berturut-turut dengan input berbeda mengarah ke:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti
98

Lihat di sini :

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD
Olivier Verdier
sumber
4
tidakkah ini akan mengubah nama penulis untuk semua komit (seluruh riwayat) cabang?
Hasen
2
Ya, itu akan mengubah semua komitmen ke info penulis baru.
ewall
9
Tandai pertanyaan sebagai duplikat alih-alih salin menempelkan jawaban.
givanse
2
bagaimana jika saya tidak menentukan nama lama atau email lama? git mengatakan "identifikasi kosong <> tidak diizinkan"
Griffan
Saya menjalankan perintah ini dan sekarang repo saya tidak akan mendorong ke atau menarik dari server git.
Jesus H
46

Jika Anda sudah mendorong beberapa komit Anda ke repositori publik, Anda tidak ingin melakukan ini, atau itu akan membuat versi alternatif dari sejarah master yang mungkin digunakan orang lain. "Jangan menyeberangi sungai ... Itu akan buruk ..."

Yang mengatakan, jika hanya komit yang telah Anda buat ke repositori lokal Anda, maka tentu saja perbaiki ini sebelum Anda mendorong ke server. Anda dapat menggunakan git filter-branchperintah dengan --commit-filteropsi, sehingga hanya mengedit komit yang cocok dengan info yang salah, seperti ini:

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD
ewall
sumber
5
Ini berfungsi sempurna sedangkan jawaban yang ditandai dengan warna hijau tidak
jmary
Setelah itu, orang mungkin ingin menghapus cadangan dengan git update-ref -d refs/original/refs/heads/master, lihat < stackoverflow.com/a/7654880/333403 >.
cknoll
FYI: Jika Anda memiliki beberapa nama / email yang salah, Anda harus menjalankannya beberapa kali. Jika itu terjadi, ia akan mengeluh kepada Anda dengan kesalahan ini: A previous backup already exists in refs/original/Jika demikian, jalankan kembali, dengan email baru, dan tambahkan -fsebelum --commit-filter. Gunakan dengan kebijaksanaan Anda sendiri. Biasanya -fhal yang berbahaya dilakukan tanpa sepengetahuan apa yang dilakukannya.
Chuck
19

Setelah menerapkan jawaban Olivier Verdier:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

... untuk mendorong riwayat yang diubah pada penggunaan repositori asli:

git push origin +yourbranch

Perintah di atas (perhatikan plus) memaksa penulisan ulang sejarah pada repo asli juga. Gunakan dengan hati-hati!

sarusso
sumber
Bekerja untuk saya, juga menulis ulang sejarah dengan benar pada asal.
Xeverous
10
Ini akan menulis ulang SEMUA komitmen - terlepas dari siapa yang menulisnya. Gunakan dengan hati-hati.
Bhavin Doshi
14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="[email protected]"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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

ini benar-benar bekerja untuk saya. Setelah git push, pastikan untuk melihat pembaruan di portal web git. Jika komit masih belum ditautkan ke akun saya, ditampilkan gambar mini default di sebelah komit dan itu tidak tercermin pada bagan waktu kontribusi saya, buka url komit dan tambahkan .patch di akhir url, dan verifikasi nama dan email sudah benar.

Jacccck
sumber
Sementara ini secara teoritis dapat menjawab pertanyaan, akan lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini, dan menyediakan tautan untuk referensi.
jhpratt
1
Ini adalah satu-satunya yang menulis ulang semua cabang.
Bruno Zell
6

Bagi mereka yang hanya ingin versi copy paste mudah (selain dari memperbarui email dan nama):

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <[email protected]> <[email protected]> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <[email protected]> <[email protected]> -f
Nick Kuznia
sumber
5
-bash:! f: acara tidak ditemukan
Saiyine
Kemungkinan besar masalah dengan terminal yang melarikan diri secara otomatis
Andrei Savin
3

Mengingat penggunaan git-filter-branchyang tidak diinginkan , untuk melakukan hal yang sama di git-filter-repo (Anda mungkin perlu menginstal dulu dengan pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"[email protected]", b"[email protected]")'

Jika repositori asli, tanpa remote, Anda harus menambahkan --forceuntuk memaksa menulis ulang. (Anda mungkin ingin membuat cadangan dari repo Anda sebelum melakukan ini.)

Jika Anda tidak ingin menyimpan referensi (akan ditampilkan dalam riwayat cabang Git GUI), Anda harus menambahkan --replace-refs delete-no-add.

Untuk fitur lebih lanjut, lihat "Pemfilteran nama & email" .

PS Dicuri dan ditingkatkan dari https://stackoverflow.com/a/59591928/714907 .

Pugsley
sumber