Comment remplacer le texte à partir de fichiers dans l'historique de git?
J'ai toujours utilisé une interface à base de git client (smartGit) et donc n'ont pas beaucoup d'expérience avec le git de la console.
Cependant, je vais maintenant faire face à la nécessité de remplacer une chaîne de caractères dans tous .les fichiers txt de l'histoire (donc, pas d'effacer le fichier en entier, mais seulement de la substitution d'une chaîne de caractères). J'ai trouvé la commande suivante:
git filter-branch --tree-filter 'git ls-files -z "*.php" |xargs -0 perl -p -i -e "s#(PASSWORD1|PASSWORD2|PASSWORD3)#xXxXxXxXxXx#g"' -- --all
J'ai essayé, et malheureusement remarqué que, bien que le mot de passe ne se changé, tous les fichiers ont été corrompus. Images, etc. seraient tous des corrompus.
Est-il une meilleure façon de le faire que de ne pas corrompre mes fichiers binaires?
Grâce.
EDIT:
Je me suis mélangé avec quelque chose. Le code qui a causé des fichiers binaires pour obtenir corrompu était:
$ git filter-branch --tree-filter "find . -type f -exec sed -i -e 's/originalpassword/newpassword/g' {} \;"
Le code en haut en fait retiré tous les fichiers avec mon mot de passe, assez étrangement.
- Ne résout pas votre problème, mais c'est semblable à une question, j'ai demandé un temps de retour: stackoverflow.com/questions/2225454/...
- En effet, il y a beaucoup de réponses sur la façon de supprimer des fichiers. J'ai besoin de remplacer une chaîne de caractères si.
- Cuadra, veuillez voir mon montage, j'ai utilisé un script différent, mêlé. Peut-être qu'il vous aide à obtenir le bon de commande.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez éviter de toucher les fichiers indésirables en passant
-name "pattern"
àfind
.Cela fonctionne pour moi:
git filter-branch --tree-filter "find . -name '*.php' -type f -exec sed -i -e 's/originalpassword/newpassword/g' {} \;"
Je vous recommande d'utiliser le BFG Repo-Cleaner, plus simple, plus rapide, alternative à
git-filter-branch
spécialement conçu pour la réécriture des fichiers d'historique de Git.Vous devez suivre attentivement ces étapes ici: https://rtyley.github.io/bfg-repo-cleaner/#usage - mais le cœur bits est juste ceci: télécharger le BFG pot d' (nécessite Java 7 ou au-dessus) et exécutez cette commande:
La
replacements.txt
fichier doit contenir tous les substitutions que vous voulez faire, dans un format qui ressemble à ceci (une entrée par ligne - noter les commentaires ne devraient pas être inclus):L'ensemble de votre historique du dépôt seront analysés, et
.php
fichiers (moins de 1 mo) aura les substitutions effectuées: aucune chaîne correspondante (qui n'est pas dans votre dernière commettre) sera remplacé.Divulgation complète: je suis l'auteur de la BFG Repo-Cleaner.
java -jar /C/Users/user/bfg-1.12.12.jar --filter-content-including '*.{php,inc,sql,txt,htm,html,js,css,xml}' --replace-text /w/Dev/\!GIT/CVS_ident_replace.txt /w/Dev/\!GIT/repo
CVS_ident_replace.txt:regex:(//\s*\$Id:).*\$==>$1\$ # Replace CVS Ident
git pull origin master
. Était-ce une erreur? Je devrais avoir faitgit clone
? Parce que, après poussant de nouveau, j'ai remarqué que les remplacements effectués avecbfg
sont partis.J'ai créé un fichier /usr/local/git/findsed.sh , avec le contenu suivant:
J'ai exécuté la commande:
Explication des commandes
Lorsque vous exécutez git filter-branch, cela passe par chaque révision que vous avez déjà commis un par un. --l'arbre-exécution du filtre de la findsed.sh le script à chaque engagé la révision, l'enregistre, puis évolue à la prochaine révision.
La commande find trouve un fichier spécifique ou un ensemble de fichiers et exécute (-exec) à la dsi de l'éditeur sur ce fichier. sed est une commande qui prend la regex après s/et la remplace par la chaîne entre /et /g (vide dans mon exemple). {} est une référence pour le chemin d'accès des fichiers qui a été donné par la commande find. Le chemin d'accès au fichier est alimenté à sed, de sorte que sed sait sur quoi travailler. \; se termine juste au -exec commande.
Séparant le script shell et commande en deux pièces permet pour le moins de complications quand il s'agit de citations " ou "".
Particularités
J'ai mis en œuvre avec succès sur un mac, et apparemment sed est un particulier (de plus?) version sur mac. Cette matière, comme c'est parfois se comporte différemment. Assurez-vous de ne sed-i " ou bien, il était l'ajout d'un "e" à la fin des fichiers, en pensant que ce était ce que je voulais au nom de mes fichiers de sauvegarde. -j'affirme ne pas faire de sauvegarde des fichiers, il suffit d'éditer les fichiers en place et aucun fichier de sauvegarde nécessaires.
Spécifier l'option-name 'filename.sh' m'a aidé à éviter un autre problème que je ne pouvais pas résoudre. Il y avait un autre fichier .sh et que le fichier se termine sans un caractère de saut de ligne. sed pour une raison quelconque, ajoutez un caractère de saut de ligne à la fin, malgré le 's/bla/bla/g' ne correspondant à rien dans ce fichier. Ainsi, au lieu d'essayer de comprendre la question, je viens de le trouver à ignorer tous les autres fichiers.
Commandes supplémentaires que le travail
En outre, j'ai trouvé que ces commandes fonctionnent dans le findsed.sh fichier (une seule commande à la fois, pas le de plusieurs, afin de commentaire # les autres):
Profitez-en!
Pourrait être une coquille problème d'expansion. Si filter-branch est en train de perdre les guillemets autour de
"*.php"
par le temps, elle évalue la commande, elle peut être en expansion à rien, doncgit ls-files -z
liste de tous les fichiers.Vous pouvez vérifier le filtre-direction de la source ou de l'essai de différentes citant des trucs, mais ce que je voudrais faire, c'est juste une seule ligne de script shell qui fait votre arbre-filtre et passer ce script à la place.
--tree-filter '...'
droit maintenant.Avec Git 2.24 (T4 2019),
git filter-branch
(et BFG) est obsolète.L'équivalent serait, à l'aide de
newren/git-filtre-repo
, et son exemple de l'article:avec
expressions.txt
: