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?


2
Apakah ini reprositori hanya untuk Anda, untuk beberapa orang atau untuk proyek besar?
thejh



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 GIT_AUTHOR_EMAIL=hobo@example.com;
  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
        GIT_AUTHOR_EMAIL=john@example.com
    fi
    if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
    then
        GIT_COMMITTER_EMAIL=john@example.com
    fi
' -- --all

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 GIT_AUTHOR_EMAIL=authorEmail@example.com;\
export GIT_COMMITTER_NAME="Commmiter Name";\
export GIT_COMMITTER_EMAIL=commiterEmail@example.com;\
fi;\
git commit-tree "$@"'

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 GIT_AUTHOR_EMAIL=mail@example.com; git commit-tree "$@"'

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

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)


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.


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

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.