Soru Git'teki birden çok işlemin yazar ve gönderenin adı ve e-postası nasıl değiştirilir?


Okul bilgisayarında basit bir betik yazıyordum ve değişiklikleri de değiştiriyordum (pendrive'ımdaki bir repoda, bilgisayarımdan evde klonlanmıştı). Birkaç işlemden sonra kök kullanıcı olarak bir şeyler yaptığımı fark ettim.

Bu taahhütlerin yazarını ismimle değiştirmenin bir yolu var mı?


2004
2018-04-15 03:09


Menşei


Soru: git filtre-dalını kullanarak önceki etiketler, sürümler ve nesneler için SHA1'leri koruyor mu? Ya da yazar isminin gücünü değiştirir, ilişkili SHA1'leri de değiştirir mi? - AndyL
Hashes evet değiştirecek - Not Available
Tanrısal olarak, sonunda benim için kök nedenini düzelten küçük bir senaryo oluşturdum. gist.github.com/tripleee/16767aa4137706fd896c - tripleee
@impinball Sorunun yaşı pek alakalı değil. Yeni bir yinelenen soru oluşturmak, sorunun dışında. Sanırım bu özel cevabı alan bir soru oluşturabilirdim ama bütün bu kadar görünürlüğü alacağına ikna olmadım. Burada Git sorularının bir sıkıntısı yokmuş gibi değil ... Yine de yardımcı olabildiğime sevindim. - tripleee
GitHub bunun için özel komut dosyası var: help.github.com/articles/changing-author-info - Timur Bernikowich


Cevaplar:


Yazarın (veya işin) değiştirilmesi, tüm tarihin yeniden yazılmasını gerektirecektir. Bununla bir şey yapmıyorsanız ve buna değer olduğunu düşünüyorsanız, kontrol etmelisiniz. git filtre-dalı. Adam sayfası, başlamanıza yardımcı olacak birkaç örnek içerir. Ayrıca, yazarın, gönderenin, tarihlerin, vb. Adını değiştirmek için ortam değişkenlerini kullanabileceğinizi de unutmayın. - "Ortam Değişkenleri" bölümüne bakın. git adam sayfası.

Özellikle, tüm yanlış yazar isimlerini ve e-postaları düzeltebilirsiniz. tüm dallar ve etiketler için bu komutla (kaynak: GitHub yardım):

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
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

801
2018-04-15 03:16



Github bunun için genel bir betik var help.github.com/articles/changing-author-info ve harika çalışıyor! - rodowi
Komut dosyasını yürüttükten sonra "git update-ref -d refs / original / refs / heads / master" komutunu çalıştırarak yedekleme dalını kaldırabilirsiniz. - D.R.
@rodowi, tüm taahhütlerimi kopyalar. - Rafael Barros
@RafaelBarros yazar bilgisi (tarihte başka herhangi bir şey gibi) islemin sha anahtarının bir parçasıdır. Tarihe yapılan herhangi bir değişiklik, tüm taahhütler için yeni kimliklere yol açan bir yeniden yazımdır. Bu nedenle, paylaşılan bir repoda yeniden yazma veya tüm kullanıcıların farkında olduğundan emin olmayın. - johannes
Kullanarak çözüldü git push --force --tags origin HEAD:master - Matteo Contrini


Etkileşimli Rebase Kullanımı

Yapabilirsin

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

Ardından tüm kötü taahhütlerinizi rebase dosyasında "edit" olarak işaretleyin. İlk taahhüdünü de değiştirmek isterseniz, onu rebase dosyasında ilk satır olarak el ile eklemelisiniz (diğer satırların formatını takip edin). Daha sonra git, her bir işlemi değiştirmenizi istediğinde,

 git commit --amend --author "New Author Name <email@address.com>" 

Açılan editörü düzenlemek veya kapatmak

git rebase --continue

rebase devam etmek.

Düzenleyiciyi açarak buraya tıklayarak atlayabilirsiniz. --no-edit böylece komut şöyle olacak:

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

Tek taahhüt

Yorum yapanların bazılarının da belirttiği gibi, yalnızca en son işlemi değiştirmek isterseniz, rebase komutu gerekli değildir. Sadece yap

 git commit --amend --author "New Author Name <email@address.com>"

Bu, yazarın adını belirtilen adla değiştirecektir, ancak gönderici yapılandırılmış kullanıcınız olarak ayarlanacaktır. git config user.name ve git config user.email. Göndereni belirttiğiniz bir şeye ayarlamak isterseniz, bu hem yazar hem de göndericiyi ayarlayacaktır:

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

Birleştirme Komiteleri hakkında not

Orijinal yanıtımda hafif bir kusur vardı. Akım arasında herhangi bir birleşme varsa HEAD ve senin <some HEAD before all your bad commits>, sonra git rebase Onları düzleştirecek (ve bu arada, GitHub isteklerini kullanırsanız, geçmişinizde bir tonluk birleşme taahhütleri olacak). Bu genellikle çok farklı bir tarihe yol açabilir (yinelenen değişiklikler "rebased out" olabilir) ve en kötü durumda git rebase zor birleştirme çakışmaları (büyük olasılıkla birleştirme işlemlerinde çözülmüş olanlar) çözümlemenizi istemek. Çözüm kullanmak -p bayrağı git rebasetarihinizin birleştirme yapısını koruyacaktır. Manpage için git rebase kullanarak uyarır -p ve -i sorunlara yol açabilir, ancak BUGS bölüm, "Düzenlemeleri düzenlemek ve taahhüt mesajlarını yeniden yayınlamak iyi çalışıyor" diyor.

ekledim -p Yukarıdaki komuta. En son işlemi değiştirdiğiniz durumda, bu bir sorun değil.


1417
2017-08-24 03:08



Garip taahhüt için harika - eşleştirme ve yazar değiştirmeyi unutuyorsanız yararlıdır - mloughran
Tipik tek hata düzeltmesi için usecase'den bahsetmek için +1: git commit --amend --author = username - Nathan Kidd
Bu mükemmel, en yaygın kullanımım, başka bir bilgisayara oturmam ve yazarı kurmayı unutmam ve bu yüzden genellikle düzeltmek için <5 taahhütte bulunmam. - Zitrax
git commit --amend --reset-author bir kez de çalışır user.name ve user.email doğru şekilde yapılandırılmıştır. - pts
Sonrasındaki tüm taahhütler için yazar bilgisini yeniden yaz <commit> kullanma user.name ve user.email itibaren ~/.gitconfig: koşmak git rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit', kaydet, çık. Düzenlemeye gerek yok! - ntc2


Ayrıca şunları da yapabilirsiniz:

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

Not, bu komutu Windows komut isteminde kullanıyorsanız, kullanmanız gerekir. "yerine ':

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

566
2018-05-15 19:15



Env filtresini daha kolay bir çözüm kullanmıyor mu? Bunun neden daha fazla oy aldığına emin değilsin. - stigkj
Sonra bağlantı bozuk. Bu değişiklikleri başka bir depoya nasıl ittiririz? - Russell
env filtresi tüm işlemleri değiştirecektir. Bu çözüm bir koşullu sağlar. - user208769
"A previous backup already exists in refs/original/ Force overwriting the backup with -f" üzgünüm ama nerede -f Bu betiği iki kez yürütmek için cüret kurulacak. Aslında bu Brian'ın cevabında, filtre-dalının çözümünden hemen sonra rahatsızlık için özür dilerim. - hhh
@ user208769 env-filter ayrıca koşullara da izin verir; cevabıma bak :-) - stigkj


