Bisakah saya mengubah nama dan nama keluarga saya di semua komit sebelumnya?

122

Saya ingin mengubah nama, nama keluarga dan email saya di semua komitmen saya, apakah itu mungkin?

Joshua
sumber
2
Apakah ini reprositori hanya untuk Anda, untuk beberapa orang atau untuk proyek besar?
thejh
3
kemungkinan duplikat Bagaimana cara mengubah pembuat komit di git?
Josh Lee

Jawaban:

212

Gunakan git-filter-branch.

git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Josh Lee" ];
  then export GIT_AUTHOR_NAME="Hobo Bob"; export [email protected];
  fi; git commit-tree "$@"'

Ini hanya memengaruhi penulis, bukan pelaku (yang untuk sebagian besar komitmen akan sama dengan penulis). Jika Anda ingin menulis ulang juga, setel variabel GIT_COMMITTER_NAMEdan GIT_COMMITTER_EMAIL.

The peringatan standar tentang menulis ulang sejarah berlaku; lakukan hanya untuk sejarah yang belum dibagikan.

Pembaruan Juni 2018

Manual ini sekarang menyertakan solusi, menggunakan --env-filter, dalam contohnya: https://git-scm.com/docs/git-filter-branch#_examples :

git filter-branch --env-filter '
    if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
    then
        [email protected]
    fi
    if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
    then
        [email protected]
    fi
' -- --all
Josh Lee
sumber
4
Jika Anda menggunakan msysgit, Anda masih memiliki akses ke bash. Kalau tidak, saya tidak tahu.
Josh Lee
@Joshua jika Anda menggunakan sesuatu di mana Anda tidak memiliki bash, Anda mungkin dapat menggunakan skrip batch windows, meskipun saya belum mencobanya.
MatrixFrog
dan bagaimana dengan tag? solusi ini tidak akan mengubah pembuat tag
piotrek
@Joshua memeriksa git repo di kotak linux dan melakukan perbaikan di sana
Will Sheppard
Apakah ada opsi yang menghasilkan cabang baru dan membiarkan komit sumber tetap utuh?
Eugen Konkov
56

Untuk menulis ulang penulis dan komiter di semua komit yang dipilih:

git filter-branch --commit-filter \
'if [ "$GIT_AUTHOR_NAME" = "OldAuthor Name" ]; then \
export GIT_AUTHOR_NAME="Author Name";\
export [email protected];\
export GIT_COMMITTER_NAME="Commmiter Name";\
export [email protected];\
fi;\
git commit-tree "$@"'
pengguna11153
sumber
1
Tetapi bagaimana cara menerapkan perubahan ke server jauh?
vikyd
5
@Viky Cobagit push --all origin --force
pengguna11153
2
Ini berhasil untuk saya! Saya menggunakan GitLab, saya harus membuka proteksi cabang sebelum perintah push.
vikyd
37

Jika tidak ada penulis lain, Anda dapat melakukan:

git filter-branch --commit-filter 'export GIT_AUTHOR_NAME="authorname"; \
export [email protected]; git commit-tree "$@"'
denis.peplin
sumber
1
Ini tidak menulis ulang info "Committer:".
pengguna11153
1
Ini tidak dimaksudkan untuk menulis ulang info pelaku. Jika Anda ingin melakukannya, ekspor GIT_COMMITTER_NAME dan GIT_COMMITTER_EMAIL juga (lihat jawaban yang diterima).
chronospoon
12

Simpan script di bawah sebagai contoh ~/.bin/git-replace-authordan jalankan dengan menggunakan, contoh:

git replace-author "John Ssmith" "John Smith" "[email protected]"

Tanpa argumen, itu memperbarui semua komit dengan nama Anda untuk menggunakan alamat email Anda saat ini sesuai dengan konfigurasi Git.

DEFAULT_NAME="$(git config user.name)"
DEFAULT_EMAIL="$(git config user.email)"
export OLD_NAME="${1:-$DEFAULT_NAME}"
export NEW_NAME="${2:-$DEFAULT_NAME}"
export NEW_EMAIL="${3:-$DEFAULT_EMAIL}"

echo "Old:" $OLD_NAME "<*>"
echo "New:" "$NEW_NAME <$NEW_EMAIL>"
echo "To undo, use: git reset $(git rev-parse HEAD)"

git filter-branch --env-filter \
'if [ "$GIT_AUTHOR_NAME" = "${OLD_NAME}" ]; then
    export GIT_AUTHOR_NAME="${NEW_NAME}"
    export GIT_AUTHOR_EMAIL="${NEW_EMAIL}"
    export GIT_COMMITTER_NAME="${NEW_NAME}"
    export GIT_COMMITTER_EMAIL="${NEW_EMAIL}"
fi'

Raw (untuk mengunduh)

Zaz
sumber
Sebagai catatan singkat: ~/.bin/perlu berada di dalam pengguna $PATHdan kebutuhan file yang akan dieksekusi, jadi lari: chmod +x ~/.bin/git-replace-author.
Michael Gecht
Dan apa hubungannya dengan argumen?
Eugen Konkov
2

Hanya jika Anda belum memaksakan komitmen Anda pada dunia. Bijak lainnya, orang lain memiliki nama lama Anda di repo mereka yang tidak mungkin Anda dapat mengubah semua orang.

EnabrenTane
sumber
Benar, tetapi dalam beberapa kasus Anda tidak punya pilihan. Dalam kasus saya, saya memiliki alamat email yang salah dikonfigurasi di konfigurasi git saya (seperti yang saya lihat dengan "git config --global -l"). Akibatnya, saya tidak memiliki aktivitas commit yang muncul di repo Github saya sendiri (karena alamat email tidak cocok dengan email yang dikonfigurasi di Github)! Untuk mengatasi ini, saya memperbaiki komit lokal saya menggunakan resep dari stackoverflow.com/a/23564785/2474068 (bekerja dengan sempurna) dan kemudian saya mendorong perubahan komit ke Github menggunakan "git push -u -f origin master" (dengan gaya tandai "-f"). Itu bertentangan dengan praktik yang diterima tetapi saya tidak punya pilihan!
leo
1
Ya, maksud saya adalah bahwa setiap garpu dari repo itu tidak akan mengalami perubahan itu kecuali mereka menerima dorongan paksa Anda. Ini akan menantang untuk mendapatkan setiap garpu untuk memperbarui :)
EnabrenTane
1

Dengan Git 2.24 (Q4 2019), git filter-branch(dan BFG) tidak digunakan lagi .

Persamaannya adalah, using newren/git-filter-repo, dan contoh bagiannya :

cd repo
git filter-repo --mailmap my-mailmap

dengan my-mailmap:

Correct Name <[email protected]> <[email protected]>

Itu akan menggantikan nama penulis dan email dari setiap komit yang dilakukan oleh siapa pun dengan <[email protected]>

Lihat git shortlogbagian penulis pemetaan untuk sintaks yang tepat

VonC
sumber