34 votes

Git: ignorer les fichiers pour le dépôt public, mais pas pour les fichiers privés

Je suis le déploiement d'une application Rails sur Heroku (pour l'instant) via git, et voudrais aussi avoir une version publique pour les personnes à regarder. Certains fichiers sont sensibles, et ne doit être engagé et poussé dans la "heroku" de la branche, mais pas le "public" de la branche. Quelle est la meilleure façon d'aller à ce sujet?

(Je ne sais sur Heroku de variables de configuration, qui est grand comme une solution temporaire, mais pas de plaisir si et quand j'ai besoin de passer les hôtes.)

Les deux branches n'ont pas besoin d'être synchronisés à tous les temps - je suis d'accord avec périodiquement la fusion du "maître" dans le "public" de la branche et en le poussant vers github séparément.

J'ai essayé différentes choses:

  • séparer .gitignore fichiers et un "nous" stratégie de fusion - cela ne fonctionnait pas, au premier abord, et après avoir jouer avec elle pour un moment, j'ai décidé que c'était trop compliqué pour que je pourrait réaliser une tâche apparemment simple

  • en utilisant une coutume exclude le fichier, et l'adjonction d' .git/config... cela ne fonctionne tout simplement pas:

.git/config

[branch "public"]
  excludesfile = +info/exclude_from_public

Quel est le meilleur moyen d'avoir un public et privé référentiel partagent le même code, mais ignorer les fichiers sensibles dans le dépôt public?

Vous pouvez supposer qu'aucun code n'a été commise ou poussé, c'est un fraîchement initialisé référentiel.

(Cette question a été posée dans des formes diverses, mais aucune des réponses n'étaient straight-forward ou les réponses semblaient vraiment hacky. Je suis juste ici pour vous demander ce de manière très simple, et j'espère recevoir une réponse très simple.)

16voto

Timothy Meade Points 1028

Je seconde le sous-module de réponse, mais essayer d'apporter quelques précisions. Tout d'abord, git ne traite pas les fichiers, mais avec s'engage. Il n'y a aucun moyen de filtrer les fichiers ou les chemins d'accès dans une branche, car une branche est vraiment un pointeur vers un commit. Lorsque vous exclure ou de les ignorer, vous êtes juste de garder les fichiers d'être ajouté à votre dépôt. aucun des 'dossiers sensibles dossiers sont encore dans le référentiel, juste dans votre répertoire de travail.

Le sous-module est juste une référence à un autre référentiel stockées dans le référentiel, et s'engager à ce que que l'extrait du référentiel est suivi. vous pouvez dire la mise à jour à l'aide de

git submodule update --recursive sensitive-files

Afin de simplifier les choses, vous ne pouvez commettre des liens symboliques dans le bon endroit pointant vers le sous-module de chemin.

ln -sf sensitive-files/shadow passwd

Puis ajouter le lien comme vous le feriez pour tout autre fichier..

Rappelez-vous le sous-module est juste un extrait dépôt git, vous pouvez facilement restreindre l'accès à ce référentiel proprement dit et de faire le principal public.

Mise à jour:

Désolé j'ai raté la notification, si vous travaillez toujours sur cette.

Vous pouvez avoir plusieurs liens symboliques dans votre repository privé de référencement sur le repository privé (sous-module) qui est extrait dans un sous-répertoire.Chacune des bases de données ou que ce soit utilisé par les Rails exemple pourrait être un lien symbolique dans le privé sous-répertoire.

Aussi, vous ne' t besoin d'une distance pointant vers le repository privé, seulement une inscription dans les .gitmodules fichier qui est automatiquement maintenue par git sous-module. Vous auriez encore besoin de protéger le repository privé afin que seuls vos Heroku instance peuvent y avoir accès. Pour que je vous suggérons d'installer gitosis sur un serveur si vous le pouvez ou utiliser un autre git solution d'hébergement. Ajouter la clé ssh publique correspondant à vos instances de la clé privée à la liste des utilisateurs autorisés. (Je ne suis pas familier avec la façon de faire dans Heroku.)

Lorsque vous poussez vos changements de heroku, il devrait récursive télécharger tous les submodules mentionnées dans le référentiel.

7voto

seanhodges Points 8005

Vous pouvez créer un pre-commit hook dans votre local repo, ici vous pouvez écrire un script pour vérifier les extraits de la branche et de supprimer le contenu litigieux fichiers s'ils sont présents, avant que la validation est traitée. Cela évite les fichiers jamais enregistrée dans l'historique de Git de la mauvaise branche.

#!/bin/bash
current_branch="$(git branch | sed -e 's/^*//')"
if [ $current_branch != "heroku" ]; then 
    // Delete sensitive files before commit
    rm -f dir1/dir2/exclude_from_public
    rm -f dir1/dir2/exclude_from_public_also
fi
exit 0

Sinon, le script pourrait il suffit de cocher les fichiers et de retourner le code de sortie "1", vous informant que la livraison ne peut pas continuer car il contient des fichiers sensibles.

Le problème, c'est que vous aurez besoin de ce script pour n'importe qui qui travaille sur les "privilégiés" heroku de la branche, et l'avoir toujours inclus dans votre propre repo.

Idéalement vous avez cette case à fait côté serveur ainsi; mais, malheureusement, GitHub propose une Web variante de l'après-recevoir crochet, donc à moins que vous ne vous êtes propre repo accueillir cette démarche ne peut être effectuée localement.

2voto

Greg Hewgill Points 356191

Une façon de le faire serait de placer vos fichiers privés dans un sous - module et de vous référer à ce module à partir de votre référentiel public. (Alternativement, vous pouvez placer vos fichiers publics dans un sous-module et vous référer à ce référentiel à partir de votre référentiel privé.)

2voto

Dan Cruz Points 7016

Voici quelques autres StackOverflow questions et réponses le long de la ligne de "comment voulez-vous faire une fusion tout en ignorant certains fichiers":

Le plus simple je pense, est d'utiliser un alias'ed fusion qui permettra de supprimer les fichiers privés avant de faire la fusion s'engager. Cela ne peut fonctionner que si vous êtes prêt à vivre avec des non-rapide-vers l'avant les fusions. Voici l' alias:

git config alias.merge-master-exclude-private '!git merge --no-commit --no-ff master && (git diff --name-only HEAD..master | grep -f private_files | while read f; do git reset HEAD -- "$f"; rm -f "$f"; done; git commit -m "Merge master, excluding private files.")'

Ensuite, éditez le private_files le fichier et ajouter des modèles de fichier qui sont privés; par exemple secret_file.*$. Vous pouvez remplacer private_files dans l'alias avec "$(git rev-parse --show-toplevel)"/private_files lire private_files à partir du répertoire de niveau supérieur.

Utiliser git merge-master-exclude-private de réaliser la fusion. Cela permettra d'exécuter un non-avance rapide, de fusion, mais sans s'engager, de trouver les fichiers qui correspondent à des modèles dans l' private_files fichier reset de l'index de tous les fichiers privés trouvé, retirez privé fichiers dans le répertoire de travail, puis les valider. Cela devrait gérer les fichiers qui ont des espaces dans leur nom.

Si vous ne voulez pas faire le commit, vous donnant une chance de modifier le message de commit, retirez - -m "Merge master, excluding private files." à partir de l'alias.

2voto

Sidnicious Points 15187

Un gars du nom de David Albert a écrit un outil appelé Junk pour résoudre presque exactement ce problème. Il permet aux fichiers d'un référentiel séparé "tiroir indésirable" de vivre avec ceux de votre référentiel principal.

Les fichiers privés auront des validations distinctes des fichiers publics, mais cela pourrait faire l'affaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X