web-dev-qa-db-fra.com

Comment changer le nom de l'auteur et du commetteur ainsi que l'e-mail de plusieurs commits dans Git?

J'étais en train d'écrire un script simple sur l'ordinateur de l'école et de valider les modifications apportées à Git (dans un dépôt qui était dans ma clé USB, cloné à partir de mon ordinateur à la maison). Après plusieurs commits, j'ai réalisé que je commettais des choses en tant qu'utilisateur root.

Est-il possible de changer l'auteur de ces commits à mon nom?

2219
Flávio Amieiro

Changer l'auteur (ou l'auteur) nécessiterait de réécrire toute l'histoire. Si cela vous convient et si vous pensez que cela en vaut la peine, vous devriez jeter un œil à git filter-branch . La page de manuel contient plusieurs exemples pour vous aider à démarrer. Notez également que vous pouvez utiliser des variables d'environnement pour modifier le nom de l'auteur, du commetteur, des dates, etc. - voir la section "Variables d'environnement" de la page de manuel git .

Plus précisément, vous pouvez corriger tous les mauvais noms d’auteurs et emails pour toutes les branches et tags avec cette commande (source: aide de GitHub ):

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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
1041
Pat Notz

Utilisation de Rebase interactive

Vous pourriez faire

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

Ensuite, marquez tous vos mauvais commits comme "edit" dans le fichier de base. Si vous souhaitez également modifier votre première validation, vous devez l'ajouter manuellement en tant que première ligne du fichier de base (suivez le format des autres lignes). Ensuite, quand git vous demande de modifier chaque commit, faites

 git commit --amend --author "New Author Name <[email protected]>" 

éditez ou fermez simplement l'éditeur qui s'ouvre, puis faites

git rebase --continue

pour continuer la rebase.

Vous pouvez ignorer d'ouvrir l'éditeur ici en ajoutant --no-edit afin que la commande soit:

git commit --amend --author "New Author Name <[email protected]>" --no-edit && \
git rebase --continue

Engagement unique

Comme l'ont noté certains commentateurs, si vous souhaitez simplement modifier la validation la plus récente, la commande rebase n'est pas nécessaire. Il suffit de faire

 git commit --amend --author "New Author Name <[email protected]>"

Ceci changera l'auteur au nom spécifié, mais le commetteur sera défini sur votre utilisateur configuré dans git config user.name et git config user.email. Si vous voulez définir le committer sur quelque chose que vous spécifiez, cela définira à la fois l'auteur et le committer:

 git -c user.name="New Author Name" -c [email protected] commit --amend --reset-author

Note sur les commits de fusion

Il y avait un léger défaut dans ma réponse initiale. S'il y a des commits de fusion entre le HEAD actuel et votre <some HEAD before all your bad commits>, alors git rebase les aplatira (et au fait, si vous utilisez des demandes d'extraction GitHub, il y aura un une tonne de fusion s’engage dans votre histoire). Cela peut très souvent conduire à un historique très différent (car les modifications en double peuvent être "rebasées"), et dans le pire des cas, cela peut vous amener à git rebase vous demander de résoudre des conflits de fusion difficiles (qui ont probablement déjà été résolus en la fusion s’engage). La solution consiste à utiliser l'indicateur -p pour git rebase, ce qui préservera la structure de fusion de votre historique. La page de manuel relative à git rebase indique que l'utilisation de -p et de -i peut entraîner des problèmes, mais que dans la section BUGS, il est indiqué "La modification et la reformulation des messages de validation doivent fonctionner correctement. "

J'ai ajouté -p à la commande ci-dessus. Dans le cas où vous ne modifiez que le commit le plus récent, ce n'est pas un problème.

1518
asmeurer

Vous pouvez aussi faire:

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

Remarque: si vous utilisez cette commande dans l'invite de commande Windows, vous devez utiliser " au lieu de ':

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
579
Rognon

Une ligne, mais soyez prudent si vous avez un référentiel multi-utilisateurs - cela changera tous s’engage à avoir le même (nouvel) auteur et le même auteur.

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

Avec des sauts de ligne dans la chaîne (ce qui est possible dans bash):

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
520
Brian Gianforcaro

Cela arrive quand vous n'avez pas initialisé $ HOME/.gitconfig. Vous pouvez corriger ceci comme:

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

