Question

Je voudrais mettre un projet Git sur GitHub, mais il contient certains fichiers avec des données sensibles (noms d'utilisateur et les mots de passe, comme /config/deploy.rb Capistrano).

Je sais que je peux ajouter ces noms à .gitignore , mais cela ne supprimerait pas leur histoire au sein de Git.

Je ne veux pas aussi recommencer en supprimant le répertoire /.git.

Y at-il un moyen de supprimer tous traces d'un fichier particulier dans l'histoire de votre Git?

Était-ce utile?

La solution

Pour toutes fins pratiques, premier chose que vous devriez être inquiet au sujet de influenceront votre PASSWORDS! On ne sait pas à partir de votre question de savoir si votre dépôt git est entièrement locale ou si vous disposez d'un dépôt distant ailleurs encore; si elle est éloignée et non sécurisé des autres que vous avez un problème. Si quelqu'un a cloné ce dépôt avant de résoudre ce problème, ils ont une copie de vos mots de passe sur leur machine locale, et il n'y a aucun moyen que vous pouvez les forcer à mettre à jour votre version « fixe » avec elle disparu de l'histoire. La seule chose sûre que vous pouvez faire est de changer le mot de passe à autre chose partout où vous l'avez utilisé.


Avec cela du chemin, voici comment le résoudre. GitHub a répondu exactement à cette question comme une FAQ :

Remarque pour les utilisateurs Windows : utilisez des guillemets doubles ( ") au lieu de singles dans cette commande

git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force

Gardez à l'esprit qu'une fois que vous avez poussé ce code à un dépôt distant comme GitHub et d'autres ont cloné ce dépôt à distance, vous êtes maintenant dans une situation où vous réécrire l'histoire. Lorsque d'autres tentent déroulez vos derniers changements après, ils reçoivent un message indiquant que les changements ne peuvent pas être appliquées parce que ce n'est pas une avance rapide.

Pour résoudre ce problème, ils doivent soit supprimer leur référentiel existant et re-clone, ou suivez les instructions sous la rubrique « RECUPERATION DE AMONT REBASE » dans git-rebase manpage.


Dans l'avenir, si vous vous engagez accidentellement quelques changements avec des informations sensibles, mais vous remarquez avant pousser à un dépôt distant, il y a quelques correctifs plus faciles. Si vous vous engagez dernier est celui d'ajouter les informations sensibles, vous pouvez simplement supprimer les informations sensibles, puis exécutez:

git commit -a --amend

qui modifiera la précédente livraison avec toutes les nouvelles modifications apportées, y compris le transfert de fichiers entiers fait avec un git rm. Si les changements sont encore dans l'histoire, mais pas encore poussé à un dépôt distant, vous pouvez faire un rebasage interactif:

git rebase -i origin/master

Cela ouvre un éditeur avec les commits que vous avez fait depuis votre dernier ancêtre commun avec le dépôt distant. Change « pick » à « modifier » sur toutes les lignes représentant un commettras avec des informations sensibles et sauvegarder et quitter. Git marcher à travers les changements, et vous laisser à un endroit où vous pouvez:

$EDITOR file-to-fix
git commit -a --amend
git rebase --continue

Pour chaque changement des informations sensibles. Finalement, vous finirez par revenir sur votre branche, et vous pouvez en toute sécurité pousser les nouveaux changements.

Autres conseils

Changer vos mots de passe est une bonne idée, mais pour le processus de suppression de mot de passe de l'histoire de votre pension, je vous recommande le BFG repo-Cleaner, plus rapide, plus simple alternative à explicitement conçu pour git-filter-branch la suppression des données privées de prises en pension Git.

Créez un fichier répertoriant les mots de passe private.txt, etc, que vous souhaitez supprimer (une entrée par ligne), puis exécutez la commande suivante:

$ java -jar bfg.jar  --replace-text private.txt  my-repo.git

Tous les fichiers sous une taille de seuil (1 Mo par défaut) dans l'histoire de votre repo seront scannés, et une chaîne de correspondance (ce n'est pas dans votre dernière commit) seront remplacés par la chaîne " *** RETIRÉ *** ». Vous pouvez ensuite utiliser pour nettoyer l'écart git gc les données mortes:

$ git gc --prune=now --aggressive

Le BFG est généralement plus rapide que 10-50x en cours d'exécution et les options <=> sont simplifiées et adaptées autour de ces deux communes cas d'utilisation:

  • Suppression Crazy Big Files
  • Suppression des mots de passe, informations d'identification et autres données privées

La divulgation complète:. Je suis l'auteur du BFG Repo-Cleaner

Je recommande ce script par David Underhill, a travaillé comme un charme pour moi.

Il ajoute ces commandes dans le filtre-branche de plus natacado pour nettoyer le désordre, il laisse derrière lui:

rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune

script complet (tous les crédits à David Underhill)

#!/bin/bash
set -o errexit

# Author: David Underhill
# Script to permanently delete files/folders from your git repository.  To use 
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2

if [ $# -eq 0 ]; then
    exit 0
fi

# make sure we're at the root of git repo
if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter \
"git rm -rf --cached --ignore-unmatch $files" HEAD

# remove the temporary history git-filter-branch
# otherwise leaves behind for a long time
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune

Les deux dernières commandes peuvent fonctionner mieux si changé à ce qui suit:

git reflog expire --expire=now --all && \
git gc --aggressive --prune=now

Si vous avez poussé à GitHub, force de poussée ne suffit pas, supprimer le référentiel ou contactez le support

Même si vous forcez appuyer sur un seconde après, il ne suffit pas, comme expliqué ci-dessous.

Les cours de l'action ne sont valides:

  • est ce que divulgué une information d'identification variable comme un mot de passe?

    • oui: modifier vos mots de passe immédiatement, et envisager d'utiliser plusieurs clés OAuth et API
    • !
    • non (photos nues):

      • ça peut vous faire si tous les problèmes dans le référentiel se nuked?

        • pas: supprimer le référentiel
        • oui:

          • support de contact
          • si la fuite est très critique pour vous, au point que vous êtes prêt à obtenir un temps d'arrêt référentiel pour la rendre moins susceptibles de fuir, rendent privé pendant que vous attendez le soutien GitHub de vous répondre

Force poussant une seconde plus tard ne suffit pas parce que:

Si vous supprimez le dépôt au lieu de forcer juste pousser cependant, engage ne disparaissent même de l'API immédiatement et donner 404, par exemple https://api.github.com/repos/cirosantilli/ test ballants-delete / engage / 8c08448b5fbf0f891696819f3b2b2d653f7a3824 Cela fonctionne même si vous recréez un autre référentiel avec le même nom.

Pour tester cela, je l'ai créé une prise en pension: https://github.com/cirosantilli/ -ballants essai et a fait:

git init
git remote add origin git@github.com:cirosantilli/test-dangling.git

touch a
git add .
git commit -m 0
git push

touch b
git add .
git commit -m 1
git push

touch c
git rm b
git add .
git commit --amend --no-edit
git push -f

Voir aussi: Comment supprimer un ballants commit de GitHub

Pour être clair: La réponse acceptée est correcte. Essayez d'abord. Cependant, il peut être inutilement complexe pour certains cas d'utilisation, en particulier si vous rencontrez des erreurs désagréables telles que "fatale: mauvaise révision --prune vide., Ou vraiment ne se soucient pas de l'histoire de votre repo

Une autre solution serait:

  1. cd à la branche de base de projet
  2. Supprimer le code sensible / fichier
  3. rm -rf .git / # Retirer toutes les informations de git votre code
  4. Aller à github et supprimer votre répertoire
  5. Suivez ce guide pour pousser votre code à un nouveau référentiel comme vous le feriez normalement - https://help.github.com/articles / ajoutant-un à-projet-existant github utilisant-la-commande en ligne /

Ce sera bien sûr supprimer toutes les branches commettras d'histoire, et les questions à la fois votre repo github et votre git local. Si cela est inacceptable, vous devez utiliser une autre approche.

Appelons cela l'option nucléaire.

Voici ma solution dans les fenêtres

  

--tree-filtre filtre de dérivation git "rm -f 'filedir / filename'" HEAD

     

git pousser --force

Assurez-vous que le chemin est correct sinon il ne fonctionnera pas

J'espère que cela aide

Utilisation filtre-branche :

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all

git push origin *branch_name* -f

Vous pouvez utiliser git forget-blob.

L'utilisation est assez simple git forget-blob file-to-forget. Vous pouvez obtenir plus d'informations ici

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

Il disparaîtra de tous les commits dans votre histoire, reflog, étiquettes, etc.

Je courir dans le même problème chaque maintenant et puis, et chaque fois que je dois revenir à ce poste et d'autres, c'est pourquoi j'automatisé le processus.

Crédits aux contributeurs de Stack Overflow qui m'a permis de mettre cela ensemble

J'ai dû faire quelques fois à jour. Notez que cela ne fonctionne que sur 1 fichier à la fois.

  1. Obtenir une liste de tous les commits qui ont modifié un fichier. L'un en bas sera le premier commit:

    git log --pretty=oneline --branches -- pathToFile

  2. Pour supprimer le fichier de l'histoire utiliser la première commettras SHA1 et le chemin du fichier de la commande précédente, et les remplir dans cette commande:

    git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..

Alors, il ressemble à ceci:

git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
  

Supprimer le cache pour le fichier de suivi git et ajouter ce fichier à la liste .gitignore

Dans mon projet, j'avais android admob_keys.xml sous forme de fichier XML séparé app / src / main / res / valeurs / dossier . Pour supprimer ce fichier sensible ci-dessous je scénario et a parfaitement fonctionné.

git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch  app/src/main/res/values/admob_keys.xml' \
--prune-empty --tag-name-filter cat -- --all
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top