Bagaimana cara mengubah nama pengarang dan pengangkut dan email dari beberapa commit di Git?

Saya menulis skrip komputer sekolah sederhana dan membuat perubahan pada Git (dalam repo yang ada di flashdisk saya yang dikloning dari komputer saya di rumah). Setelah beberapa komitmen, saya menyadari bahwa saya melakukan hal-hal sebagai pengguna root.

Apakah ada cara untuk mengubah pembuat komitmen ini dengan nama saya?

2100
15 апр. ditanya oleh Flávio Amieiro 15 Apr 2009-04-15 06:09 '09 pada 6:09 2009-04-15 06:09
@ 32 jawaban
  • 1
  • 2

Mengubah penulis (atau penglaju) akan perlu merekam u>cabang-filter git . Halaman manual berisi beberapa contoh untuk memulai. Perhatikan juga bahwa Anda dapat menggunakan variabel lingkungan untuk mengubah nama penulis, pengalih, tanggal, dll. - lihat bagian "Variabel Lingkungan" dari git man .

Secara khusus, Anda dapat memperbaiki semua nama penulis dan email yang salah untuk semua cabang dan tag menggunakan perintah ini (sumber: bantuan GitHub ):

887
15 апр. Balas diberikan oleh Pat Notz pada 15 Apr 2009-04-15 06:16 '09 pada 6:16 AM 2009-04-15 06:16

Menggunakan rebases interaktif

Anda bisa melakukannya

 git rebase -i -p <some HEAD before all of your bad commits> 

Kemudian tandai semua komit buruk Anda sebagai "pengeditan" di file rebase. Jika Anda juga ingin mengubah komit pertama Anda, Anda perlu menambahkannya secara manual ke baris pertama dalam file rebase (ikuti format dari baris lain). Kemudian, ketika git meminta Anda untuk mengubah setiap komit, buat

 git commit --amend --author "New Author Name <email@address.com>" --no-edit  \ git rebase --continue 

Fiksasi tunggal

Seperti yang dicatat oleh beberapa komentator, jika Anda hanya ingin mengubah komit terakhir, perintah rebase tidak diperlukan. Lakukan saja

  git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author 

Catatan tentang komitmen merger