testé avec la version 1.7.5.4 de git

214
lrkwz

Pour un seul commit:

git commit --amend --author="Author Name <[email protected]>"

(extrait de la réponse de asmeurer)

181
blueyed

Dans le cas où seuls les premiers commits ont de mauvais auteurs, vous pouvez faire tout cela à l'intérieur de git rebase -i à l'aide de la commande exec et du commit --amend, comme suit:

git rebase -i HEAD~6 # as required

qui vous présente la liste éditable des commits:

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

Puis ajoutez exec ... --author="..." lignes après toutes les lignes avec de mauvais auteurs:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD

enregistrer et quitter l'éditeur (à exécuter).

Cette solution est peut-être plus longue à saisir que d’autres, mais elle est très contrôlable - je sais exactement ce qui l’engage.

Merci à @asmeurer pour l'inspiration.

170
Alex Brown

Github a un solution de Nice , qui est le script Shell suivant:

#!/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" = "[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
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"
'
109
Olivier Verdier

Comme docgnome l'a mentionné, la réécriture de l'histoire est dangereuse et va casser les répertoires d'autres personnes.

Mais si vous voulez vraiment faire cela et que vous êtes dans un environnement bash (pas de problème sous Linux, sous Windows, vous pouvez utiliser git bash, fourni avec l'installation de git), utilisez git filter-branch :

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

Pour accélérer les choses, vous pouvez spécifier une plage de révisions que vous souhaitez réécrire:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
80
svick

Lorsque vous prenez en charge un commit non-fusionné d'un autre auteur, il existe un moyen simple de gérer cela.

git commit --amend --reset-author

47
Ryanmt

Vous pouvez utiliser cela comme un alias pour pouvoir:

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

ou pour les 10 derniers commits:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

Ajouter à ~/.gitconfig:

[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 "

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

J'espère que c'est utile.

41
brauliobo

Ceci est une version plus élaborée de la version de @ Brian:

Pour changer l'auteur et le committer, vous pouvez le faire (avec des sauts de ligne dans la chaîne, ce qui est possible dans bash):

_git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all
_

Vous pourriez avoir l'une de ces erreurs:

  1. Le répertoire temporaire existe déjà
  2. Les références commençant par réfs/original existent déjà
    (cela signifie qu'une autre branche de filtre a déjà été exécutée sur le référentiel et que la référence de la branche d'origine est alors sauvegardée à refs/original )

Si vous souhaitez forcer l'exécution en dépit de ces erreurs, ajoutez l'indicateur --force:

_git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all
_

Une petite explication de l'option _-- --all_ peut être nécessaire: Cela permet à la branche filtre de fonctionner sur toutes les révisions de toutes les références (ce qui inclut toutes les modifications). branches). Cela signifie, par exemple, que les étiquettes sont également réécrites et sont visibles sur les branches réécrites.

Une "erreur" courante consiste à utiliser HEAD à la place, ce qui signifie que toutes les révisions sont filtrées uniquement sur la branche actuelle . Et puis aucune balise (ou autre référence) n’existerait dans la branche réécrite.

38
stigkj
  1. lancer git rebase -i <sha1 or ref of starting point>
  2. marquer tous les commits que vous voulez changer avec edit (ou e)
  3. boucle les deux commandes suivantes jusqu'à ce que vous ayez traité tous les commits:

    git commit --amend --reuse-message=HEAD --author="New Author <[email protected]>"; git rebase --continue

Cela conservera toutes les autres informations de validation (y compris les dates). L'option --reuse-message=HEAD empêche l'éditeur de message de se lancer.

23
sporsh

J'utilise ce qui suit pour réécrire l'auteur pour un référentiel entier, y compris les balises et toutes les branches:

git filter-branch --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

Ensuite, comme décrit dans la page MAN de filter-branch , supprimez toutes les références d'origine sauvegardées par filter-branch (ceci est destructif, sauvegardez d'abord):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d
21
Ton van den Heuvel

J'ai adapté cette solution qui fonctionne en ingérant un simple author-conv-file (le format est le même que celui de git-cvsimport ). Cela fonctionne en changeant tous les utilisateurs comme défini dans le author-conv-file dans toutes les branches.

Nous avons utilisé cela conjointement avec cvs2git pour migrer notre référentiel de cvs vers git.

exemple: author-conv-file

john=John Doe <[email protected]>
jill=Jill Doe <[email protected]>

Le scénario:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) <.*>$/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* <\(.*\)>$/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all
21
Leif Gruenwoldt

