Git, önceki işlem kullanıcı adlarını ve e-postalarını yeniden yaz


171

Github'daki bir projeye bir sürü taahhütte bulundum, ancak şu anda taahhütlerimi yapmak için kullandığım bilgisayarda doğru e-posta ve komisyon tam adını ayarlamadığımı fark ettim ve bu nedenle kullanıcıların avatarı ve e-posta adresi yok mu.

Geçmişteki tüm taahhüt e-postalarını ve kullanıcı adlarını nasıl yeniden yazabilirim?



GitHub hesabımdaki e-posta adresini değiştirdikten sonra bunu yaşadım. Git komut satırını (GitHub masaüstü değil) kullanarak yerel git repo'sundan kod değişikliklerini göndermenin yanı sıra, GitHub web arabirimini kullanarak doğrudan uzak git deposundan metin ve yönetilen dosyaları da düzenledim. Yeni e-posta adresi yalnızca önceki işlemlerden kaynaklanan taahhütlere yayıldı, birincisine değil.
Robert John

Yanıtlar:


245

Bu takma adı ekleyebilirsiniz:

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 "

Yazar adını değiştirmek için:

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

veya yalnızca son 10 işlemin e-postası:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" 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 "

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


13
Ayrıca git change-commits GIT_COMMITTER_EMAIL "old@example.com" "new@example.com"committer e-postasını değiştirmek için.
laurent

20
change-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 "
Ubuntu'da

9
git: 'change-commits' bir git komutu değildir. Bkz. 'Git --help'. Git yapılandırmanıza takma ad eklemediğiniz anlamına gelir. örneğin git config -e
Wayne

3
Bu sadece değiştirmek istediğim e-posta ile tüm taahhütlerin kopyalarını yaptı. Geçmişi yeniden yazıyor gibi görünmüyor. @Olivier Verdier'ın çözümü benim için çalıştı.
Jake Wilson

7
Farklı girişlerle üst üste iki kez yapmak aşağıdakileri sağlar:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti

98

Buraya bakın :

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

4
bu, şubenin tüm taahhütleri (tüm tarih) için yazar adını değiştirmez mi?
hasen

2
Evet, bu tüm taahhütleri yeni yazar bilgilerine dönüştürür.
ewall

9
Lütfen yanıtı kopyalayıp yapıştırma yerine soruları kopya olarak işaretleyin.
Ocak'ta givanse

2
eski bir ad veya eski bir e-posta belirtmediysem ne olur? git "boş ident <> izin verilmiyor" diyor
Griffan

Bu komutu çalıştırdım ve şimdi depom git sunucusuna gitmiyor veya sunucudan çekmiyor.
Jesus H

46

Zaten kamu depoya kaydedilmesini bazı itti varsa, do not bunu yapmak istiyor, ya da başkalarının kullanmış olabileceği master tarihinin alternatif bir bölüm olur. "Akarsuları geçme ... Kötü olurdu ..."

Bununla birlikte, yalnızca yerel deponuza yaptığınız taahhütler ise, sunucuya geçmeden önce bunu düzeltin. git filter-branchKomutu seçenekle birlikte kullanabilirsiniz --commit-filter, böylece yalnızca aşağıdaki gibi yanlış bilgilerinizle eşleşen taahhütleri düzenler:

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

5
Yeşil renkle işaretlenmiş cevap yoktu
jmary

Daha sonra, yedeği ile temizlemek isteyebilirsiniz git update-ref -d refs/original/refs/heads/master, bkz. < Stackoverflow.com/a/7654880/333403 >.
cknoll

Bilginize: Birden fazla yanlış adınız / e-postanız varsa, bunu birkaç kez çalıştırmanız gerekebilir. Bu durumda size şu hatayla inler : A previous backup already exists in refs/original/Bu durumda, yeni e-posta ile yeniden çalıştırın -fve --commit-filter'ten önce bir ekleyin . Kendi takdirinize bağlı olarak kullanın. Genellikle -fne yaptığını bilmeden yapmak tehlikeli bir şeydir.
Chuck

19

Olivier Verdier'ın cevabını uyguladıktan sonra:

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

... değiştirilen geçmişi orijinal depo kullanımına aktarmak için:

git push origin +yourbranch

Yukarıdaki komut (artıya dikkat edin), geçmişi orijinal repo üzerinde de yeniden yazmaya zorlar. Dikkatle kullanın!


Benim için çalıştı, ayrıca tarihi kökeni doğru bir şekilde yeniden yazdı.
Xeverous

10
Bu, kimin yazdığına bakılmaksızın TÜM taahhütleri yeniden yazacaktır. Dikkatle kullanın.
Bhavin Doshi

14

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

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
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

bu tamamen benim için çalıştı. Git push işleminden sonra git'in web portalında güncellemeyi gördüğünüzden emin olun. Taahhüt hala hesabımla bağlantılı değilse, taahhüdün yanında varsayılan küçük resim gösteriliyorsa ve katkı zaman çizelgesi grafiğime yansıtılmamışsa, taahhüt URL'sine gidin ve URL'nin sonuna .patch ekleyin ve adı doğrulayın ve e-posta doğrudur.


Bu teorik olarak soruyu cevaplayabilse de , cevabın temel kısımlarını buraya dahil etmek ve referans için bağlantı sağlamak tercih edilir.
jhpratt

1
Bu, tüm dalları yeniden yazan tek kişidir.
Bruno Zell

6

Kolay kopyala yapıştır sürümünü isteyenler için (e-postaları ve adları güncellemenin yanı sıra):

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 <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

5
bas: olay bulunamadı
Saiyine

Büyük olasılıkla otomatik olarak şeylerden kaçan bir terminal ile ilgili bir sorun
Andrei Savin

3

Kullanımını göz önüne alındığında git-filter-branchedilir istenmediği de aynı şeyi yapmak, git-filtre-repo (eğer ilk yüklemeniz gerekebilir pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

Havuz orijinal değilse, uzaktan kumanda --forceolmadan, yeniden yazmaya zorlamak için eklemeniz gerekir. (Bunu yapmadan önce deponuzun yedeğini oluşturmak isteyebilirsiniz.)

Ref'leri korumak istemiyorsanız (Git GUI'nin şube geçmişinde görüntülenirler) eklemeniz gerekir --replace-refs delete-no-add.

Daha gelişmiş özellikler için, bkz. "Ad ve e-postaları filtreleme" .

PS Çalındı ​​ve https://stackoverflow.com/a/59591928/714907 adresinden geliştirildi .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.