Bir astar, ancak çok kullanıcılı bir deponuz varsa dikkatli olun - bu değişecektir herşey aynı (yeni) yazar ve üyeye sahip olmayı taahhüt eder.

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

Dizede linebreaks ile (bash'ta mümkündür):

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

483
2018-04-15 03:22



Evet, ama gönderenin adını / e-postasını unutma. Benim için ne çalıştı git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; GIT_COMMITER_NAME='Newname'; GIT_COMMITTER_EMAIL='newemail';" HEAD Aksi takdirde git, eski adı bir gönderici olarak takip edecektir! - Olivier Verdier
@Olivier GIT_COMMITER_NAME -> GIT_COMMITTER_NAME üzerinde bir yazım hatası var - Filipe Correia
İlk başta olmak üzere benim için tüm taahhütler için çalıştı. - Vincent
Belirttiğinizde neden tüm gönderileri yeniden yazıyor? HEAD Komutun sonunda? - Nick Volynkin
Bu benim bitbucket deposu için işe yaramıyor, herhangi bir fikrin var mı? Ben yaparım git push --force --tags origin 'refs/heads/*' tavsiye edilen komuttan sonra - ujsgeyrr1f0d0d0r0h1h0j0j_juj


Başlangıçta $ HOME / .gitconfig yoksa gerçekleşir. Bunu şu şekilde düzeltebilirsiniz:

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

git sürüm 1.7.5.4 ile test edilmiştir


202
2018-02-16 09:46



Bu son işte gerçekten iyi çalışıyor. Güzel ve basit. yok mu var küresel bir değişiklik olmak --local çok çalışıyor - Ben
git commit --amend --reset-author --no-edit - mafrosis


Tek bir taahhüt için:

git commit --amend --author="Author Name <email@address.com>"

(asmeurer'ın cevabından çıkarılmış)


180
2018-04-26 22:50



ama bu sadece en son söz konusuysa - Richard
Göre git help commit, git commit --amend “Mevcut şubenin ucunda” (HEAD olan) taahhüdü değiştirir. Bu normalde en son işlemdir, ancak önce istediğiniz herhangi bir taahhütte bulunabilirsiniz. kontrol etmek bununla uğraşmak git checkout <branch-name> veya git checkout <commit-SHA>. - Rory O'Kane
Fakat bunu yaparsanız, zaten bir ebeveyn olarak işleyen tüm taahhütler yanlış işleme işaret ediyor olacaktır. Bu noktada filtre dalını kullanmak daha iyidir. - John Gietzen
@JohnGietzen: İşlemleri düzeltmek için değiştirilene geri yükleyebilirsiniz. Bununla birlikte, eğer> 1 işlemi yapıyorsanız, daha önce bahsedildiği gibi, filtre-dalı muhtemelen çok daha kolay olacaktır. - Thanatos
Bu değişikliklerin yalnızca işleme koyulduğunu unutmayın. author ve değil committer - Nick Volynkin


Sadece en az birkaç çalışmanın kötü yazarlara sahip olması durumunda, bunu tümüyle yapabilirsiniz. git rebase -i kullanmak exec komuta ve --amend taahhüt, aşağıdaki gibi:

git rebase -i HEAD~6 # as required

sizi düzenlenebilir taahhüt listesiyle birlikte sunar:

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

Sonra Ekle exec ... --author="..." kötü yazarlarla tüm satırlardan sonra satırlar:

pick abcd Someone else's 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

editörü kaydet ve çıkar (çalıştır).

Bu çözüm, bazılarına göre daha uzun olabilir, ancak oldukça kontrol edilebilir - Ne isabet ettiğini tam olarak biliyorum.

İlham için @asmeurer'e teşekkürler.


152
2017-12-08 17:05



Kesinlikle harika. Repo'nun yerel yapılandırmasında user.name ve user.email ayarlayarak kısaltabilir ve sonra her satır sadeceexec git commit --amend --reset-author -C HEAD ? - Andrew
@Andrew --reset-author gayet iyi çalışıyor. - Boggin
Filtre dalını kullanmak için kanonik yanıt, sadece benim için refs / heads / master silindi. Böylece, kontrol edilebilir, düzenlenebilir çözümünüze +1. Teşekkürler! - jmtd
Neden başlıyorsun? Someone else's commityerine my bad commit 1? Az önce denedim HEAD^^ Son 2 işi değiştirmek için mükemmel çalıştı. - fredoverflow
Yerine git rebase -i HEAD^^^^^^ sen de yazabilirsin git rebase -i HEAD~6 - Patrick Schlüter


Github bir güzel çözümAşağıdaki kabuk komut dosyasıdır:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

108
2017-10-07 09:54



Mükemmel çalıştı. Sadece vardı git reset --hard HEAD^ Onları önceki bir versiyona götürmek için diğer yerel depolarda birkaç kez git pulldeğiştirilmiş versiyonu, ve burada hiçbir satır içermiyor unknown <stupid-windows-user@.StupidWindowsDomain.local> (git'in varsayılan değerini sevdim). - Alan Plum
Bundan sonra zorlayamam. "-F" yi kullanmak zorunda mıyım? - fossilet
yaptım git push -f. Ayrıca, yerel reposların bundan sonra tekrar klonlanması gerekmektedir. - fossilet
Kabuk betiğini belirli bir dalda çalıştırmanız gerekirse, son satırı şu şekilde değiştirebilirsiniz: "master.your-branch-name" (master'ın dallanması varsayılarak). - Robert Kajic
Komut güncellendiği için <nice solution> bağlantısını tıklayın. - mdn