J'écrivais un script simple dans l'ordinateur de l'école et j'engageais les modifications dans Git (dans un dépôt qui était dans ma clé USB, cloné depuis mon ordinateur à la maison). Après plusieurs validations, j'ai réalisé que je validais des choses en tant qu'utilisateur root.
Existe-t-il un moyen de changer l'auteur de ces commits en mon nom?
git
version-control
git-filter-branch
git-rewrite-history
Flávio Amieiro
la source
la source
Réponses:
Changer l'auteur (ou le committer) nécessiterait de réécrire toute l'histoire. Si vous êtes d'accord avec cela et pensez que cela en vaut la peine, alors vous devriez vérifier git filter-branch . La page de manuel comprend plusieurs exemples pour vous aider à démarrer. Notez également que vous pouvez utiliser des variables d'environnement pour changer le nom de l'auteur, du committer, 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'auteur et e-mails pour toutes les branches et balises avec cette commande (source: aide GitHub ):
la source
git push --force --tags origin HEAD:master
REMARQUE: cette réponse modifie les SHA1, alors faites attention à l'utiliser sur une branche qui a déjà été poussée. Si vous souhaitez uniquement corriger l'orthographe d'un nom ou mettre à jour un ancien e-mail, git vous permet de le faire sans réécrire l'historique à l'aide de
.mailmap
. Voir mon autre réponse .Utilisation d'Interactive Rebase
Vous pourriez faire
Ensuite, marquez tous vos mauvais commits comme "modifier" dans le fichier de rebase. Si vous souhaitez également modifier votre premier commit, vous devez l'ajouter manuellement comme première ligne dans le fichier de rebase (suivez le format des autres lignes). Ensuite, quand git vous demande de modifier chaque commit, faites
modifier ou simplement fermer l'éditeur qui s'ouvre, puis faites
pour continuer le rebase.
Vous pouvez ignorer l'ouverture de l'éditeur ici en ajoutant
--no-edit
pour que la commande soit:Validation unique
Comme certains commentateurs l'ont noté, si vous souhaitez simplement modifier le commit le plus récent, la commande rebase n'est pas nécessaire. Fais juste
Cela changera l'auteur en nom spécifié, mais le committer sera défini sur votre utilisateur configuré dans
git config user.name
etgit config user.email
. Si vous souhaitez définir le committer sur quelque chose que vous spécifiez, cela définira à la fois l'auteur et le committer:Remarque sur les validations de fusion
Il y avait un léger défaut dans ma réponse d'origine. S'il y a des validations de fusion entre l'actuel
HEAD
et le vôtre<some HEAD before all your bad commits>
,git rebase
les aplatiront (et au fait, si vous utilisez des requêtes Pull GitHub, il y aura une tonne de validations de fusion dans votre historique). 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 conduire àgit rebase
vous demander de résoudre des conflits de fusion difficiles (qui étaient probablement déjà résolus dans les validations de fusion). La solution consiste à utiliser l'-p
indicateur togit rebase
, qui préservera la structure de fusion de votre historique. La page de manuel pourgit rebase
avertit que l'utilisation de-p
et-i
peut entraîner des problèmes, maisBUGS
Dans la section, il est indiqué que «la modification des validations et la reformulation de leurs messages de validation devraient fonctionner correctement.J'ai ajouté
-p
à la commande ci-dessus. Dans le cas où vous modifiez simplement la validation la plus récente, ce n'est pas un problème.la source
git commit --amend --reset-author
fonctionne également une foisuser.name
etuser.email
est configuré correctement.<commit>
utiliséuser.name
et àuser.email
partir de~/.gitconfig
: exécutergit rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit'
, enregistrer, quitter. Pas besoin d'éditer!Vous pouvez également faire:
Remarque, si vous utilisez cette commande dans l'invite de commande Windows, vous devez utiliser à la
"
place de'
:la source
"A previous backup already exists in refs/original/ Force overwriting the backup with -f"
désolé mais où le-f
-flag va être quand vous exécutez ce script deux fois. En fait, c'est dans la réponse de Brian, désolé pour les perturbations juste après que la branche de filtre soit la solution.Un liner, mais soyez prudent si vous avez un référentiel multi-utilisateurs - cela changera toutes les validations pour avoir le même (nouveau) auteur et committer.
Avec des sauts de ligne dans la chaîne (ce qui est possible en bash):
la source
HEAD
à la fin de la commande?git push --force --tags origin 'refs/heads/*'
après la commande conseillée$git push --force --tags origin 'refs/heads/master'
Cela se produit lorsque vous n'avez pas initialisé $ HOME / .gitconfig. Vous pouvez résoudre ce problème comme suit:
testé avec la version 1.7.5.4 de git
la source
--local
œuvres aussigit commit --amend --reset-author --no-edit
commande est particulièrement utile si vous avez créé des validations avec des informations d'auteur erronées, puis définissez l'auteur correct après coup viagit config
. J'ai enregistré mon $ $$ juste au moment où je devais mettre à jour mon e-mail.Pour un seul commit:
(extrait de la réponse de l'asmeurer)
la source
git help commit
,git commit --amend
modifie le commit à la «pointe de la branche actuelle» (qui est HEAD). Il s'agit généralement du commit le plus récent, mais vous pouvez le faire à tout moment en vérifiant d'abord ce commit avecgit checkout <branch-name>
ougit checkout <commit-SHA>
.author
committer
Dans le cas où seules les premières validations ont de mauvais auteurs, vous pouvez tout faire à l'intérieur en
git rebase -i
utilisant laexec
commande et la--amend
validation, comme suit:qui vous présente la liste modifiable des commits:
Ajoutez ensuite des
exec ... --author="..."
lignes après toutes les lignes avec de mauvais auteurs:enregistrer et quitter l'éditeur (pour exécuter).
Cette solution peut être plus longue à taper que certaines autres, mais elle est hautement contrôlable - je sais exactement ce qu'elle engage.
Merci à @asmeurer pour l'inspiration.
la source
exec git commit --amend --reset-author -C HEAD
?Someone else's commit
au lieu demy bad commit 1
? J'ai juste essayéHEAD^^
de modifier les 2 derniers commits, et cela a parfaitement fonctionné.git rebase -i HEAD^^^^^^
vous pouvez également écriregit rebase -i HEAD~6
Github a une belle solution , qui est le script shell suivant:
la source
git reset --hard HEAD^
quelques fois sur les autres référentiels locaux pour les amener à une version antérieure,git pull
-ed la version modifiée, et me voici sans aucune ligne contenantunknown <[email protected]>
(j'ai adoré git's defaulting).git push -f
. De plus, les dépôts locaux doivent être reclonés après cela.Comme l'a mentionné docgnome, la réécriture de l'historique est dangereuse et brisera les référentiels des autres.
Mais si vous voulez vraiment le faire 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 :
Pour accélérer les choses, vous pouvez spécifier une gamme de révisions que vous souhaitez réécrire:
la source
--tag-name-filter cat
est l'option "faire fonctionner".--tag-name-filter cat
. Cela aurait vraiment dû être le comportement par défaut.Lorsque vous reprenez un commit non fusionné d'un autre auteur, il existe un moyen simple de gérer cela.
git commit --amend --reset-author
la source
--no-edit
pour rendre cela encore plus facile, car généralement la plupart des gens voudront mettre à jour uniquement l'adresse e-mail et non le message de validationVous pouvez l'utiliser comme un alias afin de pouvoir faire:
ou pour les 10 derniers commits:
Ajoutez à ~ / .gitconfig:
Source: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
J'espère que c'est utile.
la source
[[ ]]
compatible avec sh[ ]
(crochets simples). En plus ça marche très bien, merci!Il s'agit d'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 qui est possible dans bash):
Vous pouvez obtenir l'une de ces erreurs:
(cela signifie qu'une autre branche de filtre a été exécutée précédemment sur le référentiel et que la référence de branche d'origine est sauvegardée à refs / original )
Si vous souhaitez forcer l'exécution malgré ces erreurs, ajoutez l'
--force
indicateur:Une petite explication de l'
-- --all
option pourrait être nécessaire: elle fait fonctionner la branche de filtre sur toutes les révisions sur toutes les références (qui inclut toutes les branches). Cela signifie, par exemple, que les balises sont également réécrites et visibles sur les branches réécrites.Une "erreur" courante consiste à utiliser à la
HEAD
place, ce qui signifie filtrer toutes les révisions uniquement sur la branche actuelle . Et puis aucune balise (ou autres références) n'existerait dans la branche réécrite.la source
Une seule commande pour changer l'auteur des N derniers commits:
REMARQUES
--no-edit
drapeau s'assure que legit commit --amend
ne demande pas de confirmation supplémentairegit rebase -i
, vous pouvez sélectionner manuellement les validations où changer l'auteur,le fichier que vous éditez ressemblera à ceci:
Vous pouvez ensuite modifier certaines lignes pour voir où vous souhaitez modifier l'auteur. Cela vous donne un bon compromis entre l'automatisation et le contrôle: vous voyez les étapes qui se dérouleront, et une fois que vous aurez enregistré, tout sera appliqué en même temps.
la source
git rebase -i master -x ...
git rebase -i <sha1 or ref of starting point>
edit
(oue
)boucle les deux commandes suivantes jusqu'à ce que vous ayez traité toutes les validations:
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'
--reuse-message=HEAD
option empêche l'éditeur de messages de se lancer.la source
J'utilise ce qui suit pour réécrire l'auteur pour un référentiel entier, y compris les balises et toutes les branches:
Ensuite, comme décrit dans la page MAN de filter-branch , supprimez toutes les références d'origine sauvegardées par
filter-branch
(c'est destructif, sauvegardez d'abord):la source
--tag-name-filter cat
. Sinon, vos balises resteront sur la chaîne de validations d'origine. Les autres réponses ne le mentionnent pas.J'ai adapté cette solution qui fonctionne en ingérant un simple
author-conv-file
(le format est le même que pour git-cvsimport ). Il fonctionne en changeant tous les utilisateurs tels que définis dansauthor-conv-file
toutes les branches.Nous l'avons utilisé conjointement avec
cvs2git
pour migrer notre référentiel de cvs vers git.c.-à-d. échantillon
author-conv-file
Le scénario:
la source
Je dois souligner que si le seul problème est que l'auteur / e-mail est différent de votre habituel, ce n'est pas un problème. La solution correcte consiste à créer un fichier appelé
.mailmap
à la base du répertoire avec des lignes commeEt à partir de là, des commandes comme
git shortlog
considéreront ces deux noms comme étant les mêmes (sauf si vous leur dites spécifiquement de ne pas le faire). Voir http://schacon.github.com/git/git-shortlog.html pour plus d'informations.Cela a l'avantage de toutes les autres solutions ici en ce que vous n'avez pas à réécrire l'historique, ce qui peut causer des problèmes si vous avez un amont, et c'est toujours un bon moyen de perdre accidentellement des données.
Bien sûr, si vous avez commis quelque chose comme 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'histoire à ce stade, changer l'auteur de la validation est probablement une bonne idée à des fins d'attribution (auquel cas je vous dirige vers mon autre réponse ici).
la source
J'ai trouvé que les versions présentées étaient agressives, surtout si vous validez des correctifs d'autres développeurs, cela volera essentiellement leur code.
La version ci-dessous fonctionne sur toutes les branches et modifie l'auteur et le comitter séparément pour éviter cela.
Félicitations à leif81 pour l'option tout.
la source
Modifiez la validation
author name & email
parAmend
, puis remplacezold-commit with new-one
:Une autre façon
Rebasing
:la source
La façon la plus rapide et la plus simple de le faire est d'utiliser l'argument --exec de git rebase:
Cela créera une liste de tâches qui ressemble à ceci:
et cela fonctionnera automatiquement, ce qui fonctionne lorsque vous avez des centaines de validations.
la source
Si vous êtes le seul utilisateur de ce référentiel, vous pouvez réécrire l'historique en utilisant
git filter-branch
(comme écrit svick ), ougit fast-export
/ ou ungit fast-import
script de filtre (comme décrit dans l'article référencé dans la réponse docgnome ), ou un rebase interactif . Mais l'un ou l'autre modifierait les révisions à partir du premier commit modifié; cela signifie des problèmes pour quiconque a basé ses modifications sur la pré-réécriture de votre branche.RÉCUPÉRATION
Si d'autres développeurs ne basaient pas leur travail sur la version de pré-réécriture, la solution la plus simple serait de re-cloner (cloner à nouveau).
Alternativement, ils peuvent essayer
git rebase --pull
, qui avancerait rapidement s'il n'y avait aucun changement dans leur référentiel, ou rebaser leur branche au-dessus des validations réécrites (nous voulons éviter la fusion, car cela garderait les comits de pré-réécriture pour toujours). Tout cela en supposant qu'ils n'ont pas engagé de travail; utilisergit stash
pour cacher les modifications autrement.Si d'autres développeurs utilisent des branches de fonctionnalités et / ou
git pull --rebase
ne fonctionnent pas, par exemple parce que l'amont n'est pas configuré, ils doivent rebaser leur travail en plus des validations post-réécriture. Par exemple, juste après avoir récupéré de nouveaux changements (git fetch
), pour unemaster
branche basée sur / forked fromorigin/master
, il faut exécuterVoici l'état de
origin/master@{1}
pré-réécriture (avant l'extraction), voir gitrevisions .Une autre solution serait d'utiliser refs / replace / mécanisme, disponible dans Git depuis la version 1.6.5. Dans cette solution, vous fournissez des remplacements pour les validations contenant un mauvais e-mail; alors quiconque récupère les références de remplacement (quelque chose comme
fetch = +refs/replace/*:refs/replace/*
refspec à l'endroit approprié dans leur.git/config
) obtiendrait des remplacements de manière transparente, et ceux qui ne récupèrent pas ces références verraient les anciens commits.La procédure ressemble à ceci:
Rechercher toutes les validations avec un mauvais e-mail, par exemple en utilisant
Pour chaque commit incorrect, créez un commit de remplacement et ajoutez-le à la base de données d'objets
Maintenant que vous avez corrigé la validation dans la base de données d'objets, vous devez dire à git de remplacer automatiquement et de manière transparente la mauvaise validation par une correction à l'aide de la
git replace
commande:Enfin, listez tous les remplaçants pour vérifier si cette procédure a réussi
et vérifier si des remplacements ont lieu
Vous pouvez bien sûr automatiser cette procédure ... eh bien, tout sauf en utilisant
git replace
qui n'a pas (encore) le mode batch, vous devrez donc utiliser la boucle shell pour cela, ou remplacer "à la main".PAS TESTÉ! YMMV.
Notez que vous pourriez rencontrer des coins difficiles lors de l'utilisation du
refs/replace/
mécanisme: il est nouveau et pas encore très bien testé .la source
Si les validations que vous souhaitez corriger sont les dernières, et seulement quelques-unes, vous pouvez utiliser une combinaison de
git reset
etgit stash
revenir en arrière et les valider à nouveau après avoir configuré le bon nom et l'adresse e-mail.La séquence ressemblera à ceci (pour 2 commits incorrects, aucun changement en attente):
la source
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 poussés vers une branche distante 'master' à cause de l'utilisateur invalide.
la source
À l'aide de rebase interactif, vous pouvez placer une commande de modification après chaque validation que vous souhaitez modifier. Par exemple:
la source
;-)
.Notez que git stocke deux adresses e-mail différentes, une pour le committer (la personne qui a commis le changement) et une autre pour l' auteur (la personne qui a écrit le changement).
Les informations sur le committer ne sont pas affichées dans la plupart des endroits, mais vous pouvez les voir avec
git log -1 --format=%cn,%ce
(ou utilisershow
au lieu delog
pour spécifier un commit particulier).Bien que changer l'auteur de votre dernier commit soit aussi simple que cela
git commit --amend --author "Author Name <[email protected]>"
, il n'y a pas de ligne ou d'argument unique pour faire de même avec les informations du committer.La solution consiste à (temporairement ou non) modifier vos informations utilisateur, puis à modifier le commit, ce qui mettra le commiteur à jour avec vos informations actuelles:
la source
path\to\repo\.git
. Je ne sais pas encore ce que vous devez faire pour l'effacer totalement. Amends malheureusement (?) Ne semble pas effacer.Nous avons rencontré un problème aujourd'hui où un caractère UTF8 dans un nom d'auteur causait des problèmes sur le serveur de génération, 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, selon les instructions ici: https://help.github.com/articles/setting-your-username-in-git/
Étape 2: exécutez le script bash suivant:
Aperçu rapide: extrayez votre référentiel dans un fichier temporaire, extrayez toutes les branches distantes, exécutez le script qui réécrira l'historique, effectuez une poussée forcée du nouvel état et dites à tous vos collègues de faire un tirage de rebase pour obtenir les modifications.
Nous avons eu du mal à exécuter cela sur OS X, car cela a en quelque sorte gâché les fins de ligne dans les messages de validation, nous avons donc dû le réexécuter sur une machine Linux par la suite.
la source
Votre problème est vraiment courant. Voir " Utiliser 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 mis ce script sur votre chemin, vous pouvez lancer des commandes comme:
Modifier les correspondances d'auteur sur la branche actuelle
Modifiez les correspondances d'auteur et de committer sur <branch> et <branch2>. Passer
-f
à filter-branch pour permettre la réécriture des sauvegardesAfficher les utilisateurs existants sur le référentiel
Au fait, après avoir apporté vos modifications, nettoyez la sauvegarde de la branche de filtre avec: git-backup-clean
la source
Essayez ceci. Il fera la même chose que mentionné ci-dessus, mais de manière interactive.
Référence: https://github.com/majdarbash/git-author-change-script
la source
Je veux également ajouter mon exemple. Je veux créer une fonction bash avec un paramètre donné.
cela fonctionne dans mint-linux-17.3
la source
Si vous êtes le seul utilisateur de ce dépôt ou si vous ne vous souciez pas de le casser pour d'autres utilisateurs, alors oui. Si vous avez poussé ces validations et qu'elles existent là où un autre endroit peut y accéder, alors non, à moins que vous ne vous souciez pas de casser les repos des autres. Le problème est qu'en changeant ces validations, vous générerez de nouveaux SHA qui les traiteront comme des validations différentes. 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 procéder. (Je n'ai pas essayé ça alors YMMV)
la source
refs/replace/
mécanisme.