J'ai trouvé les versions présentées trop agressives, en particulier si vous corrigez des correctifs d'autres développeurs, cela leur volerait essentiellement du code.

La version ci-dessous fonctionne sur toutes les branches et modifie l'auteur et le créateur séparément pour éviter cela.

Félicitations à leif81 pour l'option tout.

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<[email protected]>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<[email protected]>";
fi
' -- --all
18
drahnr
  1. Modifiez commit author name & email par Amend, puis remplacez old-commit with new-one:

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <[email protected]>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git Push -f Origin HEAD              # force Push 
    
  2. Une autre façon Rebasing:

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <[email protected]>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase
    
17
Sajib Khan

Je dois préciser que si le seul problème est que l'auteur/l'email est différent de votre habitude, ce n'est pas un problème. La solution correcte consiste à créer un fichier nommé .mailmap à la base du répertoire avec des lignes telles que

Name you want <email you want> Name you don't want <email you don't want>

Et à partir de là, des commandes telles que git shortlog considèrent que ces deux noms sont identiques (à moins que vous ne leur disiez spécifiquement de ne pas le faire). Voir http://schacon.github.com/git/git-shortlog.html pour plus d'informations.

Cela présente l’avantage de toutes les autres solutions ici, en ce sens que vous n’avez pas à réécrire l’historique, ce qui peut poser des problèmes si vous avez un réseau en amont et constitue toujours un bon moyen de perdre des données par accident.

Bien sûr, si vous avez commis quelque chose en tant que vous-même et que cela devrait vraiment être quelqu'un d'autre, et que cela ne vous dérange pas de réécrire l'historique à ce stade, changer le commender est probablement une bonne idée aux fins d'attribution (dans ce cas, je vous dirige vers mon autre réponse ici).

16
asmeurer

Supposons que vous souhaitiez changer l'auteur pour les N derniers commits:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

NOTES

  • le drapeau --no-edit s'assure que le git commit --amend ne demande pas de confirmation supplémentaire
  • lorsque vous utilisez git rebase -i, vous pouvez sélectionner manuellement les commits où modifier l'auteur,

le fichier que vous éditez ressemblera à ceci:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit

Vous pouvez alors toujours modifier certaines lignes pour voir où vous voulez changer l'auteur. Cela vous donne un bon compromis entre automatisation et contrôle: vous voyez les étapes à suivre et une fois que vous enregistrez, tout sera appliqué en une fois.

13
Chris Maes

Si vous êtes le seul utilisateur de ce référentiel, vous pouvez réécrire l'historique en utilisant git filter-branch (comme svick écrit ), ou git fast-export / git fast-import plus le script de filtrage (comme décrit dans l'article référencé dans docgnome answer ), ou interactif rebase . Mais l'un ou l'autre modifierait les révisions à partir du premier engagement modifié; cela signifie des problèmes pour quiconque fondant ses modifications sur la pré-réécriture de votre branche.

RÉCUPÉRATION

Si les autres développeurs ne basaient pas leur travail sur la version pré-réécriture, la solution la plus simple consisterait à cloner à nouveau (cloner à nouveau).

Ils peuvent aussi essayer git rebase --pull, ce qui accélèrerait l’avancement si aucun référentiel n’était modifié dans leur référentiel, ou rebasonnait leur branche au-dessus des validations réécrites (nous voulons éviter la fusion, car cela garderait les vérifications pré-réécrites pour toujours) . Tout cela en supposant qu’ils n’ont pas engagé de travail; utilisez git stash pour cacher les modifications autrement.

Si d'autres développeurs utilisent des branches de fonctionnalités et/ou si git pull --rebase ne fonctionne pas, par exemple. car l'amont n'est pas configuré, ils doivent rebase leur travail sur les validations post-réécriture. Par exemple, juste après avoir récupéré les nouvelles modifications (git fetch), pour une branche master basée sur/passé de Origin/master, il faut exécuter

