Quelle est une bonne stratégie pour garder IPython des carnets de notes sous contrôle de version ?
Le format du carnet de notes se prête bien au contrôle de version : si l'on veut contrôler la version du carnet de notes et des résultats, cela fonctionne très bien. L'ennui vient lorsque l'on veut seulement contrôler la version de l'entrée, à l'exclusion des sorties de la cellule (alias "produits de construction") qui peuvent être de gros blobs binaires, en particulier pour les films et les intrigues. En particulier, j'essaie de trouver un bon flux de travail qui :
- me permet de choisir entre inclure ou exclure la sortie,
- m'empêche de commettre accidentellement des sorties si je ne le souhaite pas,
- me permet de conserver la sortie dans ma version locale,
- me permet de voir quand j'ai des changements dans les entrées en utilisant mon système de contrôle de version (i.e. si je ne contrôle que les entrées mais que mon fichier local a des sorties, alors j'aimerais pouvoir voir si les entrées ont changé (ce qui nécessite un commit). L'utilisation de la commande d'état du contrôle de version enregistrera toujours une différence puisque le fichier local a des sorties).
- me permet de mettre à jour mon cahier de travail (qui contient la sortie) à partir d'un cahier propre mis à jour. (mise à jour)
Comme mentionné, si je choisis d'inclure les sorties (ce qui est souhaitable lorsque l'on utilise des nbviewer par exemple), alors tout va bien. Le problème est que lorsque je ne pas vous voulez contrôler la version de la sortie. Il existe quelques outils et scripts pour dépouiller la sortie du carnet de notes, mais je rencontre fréquemment les problèmes suivants :
- J'ai accidentellement commit une version avec la sortie, polluant ainsi mon référentiel.
- J'efface la sortie pour utiliser le contrôle de version, mais je préférerais vraiment garder la sortie dans ma copie locale (il faut parfois un certain temps pour reproduire par exemple).
- Certains des scripts qui dépouillent la sortie modifient légèrement le format par rapport à l'option
Cell/All Output/Clear
ce qui crée un bruit indésirable dans les diffs. Ce problème est résolu par certaines des réponses. - Lorsque j'apporte des modifications à une version propre du fichier, je dois trouver un moyen d'incorporer ces modifications dans mon carnet de travail sans avoir à tout réexécuter. (mise à jour)
J'ai envisagé plusieurs options dont je parlerai ci-dessous, mais je n'ai pas encore trouvé de bonne solution globale. Une solution complète pourrait nécessiter quelques changements dans IPython, ou pourrait s'appuyer sur quelques simples scripts externes. J'utilise actuellement mercuriel mais j'aimerais une solution qui fonctionne aussi avec git Une solution idéale serait agnostique au contrôle de version.
Cette question a été discutée à de nombreuses reprises, mais il n'existe pas de solution définitive ou claire du point de vue de l'utilisateur. La réponse à cette question devrait fournir la stratégie définitive. Ce n'est pas grave si cela nécessite une version récente (même de développement) de IPython ou une extension facile à installer.
Mise à jour : J'ai joué avec mon carnet de notes modifié qui enregistre éventuellement une .clean
avec chaque sauvegarde utilisant Les suggestions de Gregory Crosswhite . Cela satisfait la plupart de mes contraintes mais laisse les suivantes non résolues :
- Cette solution n'est pas encore standard (elle nécessite une modification du code source d'ipython). Existe-t-il un moyen d'obtenir ce comportement avec une simple extension ? Il faut une sorte de crochet on-save.
- Un problème que je rencontre avec le flux de travail actuel est de tirer les modifications. Ceux-ci arrivent dans le
.clean
et doivent ensuite être intégrés d'une manière ou d'une autre dans ma version de travail. (Bien sûr, je peux toujours réexécuter le notebook, mais cela peut être pénible, surtout si certains des résultats dépendent de longs calculs, de calculs en parallèle, etc. Peut-être qu'un flux de travail impliquant une extension comme ipycache pourrait fonctionner, mais cela semble un peu trop compliqué.
Notes
Retrait (stripping) Sortie
- Lorsque le notebook est en cours d'exécution, on peut utiliser la fonction
Cell/All Output/Clear
pour supprimer la sortie. - Il existe quelques scripts pour supprimer la sortie, comme le scripts. nbstripout.py qui supprime la sortie, mais ne produit pas la même sortie qu'en utilisant l'interface du notebook. Ceci a finalement été inclus dans la version ipython/nbconvert mais il a été clôturé en indiquant que les modifications sont maintenant incluses dans le répertoire de l'entreprise. ipython/ipython mais la fonctionnalité correspondante ne semble pas encore avoir été incluse. (mise à jour) Ceci étant dit, La solution de Gregory Crosswhite montre que cela est assez facile à faire, même sans invoquer ipython/nbconvert Cette approche est donc probablement réalisable si elle peut être connectée correctement. (L'attacher à chaque système de contrôle de version, cependant, ne semble pas être une bonne idée - cela devrait d'une manière ou d'une autre s'accrocher au mécanisme du carnet de notes).
Groupes de discussion
Questions
- 977 : Demandes de fonctionnalités pour l'ordinateur portable (Ouvert) .
- 1280 : Option "Effacer tout" lors de la sauvegarde (Ouvrir) . (Découle de cette discussion .)
- 3295 : carnets de notes auto-exportés : exporter uniquement les cellules explicitement marquées (Closed) . Résolu par extension 11 Ajouter la magie writeandexecute (Fusionné) .
Pull Requests
- 1621 : effacer les numéros d'invite In[] lors de "Clear All Output" (fusionné) . (Voir aussi 2519 (fusionné) .)
- 1563 : améliorations de clear_output (Fusionné) .
- 3065 : diff-abilité des cahiers (Closed) .
- 3291 : Ajouter l'option de sauter les cellules de sortie lors de la sauvegarde. (Fermé) . Cette question semble extrêmement pertinente, mais elle a été classée avec la suggestion d'utiliser un filtre "propre/salissant". Une question pertinente Que pouvez-vous utiliser si vous voulez supprimer la sortie avant de lancer git diff ? ne semble pas avoir reçu de réponse.
- 3312 : WIP : Crochets de sauvegarde de l'ordinateur portable (Fermé) .
- 3747 : transformateur ipynb -> ipynb (Fermé) . Ce dernier est rebasé en 4175 .
- 4175 : nbconvert : Base exportatrice Jinjaless (Fusionné) .
- 142 : Utiliser STDIN dans nbstripout si aucune entrée n'est donnée (Open) .
0 votes
Cela semble être une bonne chose à ajouter en tant que problème sur le site Web de la Commission européenne. github.com/ipython/ipython ou soumettez une demande de retrait qui vous aide à atteindre cet objectif.
0 votes
Comme vous pouvez le constater, il existe déjà une pléthore de relations publiques et de questions relatives à cet objectif. Une fois ceux-ci résolus (à savoir PR 4175 ), alors une réponse définitive devrait être disponible, mais elle impliquera probablement des scripts supplémentaires en dehors d'IPython (des hooks git ou hg par exemple). Par conséquent, je ne pense pas qu'il y aura quoi que ce soit à gagner en ajoutant un nouveau PR ou problème.
0 votes
Oui, leur développement progresse rapidement et régulièrement chaque jour. Mais les développeurs sont de bonnes personnes (et ont probablement lu ce message). Je sais que je veux un flux de travail facile pour travailler avec git.
0 votes
@Kyle J'ai également mentionné ce point sur la liste de diffusion. Il semble que PR 4175 sera résolu en quelques heures/jours, donc je m'attends à ce que ça aille vite.
4 votes
Une fois que vous avez un script fonctionnel pour supprimer la sortie, vous pouvez utiliser un filtre "clean" de Git pour l'appliquer automatiquement avant de commiter (voir les filtres clean/smudge).
0 votes
Toutes les réponses sont contenues dans la question ! @mforbes, c'est bien de répondre à votre propre question, mais c'est mieux si vous pouvez mettre les réponses dans une réponse.
1 votes
@foobarbecue La question contient des solutions de rechange insatisfaisantes : chacune d'entre elles présente au moins une limitation. Maintenant que le PR 4175 a été fusionné, une solution complète peut probablement être formulée, mais cela reste à faire. Dès que j'aurai un peu de temps, je le ferai (en tant que réponse) si quelqu'un d'autre ne fournit pas une solution satisfaisante entre-temps.
0 votes
C'est juste. J'ai hâte de connaître la solution, je vais probablement l'utiliser.
0 votes
Une autre solution partielle : un filtre pour git qui affiche des différences plus propres, mais qui commet toujours les carnets de notes actuels entiers et non modifiés : gist.github.com/takluyver/bc8f3275c7d34abb68bf
0 votes
Très bonne question, mais je ne vois pas de réponse acceptée. Quelles réponses avez-vous essayées ? Y a-t-il une solution recommandée ?
1 votes
@saroele Je n'ai pas encore trouvé de solution recommandée : J'allais opter pour le
--script
mais cette option a été supprimée. J'attends que les crochets post-save soient implémentés ( qui sont prévues ), et je pense alors être en mesure de fournir une solution acceptable combinant plusieurs des techniques.0 votes
Il semble qu'IPython se rapproche. Une fois que PR 6896 est acceptée, alors nous devrions être en mesure de résoudre cette question grâce à des crochets pré et post-sauvegarde.
1 votes
@mforbes On dirait que ce PR a été fusionné quelques jours après votre commentaire. Pourriez-vous, ou quelqu'un de plus compétent
1 votes
@kobejohn : Je viens d'ajouter une réponse.
0 votes
La meilleure solution n'est-elle pas d'envoyer un PR à github pour modifier l'outil de comparaison afin qu'il prenne en compte les différences des blocs-notes et qu'il n'affiche que la différence des cellules d'entrée ? Ainsi, la sortie est toujours enregistrée et rendue sur GitHub, ce qui est une fonctionnalité très utile des notebooks.
1 votes
En rapport avec stackoverflow.com/questions/28908319 .