Yanlış bir e-posta adresini / adını düzeltmek için git'in geçmişini nasıl düzenlerim [name]


76

Ben budala kullanarak başladığımda ben sadece bir yaptım git initve demeye başladı addve commit. Şimdi dikkat etmeye başladım ve taahhütlerimin cowens@localmachineistediğim adres yerine göründüğünü görebiliyorum . Görünüşe göre ayar GIT_AUTHOR_EMAILve sanki GIT_COMMITTER_EMAIListediğimi yapacak gibi gözüküyor , ama yine de eski e-posta adresleri / isimleriyle söz veriyorum. Eski taahhütleri nasıl düzeltebilirim?


4
Gelecekteki okuyucularımız için: Buna gitbenzer amaçlarla kullanmayla ilgili sorular Stack Overflow'ta daha iyi sorulur .
Michael Hampton

İşte stackoverflow.com'daki en yakın soru .
naught101

Yanıtlar:


82

Geri dönebilir ve tüm taahhütlerinizi tek bir çağrı ile git filtre şubesine bağlayabilirsiniz. Bu rebase ile aynı etkiye sahiptir, ancak her bir işlemi tek tek düzeltmek yerine, tüm geçmişinizi düzeltmek için yalnızca bir komut yapmanız yeterlidir.

Tüm yanlış e-postaları bu komutla düzeltebilirsiniz:

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

Git belgelerinde daha fazla bilgi bulabilirsiniz.


11
peki, git filtre dalı - env ​​filtresi 'dışa aktarma GIT_AUTHOR_EMAIL = "foo@example.com"; GIT_AUTHOR_NAME = "Foo"' çok teşekkürler, teşekkürler. Eğer değiştirebilseydim bu kabul edilen cevap olurdu (Sunucu Hatası ile ilgili bir hata var gibi görünüyor).
Chas. Owens

7
İhracat hatlarının, eşittir işaretinin her iki tarafında da boşluk olmamalıdır. Yani şöyle görünmeliler: export GIT_AUTHOR_EMAIL = "(doğru e-posta)";
Andy Balaam

1
Şimdi, bunu Windows'ta nasıl yaparım?
Carsten Schmitz

2
@Deckard: betiği fixcommits.sh gibi bir metin dosyasına kaydedin, sonra Git Bash'i çalıştırın ve betiği çalıştırın. Scripti dosyasını reponun kök dizinine koydum, sonra Git Bash'deki o klasöre gittim, sonra betiği ./fixcommits.sh ile çalıştırdım
Avalanchis

2
Ek 1 Bu komut formatı benim için çalışmıyordu, ancak / sonra yaptıysa:if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi
Josh M.

28

Git'in filtre dalı komutu güçlüdür, ancak önemsiz olmayan herhangi bir şey için kullanmak, örneğin düzeltmek için birden fazla yazıcınız varsa, kullanışsızdır.

İşte git-shortlog kılavuz sayfasında açıklanan .mailmap özelliğini kullanan, faydalı bulduğum bir alternatif. Bu, git log'un biçimlendirme tesisi ile kullanabileceğimiz bir yazar haritalandırma mekanizması sağlar. Adlandırılmış bir komisyon sırasını değiştirmek ve değiştirmek için komutları üretmek için kullanabiliriz.

Örneğin, $ START işleminden başlayarak $ BRANCH şubesindeki yazarlığı düzeltmek istediğinizi varsayalım.

Mevcut yazar adlarını düzeltmek için eşleştiren, deponuzun üst dizininde bir .mailmap dosyası oluşturmanız gerekir. Mevcut yazar isimlerinin listesini aşağıdakilerle yapabilirsiniz:

git shortlog -se

Bunun gibi bir .mailmap dosyası ile bitirmeniz gerekir (sayın):

You <you@somewhere.org>   cowens@localmachine
You <you@somewhere.org>   root@localmachine

Şimdi $ BRANCH'ı $ BRANCH2 olarak yeniden yazmak için komutları oluşturmak için git logun biçimlendirme özelliğini kullanabilirsiniz.

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

İlk komut $ START taahhüdünden filizlenen yeni bir boş dal oluşturur. $ START ile $ BRANCH arasındaki her bir işlem için, ikinci komut kirazı, orijinal şubeyi geçerli olan $ BRANCH2 şubesinin sonuna götürür ve yazarı doğru bir şekilde ayarlamak için değiştirir.

Bu aynı zamanda genel olarak uygulanabilir - bunu ~ / .gitconfig dosyasına koyun:

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

Bu yüzden, yazarları düzeltmeniz gerektiğinde, şimdi sadece bir .mapfile oluşturmanız ve yapmanız gerekenler:

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

Orijinal dal referansı yenisine atanabilir ve yenisi silinebilir:

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2

Bu harika. Daha fazla temsilcim olsaydı sana ödül alırdım. Thanks :)
pistache 10:12

9

'Dan gelen cevabı bir araya getirme

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root

Beni doğru yolda buldum, ama şu komutu almam gerekiyor: stackoverflow.com/a/28536828/307 --author kullanımı yerine
Brett Veenstra

5

Jedberg'in cevabını takip etmek için: Söz konusu komisyonları kullanabilir rebase -ive düzenleyebilirsiniz. Eğer kullanırsanız git commit --amend --author <AUTHOR DETAILS>, o git rebase continuezaman geçip geçmişi düzeltebilirsiniz.

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.