$ git rebase --onto Origin/master Origin/master@{1} master

Ici, Origin/master@{1} correspond à l'état de pré-réécriture (avant extraction), voir gitrevisions .


Une autre solution consisterait à utiliser le mécanisme refs/replace /, disponible dans Git depuis la version 1.6.5. Dans cette solution, vous fournissez des remplacements pour les commits contenant un courrier électronique incorrect. alors, toute personne qui récupère des références de remplacement (quelque chose comme fetch = +refs/replace/*:refs/replace/* refspec à la place appropriée dans leur .git/config) obtiendrait des remplacements de manière transparente, et ceux qui ne chercheraient pas ces références verraient les anciens commits.

La procédure ressemble à ceci:

  1. Trouver tous les commits avec un email incorrect, par exemple en utilisant

    $ git log [email protected] --all
    
  2. Pour chaque validation incorrecte, créez une validation de remplacement et ajoutez-la à la base de données objet.

    $ git cat-file -p <ID of wrong commit> | 
      sed -e 's/user@wrong\.email/[email protected]/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    
  3. Maintenant que vous avez corrigé le commit dans la base de données d'objets, vous devez indiquer à git de remplacer automatiquement et de manière transparente le faux commit par le correctif en utilisant git replace commande:

    $ git replace <ID of wrong commit> <ID of corrected commit>
    
  4. Enfin, listez tous les remplaçants pour vérifier si cette procédure a abouti

    $ git replace -l
    

    et vérifier si les remplacements ont lieu

    $ git log [email protected] --all
    

Vous pouvez bien sûr automatiser cette procédure ... eh bien, tous sauf l’utilisation de git replace qui n’a pas (encore) de mode de traitement par lots; vous devrez donc utiliser la boucle Shell pour cela ou remplacer "à la main".

NON TESTED! YMMV.

Notez que vous pouvez rencontrer des difficultés lors de l’utilisation du mécanisme refs/replace/: il est nouveau et n’a pas encore été bien testé..

9
Jakub Narębski

Si les commits que vous souhaitez corriger sont les plus récents, vous pouvez utiliser une combinaison de git reset et git stash pour revenir en arrière et les valider à nouveau après avoir configuré le nom et l'adresse e-mail corrects. .

La séquence ressemblera à ceci (pour 2 erreurs de validation, aucune modification en attente):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a
6
djromero

Le moyen le plus rapide et le plus simple consiste à utiliser l'argument --exec de git rebase:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

Cela va créer une liste de tâches qui ressemble à ceci:

pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...

et cela fonctionnera automatiquement, ce qui fonctionnera lorsque vous aurez des centaines de commits.

6
Lie Ryan

Votre problème est vraiment commun. Voir " tiliser Mailmap pour corriger la liste des auteurs dans Git "

Par souci de simplicité, j'ai créé un script pour faciliter le processus: git-changemail

Après avoir placé ce script sur votre chemin, vous pouvez émettre des commandes telles que:

  • Modifier les correspondances d'auteur sur la branche actuelle

    $ git changemail -a [email protected] -n newname -m [email protected]
    
  • Modifiez les correspondances auteur et auteur sur <branche> et <branche2>. Passez -f à la branche de filtre pour permettre la réécriture des sauvegardes

    $ git changemail -b [email protected] -n newname -m [email protected] -- -f &lt;branch> &lt;branch2>
    
  • Afficher les utilisateurs existants sur le repo

    $ git changemail --show-both
    

A propos, après avoir effectué vos modifications, nettoyez la sauvegarde de la branche filter avec: git-backup-clean

5
albfan

Nous avons rencontré un problème aujourd'hui où un caractère UTF8 dans un nom d'auteur posait problème sur le serveur de compilation. Nous avons donc dû réécrire l'historique pour corriger cela. Les mesures prises étaient les suivantes:

Étape 1: Modifiez votre nom d'utilisateur dans git pour tous les futurs commits, conformément aux instructions ci-dessous: https://help.github.com/articles/setting-your-username-in-git/

Étape 2: Exécutez le script bash suivant:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r Origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force Push the rewritten branches + tags to the remote
git Push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

Présentation rapide: extrayez votre référentiel dans un fichier temporaire, extrayez toutes les branches distantes, exécutez le script qui réécrit l’historique, forcez le nouvel état et indiquez à tous vos collègues de procéder à une nouvelle extraction pour obtenir les modifications.

Nous avions des problèmes pour l’exécuter sur OS X parce que cela finissait par gâcher les fins de ligne dans les messages de validation, nous avons donc dû le réexécuter ultérieurement sur une machine Linux.

5

Notez que git stocke deux différentes adresses e-mail, une pour le committer (la personne qui a effectué la modification) et une autre un pour l'auteur (la personne qui a écrit le changement).

Les informations sur le committeur ne sont pas affichées dans la plupart des endroits, mais vous pouvez les voir avec git log -1 --format=%cn,%ce (ou utilisez show au lieu de log pour spécifier une validation particulière).

Bien que le changement d’auteur de votre dernier commit soit aussi simple que git commit --amend --author "Author Name <[email protected]>", il n’existe pas de solution unique ni d’argument permettant de faire la même chose avec les informations sur le donneur.

La solution consiste à (temporairement ou non) modifier vos informations utilisateur, puis à modifier le commit, ce qui mettra à jour le commetteur avec vos informations actuelles:

git config user.email [email protected] 
git commit --amend
5
Sir Athos

À l'aide de la base interactive, vous pouvez placer une commande de modification après chaque validation que vous souhaitez modifier. Par exemple:

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead
5
j16r

Si vous utilisez Eclipse avec EGit, il existe une solution assez simple.
Hypothèse: vous avez des commits dans une branche locale 'local_master_user_x' qui ne peuvent pas être transférés vers une branche distante 'maître' à cause de l'utilisateur non valide.

  1. Commander le 'maître' de la branche distante
  2. Sélectionnez les projets/dossiers/fichiers pour lesquels 'local_master_user_x' contient des modifications.
  3. Clic droit - Remplacer par - Branche - 'local_master_user_x'
  4. Validez ces modifications à nouveau, cette fois en tant qu'utilisateur correct et dans le "maître" de la branche locale
  5. Push to 'maître' à distance
5
paphko

Si vous êtes le seul utilisateur de ce référentiel ou si vous ne vous inquiétez pas de le casser éventuellement pour d'autres utilisateurs, alors oui. Si vous avez poussé ces commissions et qu'elles existent où un autre endroit peut y accéder, alors non, à moins que vous ne vous préoccupiez pas de mettre en veilleuse le repos des autres. Le problème est qu'en modifiant ces commits, vous allez générer de nouveaux SHA qui les traiteront comme des commits différents. Quand quelqu'un d'autre essaie de récupérer ces commits modifiés, l'histoire est différente et kaboom.

Cette page http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html décrit comment le faire. (Je n'ai pas essayé cela alors YMMV)

2
baudtack

Je veux ajouter mon exemple aussi. Je veux créer une fonction bash_function avec un paramètre donné.

cela fonctionne dans mint-linux-17.3

# $1 => email to change, $2 => new_name, $3 => new E-Mail

function git_change_user_config_for_commit {

 # defaults
 WRONG_EMAIL=${1:-"[email protected]"}
 NEW_NAME=${2:-"your name"}
 NEW_EMAIL=${3:-"[email protected]"}

 git filter-branch -f --env-filter "
  if [ \$GIT_COMMITTER_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_COMMITTER_NAME='$NEW_NAME'
    export GIT_COMMITTER_EMAIL='$NEW_EMAIL'
  fi
  if [ \$GIT_AUTHOR_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_AUTHOR_NAME='$NEW_NAME'
    export GIT_AUTHOR_EMAIL='$NEW_EMAIL'
  fi
 " --tag-name-filter cat -- --branches --tags;
}
2
stephanfriedrich

Essayez ceci. Il fera la même chose que mentionné ci-dessus, mais de manière interactive.

bash <(curl -s  https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)

Référence: https://github.com/majdarbash/git-author-change-script

1
Majd Arbash
git rebase -i YOUR_FIRTS_COMMIT_SHA^

while true; do git commit --amend --author="Name Surname <[email protected]>" --no-edit && git rebase --continue; done

Appuyez sur ^ C # après la réinitialisation (la boucle continuera à mettre à jour la dernière validation)

1
Vojtech Vitek