Qual é uma boa estratégia para manter os notebooks IPython sob controle de versão?
O formato do notebook é bastante acessível para o controle de versão: se alguém deseja controlar o notebook e as saídas, ele funciona muito bem. O aborrecimento ocorre quando se quer apenas controlar a versão da entrada, excluindo as saídas de célula (também conhecidas como "produtos de construção") que podem ser grandes bolhas binárias, especialmente para filmes e plotagens. Em particular, estou tentando encontrar um bom fluxo de trabalho que:
- permite escolher entre incluir ou excluir a saída,
- me impede de confirmar acidentalmente a saída, se eu não a quiser,
- me permite manter a saída na minha versão local,
- permite que eu veja quando tenho alterações nas entradas usando meu sistema de controle de versão (ou seja, se eu controlo apenas as entradas, mas meu arquivo local tem saídas, gostaria de poder ver se as entradas foram alteradas (exigindo uma confirmação O uso do comando status do controle de versão sempre registra uma diferença, pois o arquivo local possui saídas.)
- permite atualizar meu notebook de trabalho (que contém a saída) de um notebook limpo e atualizado. (atualizar)
Como mencionado, se eu optar por incluir as saídas (o que é desejável ao usar o nbviewer, por exemplo), tudo está bem. O problema é quando eu não quero controlar a versão da saída. Existem algumas ferramentas e scripts para eliminar a saída do notebook, mas frequentemente encontro os seguintes problemas:
- Eu acidentalmente confirmo uma versão com a saída, poluindo assim meu repositório.
- Limpo a saída para usar o controle de versão, mas realmente prefiro manter a saída na minha cópia local (às vezes leva um tempo para reproduzir, por exemplo).
- Alguns dos scripts que retiram a saída alteram ligeiramente o formato em comparação com a
Cell/All Output/Clear
opção de menu, criando assim ruídos indesejados nos diffs. Isso é resolvido por algumas das respostas. - Ao puxar alterações para uma versão limpa do arquivo, preciso encontrar uma maneira de incorporar essas alterações no meu notebook de trabalho sem precisar executar novamente tudo. (atualizar)
Eu considerei várias opções que discutirei abaixo, mas ainda não encontrei uma boa solução abrangente. Uma solução completa pode exigir algumas alterações no IPython ou depender de alguns scripts externos simples. Atualmente, uso mercurial , mas gostaria de uma solução que também funcione com o git : uma solução ideal seria independente do controle de versão.
Esse problema foi discutido várias vezes, mas não há uma solução definitiva ou clara da perspectiva do usuário. A resposta a esta pergunta deve fornecer a estratégia definitiva. Não há problema em exigir uma versão recente (mesmo em desenvolvimento) do IPython ou uma extensão facilmente instalada.
Atualização: Eu brinquei com a versão modificada do meu notebook, que opcionalmente salva uma .clean
versão a cada salvamento, usando as sugestões de Gregory Crosswhite . Isso satisfaz a maioria das minhas restrições, mas deixa o seguinte não resolvido:
- Essa ainda não é uma solução padrão (requer uma modificação da fonte ipython. Existe uma maneira de obter esse comportamento com uma extensão simples? Precisa de algum tipo de gancho para salvar.
- Um problema que tenho no fluxo de trabalho atual está provocando alterações. Eles entrarão no
.clean
arquivo e precisam ser integrados de alguma forma à minha versão de trabalho. (Obviamente, eu sempre posso reexecutar o notebook, mas isso pode ser uma dor, especialmente se alguns dos resultados dependem de cálculos longos, cálculos paralelos etc.). Ainda não tenho uma boa idéia sobre como resolver isso. . Talvez um fluxo de trabalho envolvendo uma extensão como o ipycache possa funcionar, mas isso parece um pouco complicado.
Notas
Remoção (remoção) da saída
- Quando o notebook está funcionando, pode-se usar a
Cell/All Output/Clear
opção de menu para remover a saída. - Existem alguns scripts para remover a saída, como o script nbstripout.py, que remove a saída, mas não produz a mesma saída que a interface do notebook. Eventualmente, isso foi incluído no repositório ipython / nbconvert , mas foi encerrado, informando que as alterações agora estão incluídas no ipython / ipython , mas a funcionalidade correspondente parece não ter sido incluída ainda. (update) Dito isto, a solução de Gregory Crosswhite mostra que isso é bastante fácil de fazer, mesmo sem chamar ipython / nbconvert, portanto, essa abordagem provavelmente é viável se puder ser conectada adequadamente. (Anexá-la a cada sistema de controle de versão, no entanto, não parece uma boa idéia - isso deve, de alguma forma, conectar-se ao mecanismo do notebook).
Grupos de Notícias
Problemas
- 977: Solicitações de recursos do notebook (aberto) .
- 1280: opção Limpar tudo ao salvar (Abrir) . (Segue desta discussão .)
- 3295: blocos de notas autoexportados: apenas exportam células marcadas explicitamente (Fechadas) . Resolvido pela extensão 11 Adicione magia de escrever e executar (Mesclado) .
Solicitações Pull
- 1621: apague os números do prompt [] em "Apagar tudo resultado" (mesclado) . (Veja também 2519 (Mesclado) .)
- 1563: melhorias de clear_output (mesclado) .
- 3065: dificuldade de notebooks (fechada) .
- 3291: adicione a opção para ignorar as células de saída ao salvar. (Fechado) . Isso parece extremamente relevante, mas foi encerrado com a sugestão de usar um filtro "limpo / mancha". Uma pergunta relevante, o que você pode usar se quiser retirar a saída antes de executar o git diff? parece não ter sido respondido.
- 3312: WIP: ganchos para salvar notebook (fechados) .
- 3747: ipynb -> transformador ipynb (fechado) . Isso é reformulado em 4175 .
- 4175: nbconvert: base exportadora de Jinjaless (mesclada) .
- 142: Use STDIN em nbstripout se nenhuma entrada for fornecida (Aberto) .
--script
opção, mas que foi removida. Estou esperando até que os ganchos pós-salvamento sejam implementados ( que são planejados ) e, nesse ponto, acho que poderei fornecer uma solução aceitável combinando várias das técnicas.