Ada sedikit cacat dalam respons awal saya. Jika ada penggabungan antara HEAD saat ini dan <some HEAD before all your bad commits> , maka git rebase akan memuluskan mereka (dan, omong-omong, jika Anda menggunakan permintaan GitHub dalam riwayat Anda). Ini seringkali dapat mengarah pada cerita yang sangat berbeda (karena perubahan duplikat dapat "diinstal u>git rebase meminta Anda untuk menyelesaikan konflik gabungan yang kompleks (yang mungkin sudah diselesaikan dalam gabungan). ). Solusinya adalah menggunakan flag -p untuk git rebase , yang akan mempertahankan struktur penggabungan cerita Anda. git rebase memperingatkan bahwa menggunakan -p dan -i dapat menyebabkan masalah, tetapi bagian BUGS mengatakan: "Mengedit komit dan menulis u>

Saya menambahkan -p pada perintah di atas. Untuk kasus ketika Anda baru saja mengubah pesan terakhir, ini bukan masalah.

1465
24 авг. balasan diberikan asmeurer 24 agustus . 2009-08-24 06:08 '09 pada pukul 6:08 pagi 2009-08-24 06:08

Anda juga dapat melakukan:

 git filter-branch --commit-filter " if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ]; then GIT_COMMITTER_NAME="<New Name>"; GIT_AUTHOR_NAME="<New Name>"; GIT_COMMITTER_EMAIL="<New Email>"; GIT_AUTHOR_EMAIL="<New Email>"; git commit-tree "$@"; else git commit-tree "$@"; fi" HEAD 
573
15 мая '09 в 22:15 2009-05-15 22:15 jawabannya diberikan oleh Rognon 15 Mei '09 pada 10:15 2009-05-15 22:15

Satu sisipan, tapi hati-hati jika Anda memiliki repositori multi-pengguna - ini akan mengubah semua fiksasi untuk keberadaan pengarang dan pengalih yang sama (baru).

 git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD 

Dari baris ke baris (yang dimungkinkan dalam bash):

501
15 апр. Balas diberikan oleh Brian Gianforcaro pada 15 April 2009-04-15 06:22 '09 pada 6:22 pagi 2009-04-15 06:22

Ini terjadi ketika Anda belum menginisialisasi $ HOME / .gitconfig. Anda dapat memperbaikinya sebagai:

 git config --global user.name "you name" git config --global user.email you@domain.com git commit --amend --reset-author 

dengan git versi 1.7.5.4

209
16 февр. jawabannya diberikan lrkwz 16 Feb. 2012-02-16 12:46 '12 pada 12:46 2012-02-16 12:46

Untuk satu perbaikan:

181
27 апр. jawabannya diberikan blueyed 27 April. 2010-04-27 01:50 '10 pada 1:50 2010-04-27 01:50

Jika hanya komit terkecil yang memiliki penulis buruk, Anda dapat melakukan semuanya di dalam git rebase -i menggunakan perintah exec dan memperbaiki --amend sebagai berikut:

 git rebase -i HEAD~6 # as required 

yang memberi Anda daftar komitmen yang dapat diedit:

 pick abcd Someone else commit pick defg my bad commit 1 pick 1234 my bad commit 2 

Kemudian tambahkan baris exec ... --author="..." setelah semua baris dengan penulis buruk:

 pick abcd Someone else commit pick defg my bad commit 1 exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD pick 1234 my bad commit 2 exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD 

simpan dan keluar dari editor (untuk menjalankan).

Keputusan ini mungkin lebih lama dari yang lain, tetapi sangat bisa dikontrol - saya tahu persis apa yang dilakukannya.

Terima kasih kepada @asmeurer untuk inspirasi.

159
08 дек. jawabannya diberikan oleh Alex Brown 08 Des. 2011-12-08 20:05 '11 pada 20:05 2011-12-08 20:05

Github memiliki solusi yang bagus , yaitu skrip shell berikut:

108
07 окт. Balasan diberikan oleh Olivier Verdier 07 Okt 2010-10-07 12:54 '10 pada 12:54 2010-10-07 12:54

Seperti disebutkan di atas, penulisan u>

Tetapi jika Anda benar-benar ingin melakukan ini, dan Anda berada di lingkungan bash (tidak ada masalah di Linux, di Windows Anda dapat menggunakan git bash, yang datang dengan instalasi git), gunakan cabang git filter :

 git filter-branch --env-filter ' if [ $GIT_AUTHOR_EMAIL = bad@email ]; then GIT_AUTHOR_EMAIL=correct@email; fi; export GIT_AUTHOR_EMAIL' HEAD~20..HEAD 
80
04 авг. jawabannya diberikan oleh svick 04 Agustus. 2010-08-04 03:52 '10 pada 3:52 2010-08-04 03:52

Saat mengambil komit yang tidak siap dari penulis lain, ada cara mudah untuk menangani ini.

git commit --amend --reset-author

46
24 марта '16 в 1:23 2016-03-24 01:23 jawabannya diberikan oleh Ryanmt pada 24 Maret '16 pada 1:23 2016-03-24 01:23

Ini adalah versi @Brian versi yang lebih bijaksana:

Untuk mengubah pembuat dan pengalih, Anda dapat melakukan ini (menggunakan baris dalam string yang dimungkinkan dalam bash):

 git filter-branch --force --env-filter ' if [ "$GIT_COMMITTER_NAME" = "<Old name>" ]; then GIT_COMMITTER_NAME="<New name>"; GIT_COMMITTER_EMAIL="<New email>"; GIT_AUTHOR_NAME="<New name>"; GIT_AUTHOR_EMAIL="<New email>"; fi' -- --all 

Penjelasan sedikit dari opsi -- --all mungkin diperlukan: ini bekerja dengan filter pada semua revisi pada semua tautan (termasuk semua cabang). Ini berarti, misalnya, bahwa tag juga ditulis u>

"Kesalahan" yang umum adalah menggunakan HEAD sebagai gantinya, yang berarti memfilter semua revisi untuk cabang saat ini saja. Dan kemudian di utas yang ditulis u>

38
09 дек. jawabannya diberikan stigkj 09 desember . 2011-12-09 13:23 '11 pada 1:23 PM 2011-12-09 13:23

Anda dapat menggunakannya sebagai alias, sehingga Anda dapat melakukannya:

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

atau selama 10 komit terakhir:

 git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD 

Tambahkan ke ~ / .gitconfig:

 [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

Semoga ini bermanfaat.

38
02 авг. jawabannya diberikan brauliobo 02 Agustus. 2012-08-02 02:09 '12 pada 2:09 2012-08-02 02:09
  • jalankan git rebase -i <sha1 or ref of starting point>
  • tandai semua komit yang ingin Anda edit dengan edit (atau e )
  • jalankan dua perintah berikut sampai Anda menangani semua komitmen:

    git commit --amend --reuse-message=HEAD --author="New Author <new@author.email>" ; git rebase --continue

Ini akan menyimpan semua informasi komit lainnya (termasuk tanggal). Opsi --reuse-message=HEAD menonaktifkan peluncuran editor pesan.

23
04 окт. Balasan diberikan sporsh 04 oktober. 2012-10-04 05:22 '12 pada 5:22 pagi 2012-10-04 05:22

Saya menggunakan yang berikut ini untuk menulis u>

halaman MAN dari cabang filter , hapus semua referensi asli yang dibuat di bawah cadangan filter-branch (ini merusak, pencadangan pertama): 

21
16 февр. Jawabannya diberikan Ton van den Heuvel 16 Feb. 2011-02-16 18:27 '11 pada 18:27 2011-02-16 18:27

Saya mengadaptasi solusi ini, yang berfungsi dengan menelan file author-conv-file sederhana (formatnya sama dengan untuk git-cvsimport ). Ini bekerja dengan memodifikasi semua pengguna, sebagaimana didefinisikan dalam file author-conv-file untuk semua cabang.

Kami menggunakan ini bersamaan dengan cvs2git untuk mentransfer repositori kami dari cvs ke git.

itu adalah Contoh author-conv-file

 john=John Doe <john.doe@hotmail.com> jill=Jill Doe <jill.doe@hotmail.com> 

skrip:

20
05 февр. jawaban yang diberikan oleh Leif Gruenwoldt 05 Feb. 2011-02-05 01:46 '11 pada 1:46 2011-02-05 01:46

Saya menemukan versi yang disajikan dari cara agresif, terutama jika Anda membuat koreksi dari pengembang lain, ini pada dasarnya mencuri kode mereka.

Versi berikut ini berfungsi di semua cabang dan mengubah penulis dan pengangkat secara terpisah untuk mencegah hal ini.

Klaim ke leif81 untuk semua opsi.

18
23 апр. jawab diberikan drahnr 23 Apr 2012-04-23 11:46 '12 pada 11:46 2012-04-23 11:46
  • Ubah author name email Amend author name email ke Amend , lalu ganti old-commit with new-one :

     $ git checkout <commit-hash> # checkout to the commit need to modify $ git commit --amend --author "name <author@email.com>" # change the author name and email $ git replace <old-commit-hash> <new-commit-hash> # replace the old commit by new one $ git filter-branch -- --all # rewrite all futures commits based on the replacement $ git replace -d <old-commit-hash> # remove the replacement for cleanliness $ git push -f origin HEAD # force push 
  • Cara lain Rebasing :

     $ git rebase -i <good-commit-hash> # back to last good commit # Editor would open, replace 'pick' with 'edit' before the commit want to change author $ git commit --amend --author="author name <author@email.com>" # change the author name  email # Save changes and exit the editor $ git rebase --continue # finish the rebase 
17
14 дек. Sajib Khan menjawab 14 Des. 2016-12-14 18:01 16 di 18:01 2016-12-14 18:01

Saya harus menunjukkan bahwa jika satu-satunya masalah adalah bahwa penulis / email berbeda dari yang biasa Anda, ini bukan masalah. Perbaikan yang benar adalah dengan membuat file dengan nama .mailmap di direktori dasar dengan baris seperti

 Name you want <email you want> Name you don't want <email you don't want> 

Mulai sekarang, perintah seperti git shortlog akan menganggap kedua nama ini sama (kecuali Anda memberi tahu mereka secara spesifik). Untuk detailnya, lihat http://schacon.github.com/git/git-shortlog.html .

Ini memiliki keunggulan dari semua solusi lain di sini bahwa Anda tidak perlu menulis u>

Tentu saja, jika Anda melakukan sesuatu seperti diri Anda sendiri, dan itu harusnya orang lain, dan Anda tidak keberatan menulis u>

15
29 февр. Jawabannya diberikan penanggung pada 29 Februari. 2012-02-29 02:57 '12 pada 2:57 2012-02-29 02:57

Jika Anda adalah satu-satunya pengguna repositori ini, Anda dapat menulis u> menggunakan git filter-branch (seperti yang ditulis svick ), atau git fast-export git fast-import / git fast-import ditambah filter skrip (seperti dijelaskan dalam artikel yang dirujuk oleh jawaban docgnome ) atau rebase interaktif. Tetapi salah satu dari mereka akan mengubah perubahan dari komitmen pertama yang diubah; ini berarti kesulitan bagi siapa saja yang mendasarkan perubahannya pada cabangnya sebelum menulis u>

PEMULIHAN

Jika pengembang lain tidak mendasarkan pekerjaan mereka pada versi awal, solusi termudah adalah mengkloning u>

Atau, mereka dapat mencoba git rebase --pull , yang akan dengan cepat diteruskan jika tidak ada perubahan dalam repositori mereka, atau menghubungkan kembali cabang mereka di atas komitmen yang ditulis u>git stash untuk membuang perubahan sebaliknya.

Jika pengembang lain menggunakan cabang fungsi, dan / atau git pull --rebase tidak berfungsi, misalnya. karena upstream tidak dikonfigurasi, mereka harus memulai kembali pekerjaan mereka di atas catatan setelah menulis u>git fetch ), untuk cabang master berdasarkan / bercabang dari origin/master Anda harus menjalankan

 $ git rebase --onto origin/master origin/master@{1} master 

Di sini, origin/master@{1} adalah status prarekam (sebelum pengambilan), lihat pembagian git .


Solusi alternatif adalah menggunakan referensi / ganti / mekanisme, tersedia di Git sejak versi 1.6.5. Dalam solusi ini, Anda memberikan pengganti untuk komit dengan alamat email yang salah; maka seseorang yang mengambil "ref" (sesuatu seperti fetch = +refs/replace/*:refs/replace/* refspec di tempat yang sesuai di .git/config ) akan menerima penggantian secara transparan, dan mereka yang tidak mengambil tautan ini akan melihat komitmen lama.

Prosedurnya terlihat seperti ini:

  • Temukan semua komitmen dengan alamat email yang salah, misalnya menggunakan

     $ git log --author=user@wrong.email --all 
  • Untuk setiap komit yang salah, buat komit pengganti dan tambahkan ke database objek.

     $ git cat-file -p <ID of wrong commit> | sed -e 's/user@wrong\.email/user@example.com/g' > tmp.txt $ git hash-object -t commit -w tmp.txt <ID of corrected commit> 
  • Sekarang setelah Anda mengkoreksi komit di database objek, Anda perlu memberi tahu Git untuk secara otomatis dan transparan mengganti komit yang salah, dikoreksi dengan git replace :

     $ git replace <ID of wrong commit> <ID of corrected commit> 
  • Terakhir, daftarkan seluruh penggantian untuk memeriksa apakah prosedur ini dilakukan.

     $ git replace -l 

    dan periksa apakah ada penggantinya

     $ git log --author=user@wrong.email --all 

Anda dapat, tentu saja, mengotomatiskan prosedur ini ... well, semuanya kecuali penggunaan git replace , yang tidak memiliki mode batch (sejauh ini), jadi Anda harus menggunakan shell loop untuk ini atau menggantinya secara manual.

TIDAK TETAP! YMMV.

Perhatikan bahwa ketika menggunakan refs/replace/ mekanisme Anda mungkin menemukan beberapa sudut kasar: itu baru dan belum diuji dengan baik .

9
04 авг. jawaban diberikan oleh Jakub Narębski 04 Agustus. 2010-08-04 12:41 '10 pada 12:41 2010-08-04 12:41

Jika perbaikan yang ingin Anda perbaiki adalah yang terakhir, dan hanya beberapa, Anda dapat menggunakan git reset dan git stash kombinasi untuk kembali memperbaikinya setelah menetapkan nama dan email yang benar.

Urutannya akan seperti ini (untuk 2 komitmen salah, tanpa menunggu perubahan):

 git config user.name <good name> git config user.email <good email> git reset HEAD^ git stash git reset HEAD^ git commit -a git stash pop git commit -a 
6
30 сент. Jawaban diberikan oleh djromero 30 Sep 2011-09-30 21:04 '11 pada 21:04 2011-09-30 21:04

Menggunakan rebase interaktif, Anda dapat menempatkan perintah perubahan setelah setiap komit yang ingin Anda ubah. Sebagai contoh:

 pick a07cb86 Project tile template with full details and styling x git commit --amend --reset-author -Chead 
5
26 февр. jawabannya diberikan j16r 26 Feb. 2013-02-26 16:19 '13 pada 16:19 2013-02-26 16:19

Perhatikan bahwa git menyimpan dua alamat email yang berbeda, satu untuk committer (orang yang membuat perubahan) dan yang lain untuk penulis (orang yang menulis perubahan).

Informasi tentang committer tidak ditampilkan di sebagian besar tempat, tetapi Anda dapat melihatnya dengan git log -1 --format=%cn,%ce (atau gunakan show sebagai ganti log untuk menunjukkan komit tertentu).

Mengubah penulis komit terakhir Anda semudah git commit --amend --author "Author Name <email@example.com>" , tidak ada satu baris atau argumen untuk melakukan hal yang sama dengan informasi anggota.

Solusinya adalah (sementara atau tidak) mengubah informasi pengguna Anda dan kemudian memperbaiki komit, yang memperbarui pengalih ke informasi Anda saat ini:

 git config user.email my_other_email@example.com git commit --amend 
5
06 дек. Balas diberikan oleh Sir Athos 06 Des 2013-12-06 00:21 '13 pada 0:21 2013-12-06 00:21

Jika Anda menggunakan Eclipse dengan EGit, maka ada solusi yang cukup sederhana.
Asumsi: Anda membuat kesalahan di cabang lokal local_master_user_x, yang tidak dapat ditransfer ke "master" dari cabang jarak jauh karena pengguna yang tidak valid.

  • Lihat "master" cabang jarak jauh
  • Pilih proyek / folder / file yang berisi perubahan local_master_user_x.
  • Klik kanan - Ganti dengan - Cabang - 'local_master_user_x'
  • Selesaikan perubahan ini lagi, kali ini sebagai pengguna yang benar dan di "master" cabang lokal
  • Dorong ke 'master' jarak jauh
5
24 авг. jawabannya diberikan oleh paphko 24 Agustus. 2011-08-24 20:54 '11 pada 20:54 2011-08-24 20:54

Hari ini kami mengalami masalah ketika karakter UTF8 dalam nama penulis menyebabkan masalah pada server build, jadi kami harus menulis u>

>https://help.github.com/articles/setting-your-username-in-git/

>

 #!/bin/sh REPO_URL=ssh://path/to/your.git REPO_DIR=rewrite.tmp # Clone the repository git clone ${REPO_URL} ${REPO_DIR} # Change to the cloned repository cd ${REPO_DIR} # Checkout all the remote branches as local tracking branches git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout # Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX git filter-branch --env-filter ' OLD_EMAIL="me@something.com" CORRECT_NAME="New Me" if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ] then export GIT_COMMITTER_NAME="$CORRECT_NAME" fi if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ] then export GIT_AUTHOR_NAME="$CORRECT_NAME" fi ' --tag-name-filter cat -- --branches --tags # Force push the rewritten branches + tags to the remote git push -f # Remove all knowledge that we did something rm -rf ${REPO_DIR} # Tell your colleagues to `git pull --rebase` on all their local remote tracking branches 

Tinjauan singkat. Lakukan pemesanan dalam file sementara, periksa semua cabang yang dihapus, jalankan skrip yang akan menulis u>

Kami mengalami masalah saat menjalankannya di OS X karena entah bagaimana mencampuradukkan ujungnya dengan pesan komit, jadi kami harus meluncurkannya kembali di mesin Linux setelah itu.

5
22 окт. Jawaban diberikan oleh Miloš Ranđelović 22 Oktober. 2014-10-22 06:32 '14 pada 6:32 2014-10-22 06:32

Masalah Anda sangat umum. Lihat " Menggunakan Mailmap untuk memperbaiki daftar penulis di Git "

Untuk mempermudah, saya membuat skrip untuk memudahkan proses: git-changemail

Setelah menempatkan skrip ini di jalan Anda, Anda dapat mengeluarkan perintah seperti:

  • Perubahan penulis di cabang saat ini

     $ git changemail -a old@email.com -n newname -m new@email.com 
  • Ubah pemetaan penulis dan committer ke <branch> dan <branch2>. Передайте -f в ветвь фильтра, чтобы разрешить переписывание резервных копий

     $ git changemail -b old@email.com -n newname -m new@email.com -- -f  >