Posso mudar meu nome e sobrenome em todas as confirmações anteriores?

122

Gostaria de mudar meu nome, sobrenome e e-mail em todos os meus commits, é possível?

Joshua
fonte
2
É um reprositório apenas para você, para algumas pessoas ou para um grande projeto?
thejh
3
possível duplicata de Como altero o autor de uma confirmação no git?
Josh Lee

Respostas:

212

Use 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 "$@"'

Isso afeta apenas o autor, não o autor (que para a maioria dos commits será o mesmo que o autor). Se você deseja reescrevê-las, defina as variáveis GIT_COMMITTER_NAMEe GIT_COMMITTER_EMAIL.

O aviso padrão sobre reescrever o histórico se aplica; apenas faça isso para a história que ainda não foi compartilhada.

Atualização de junho de 2018

O manual agora inclui uma solução, usando --env-filter, em seus exemplos: 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
fonte
4
Se você estiver usando msysgit, ainda tem acesso bash. Caso contrário, eu não tenho idéia.
Josh Lee
@ Josué, se você estiver usando algo em que não possui o bash, provavelmente poderá usar o script em lote do Windows, embora eu não tenha tentado.
MatrixFrog
e as tags? esta solução não vai mudar autor de marcas
piotrek
@Joshua verificar o repo git em uma máquina Linux e executar a correção lá
Will Sheppard
Existe uma opção que resulte em nova ramificação e deixe a fonte confirmada intacta?
Eugen Konkov
56

Para reescrever o autor e o commiter em todos os commits selecionados:

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 "$@"'
user11153
fonte
1
Mas como aplicar as alterações no servidor remoto?
vikyd
5
@Viky Trygit push --all origin --force
user11153
2
Funciona para mim ! Estou usando o GitLab, tenho que desproteger o ramo antes de pressionar o comando.
vikyd
37

Se não houver outros autores, você poderá:

git filter-branch --commit-filter 'export GIT_AUTHOR_NAME="authorname"; \
export [email protected]; git commit-tree "$@"'
denis.peplin
fonte
1
Não está reescrevendo informações de "Committer:".
User11153
1
Não pretende reescrever as informações do committer. Se você quiser fazer isso, exporte GIT_COMMITTER_NAME e GIT_COMMITTER_EMAIL também (consulte a resposta aceita).
Chronospoon
12

Salve o script abaixo como por exemplo ~/.bin/git-replace-authore execute-o usando, por exemplo:

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

Sem argumentos, ele atualiza todos os commits com seu nome para usar seu endereço de email atual de acordo com a configuração do 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 (para download)

Zaz
fonte
Como uma pequena nota: ~/.bin/precisa estar dentro dos usuários $PATHe as necessidades de arquivo para ser executável, então execute: chmod +x ~/.bin/git-replace-author.
Michael Gecht
E o que isso faz com argumentos?
Eugen Konkov
2

Somente se você não tiver enviado seus commits ao mundo. Por outro lado, todo mundo tem seu nome antigo em seu repositório, o que é improvável que você possa mudar o nome de todos.

EnabrenTane
fonte
Verdade, mas em alguns casos você não tem escolha. No meu caso, eu tinha um endereço de e-mail errado configurado na minha configuração do git (como pude ver em "git config --global -l"). Como resultado, eu não tive nenhuma atividade de confirmação aparecendo no meu próprio repositório do Github (porque o endereço de email não correspondia ao email configurado no Github)! Para resolver isso, corrigi meus commits locais usando a receita de stackoverflow.com/a/23564785/2474068 (funcionou perfeitamente) e depois enviei os commits alterados para o Github usando "git push -u -f origin master" (com a força sinalizador "-f"). Isso vai contra a prática aceita, mas eu não tive escolha!
Leo
1
Sim, meu argumento era que qualquer garfo desse repositório não teria essa mudança, a menos que eles aceitassem seu impulso de força. Seria um desafio para obter cada garfo para atualização :)
EnabrenTane
1

Com o Git 2.24 (quarto trimestre de 2019), git filter-branch(e BFG) está obsoleto .

O equivalente seria, using newren/git-filter-repo, e sua seção de exemplo :

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

com my-mailmap:

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

Isso substituiria o nome do autor e o email de qualquer confirmação feita por qualquer pessoa com <[email protected]>

Consulte a git shortlogseção de autor de mapeamento para obter a sintaxe exata de

VonC
fonte