¿Cuál es una buena estrategia para mantener las notebooks IPython bajo control de versiones?
El formato de la notebook es bastante adecuado para el control de versiones: si uno quiere controlar la versión de la notebook y las salidas, entonces esto funciona bastante bien. La molestia se produce cuando uno solo quiere controlar la entrada de la versión, excluyendo las salidas de celda (también conocidas como "productos de compilación") que pueden ser grandes bloques binarios, especialmente para películas y tramas. En particular, estoy tratando de encontrar un buen flujo de trabajo que:
- me permite elegir entre incluir o excluir resultados,
- me impide comprometer la salida accidentalmente si no la quiero,
- me permite mantener la salida en mi versión local,
- me permite ver cuándo tengo cambios en las entradas usando mi sistema de control de versiones (es decir, si solo controlo las entradas de las versiones pero mi archivo local tiene salidas, entonces me gustaría poder ver si las entradas han cambiado (lo que requiere una confirmación El uso del comando de control de versión siempre registrará una diferencia, ya que el archivo local tiene salidas).
- me permite actualizar mi cuaderno de trabajo (que contiene la salida) desde un cuaderno limpio actualizado. (actualizar)
Como se mencionó, si elegí incluir las salidas (lo cual es deseable cuando uso nbviewer, por ejemplo), entonces todo está bien. El problema es cuando no quiero controlar la versión de la salida. Hay algunas herramientas y scripts para eliminar la salida del cuaderno, pero con frecuencia encuentro los siguientes problemas:
- Accidentalmente confirmo una versión con la salida, contaminando así mi repositorio.
- Borro la salida para usar el control de versiones, pero realmente prefiero mantener la salida en mi copia local (a veces lleva un tiempo reproducirla, por ejemplo).
- Algunas de las secuencias de comandos que eliminan la salida cambian el formato ligeramente en comparación con la
Cell/All Output/Clear
opción del menú, creando así un ruido no deseado en las diferencias. Esto se resuelve con algunas de las respuestas. - Al realizar cambios en una versión limpia del archivo, necesito encontrar alguna forma de incorporar esos cambios en mi cuaderno de trabajo sin tener que volver a ejecutar todo. (actualizar)
He considerado varias opciones que analizaré a continuación, pero aún no he encontrado una buena solución integral. Una solución completa puede requerir algunos cambios en IPython, o puede depender de algunos scripts externos simples. Actualmente uso mercurial , pero me gustaría una solución que también funcione con git : una solución ideal sería agnóstico de control de versiones.
Este problema se ha discutido muchas veces, pero no existe una solución definitiva o clara desde la perspectiva del usuario. La respuesta a esta pregunta debería proporcionar la estrategia definitiva. Está bien si requiere una versión reciente (incluso de desarrollo) de IPython o una extensión fácil de instalar.
Actualización: He estado jugando con mi versión de cuaderno modificada que opcionalmente guarda una .clean
versión con cada guardado usando las sugerencias de Gregory Crosswhite . Esto satisface la mayoría de mis limitaciones pero deja lo siguiente sin resolver:
- Esta todavía no es una solución estándar (requiere una modificación de la fuente de ipython. ¿Hay alguna forma de lograr este comportamiento con una extensión simple? Necesita algún tipo de enlace de guardado.
- Un problema que tengo con el flujo de trabajo actual es sacar los cambios. Estos entrarán en el
.clean
archivo y luego deberán integrarse de alguna manera en mi versión de trabajo. (Por supuesto, siempre puedo volver a ejecutar el cuaderno, pero esto puede ser un problema, especialmente si algunos de los resultados dependen de cálculos largos, cálculos paralelos, etc.) Todavía no tengo una buena idea sobre cómo resolver esto. . Quizás un flujo de trabajo que implique una extensión como ipycache podría funcionar, pero eso parece un poco demasiado complicado.
Notas
Eliminar (pelar) la salida
- Cuando la computadora portátil se está ejecutando, se puede usar la
Cell/All Output/Clear
opción de menú para eliminar la salida. - Hay algunas secuencias de comandos para eliminar la salida, como la secuencia de comandos nbstripout.py que elimina la salida, pero no produce la misma salida que con la interfaz de la notebook. Esto finalmente se incluyó en el repositorio de ipython / nbconvert , pero se cerró indicando que los cambios ahora se incluyen en ipython / ipython , pero la funcionalidad correspondiente parece no haberse incluido todavía. (actualización) Dicho esto, la solución de Gregory Crosswhite muestra que esto es bastante fácil de hacer, incluso sin invocar ipython / nbconvert, por lo que este enfoque probablemente sea viable si se puede conectar correctamente. (Sin embargo, adjuntarlo a cada sistema de control de versiones no parece una buena idea, esto de alguna manera debería engancharse en el mecanismo del portátil).
Grupos de noticias
Cuestiones
- 977: Solicitudes de funciones de notebook (Abierto) .
- 1280: Borrar todo al guardar la opción (Abrir) . (Sigue de esta discusión ).
- 3295: cuadernos autoexportados: solo exporta celdas marcadas explícitamente (Cerrado) . Resuelto por la extensión 11 Agregue writeandexecute magic (Merged) .
Solicitudes de extracción
- 1621: borrar en [] números de solicitud en "Borrar toda la salida" (Fusionada) . (Ver también 2519 (Combinado) .)
- 1563: mejoras de clear_output (fusionadas) .
- 3065: diferencia de capacidad de los cuadernos (Cerrado) .
- 3291: agregue la opción de omitir celdas de salida al guardar. (Cerrado) . Esto parece extremadamente relevante, sin embargo, se cerró con la sugerencia de usar un filtro "limpiar / manchar". Una pregunta relevante, ¿ qué puede usar si desea eliminar la salida antes de ejecutar git diff? Parece no haber sido respondido.
- 3312: WIP: Ganchos para guardar portátiles (Cerrado) .
- 3747: ipynb -> transformador ipynb (cerrado) . Esto se reformula en 4175 .
- 4175: nbconvert: base de exportadores Jinjaless (fusionada) .
- 142: Use STDIN en nbstripout si no se proporciona ninguna entrada (Abrir) .
--script
opción, pero se ha eliminado. Estoy esperando hasta que se implementen los ganchos posteriores al guardado ( que están planificados ), momento en el que creo que podré proporcionar una solución aceptable que combine varias de las técnicas.