Jaka jest dobra strategia utrzymywania notebooków IPython pod kontrolą wersji?
Format notebooka jest całkiem podatny na kontrolę wersji: jeśli ktoś chce kontrolować wersję notebooka i wyjść, działa to całkiem dobrze. Drażliwość pojawia się, gdy chce się tylko kontrolować wersję danych wejściowych, wyłączając wyjścia komórek (inaczej „produkty do budowania”), które mogą być dużymi binarnymi plamami, szczególnie dla filmów i fabuł. W szczególności staram się znaleźć dobry przepływ pracy, który:
- pozwala mi wybierać między włączeniem lub wyłączeniem danych wyjściowych,
- zapobiega przypadkowemu uruchomieniu wyjścia, jeśli go nie chcę,
- pozwala mi zachować dane wyjściowe w mojej lokalnej wersji,
- pozwala mi zobaczyć, kiedy mam zmiany danych wejściowych za pomocą mojego systemu kontroli wersji (tj. jeśli tylko kontroluję wersję danych wejściowych, ale mój plik lokalny ma dane wyjściowe, to chciałbym móc zobaczyć, czy dane wejściowe uległy zmianie (wymaga zatwierdzenia Użycie polecenia statusu kontroli wersji zawsze rejestruje różnicę, ponieważ plik lokalny ma dane wyjściowe.)
- pozwala mi aktualizować mój działający notatnik (który zawiera dane wyjściowe) z zaktualizowanego czystego notatnika. (aktualizacja)
Jak wspomniano, jeśli zdecyduję się na dołączenie wyjść (co jest pożądane, na przykład przy użyciu nbviewer ), wtedy wszystko będzie dobrze. Problem polega na tym, że nie chcę kontrolować wersji danych wyjściowych. Istnieją narzędzia i skrypty do usuwania danych wyjściowych z notatnika, ale często napotykam następujące problemy:
- Przypadkowo zatwierdzam wersję z wyjściem, zanieczyszczając w ten sposób moje repozytorium.
- Wyczyszczam dane wyjściowe, aby użyć kontroli wersji, ale tak naprawdę wolałbym zachować dane wyjściowe w mojej lokalnej kopii (czasami na przykład odtworzenie zajmuje trochę czasu).
- Niektóre skrypty usuwające dane wyjściowe nieznacznie zmieniają format w porównaniu z
Cell/All Output/Clear
opcją menu, tworząc w ten sposób niepożądany szum w różnicach. Rozwiązują to niektóre odpowiedzi. - Wyciągając zmiany do czystej wersji pliku, muszę znaleźć sposób na wprowadzenie tych zmian do mojego roboczego notebooka bez konieczności ponownego uruchamiania wszystkiego. (aktualizacja)
Rozważyłem kilka opcji, które omówię poniżej, ale jeszcze nie znalazłem dobrego kompleksowego rozwiązania. Pełne rozwiązanie może wymagać pewnych zmian w IPython lub może polegać na prostych skryptach zewnętrznych. Obecnie używam rtęci , ale chciałbym rozwiązania, które również działa z git : idealnym rozwiązaniem byłoby agnostyk kontroli wersji.
Zagadnienie to było omawiane wiele razy, ale nie ma ostatecznego ani jasnego rozwiązania z perspektywy użytkownika. Odpowiedź na to pytanie powinna stanowić ostateczną strategię. Jest w porządku, jeśli wymaga najnowszej (nawet programistycznej) wersji IPython lub łatwo instalowanego rozszerzenia.
Aktualizacja: gram z moją zmodyfikowaną wersją notebooka, która opcjonalnie zapisuje .clean
wersję przy każdym zapisie, korzystając z sugestii Gregory Crosswhite . Spełnia to większość moich ograniczeń, ale pozostawia następujące nierozwiązane:
- Nie jest to jeszcze standardowe rozwiązanie (wymaga modyfikacji źródła ipython. Czy istnieje sposób na osiągnięcie tego zachowania za pomocą prostego rozszerzenia? Potrzebuje pewnego rodzaju zaczepu przy zapisie.
- Problemem z bieżącym przepływem pracy jest pobieranie zmian. Będą one wchodzić do
.clean
pliku, a następnie muszą być jakoś zintegrowane z moją działającą wersją. (Oczywiście zawsze mogę ponownie uruchomić notatnik, ale może to być uciążliwe, szczególnie jeśli niektóre wyniki zależą od długich obliczeń, obliczeń równoległych itp.) Nie mam jeszcze pojęcia, jak rozwiązać ten problem . Być może przepływ pracy z rozszerzeniem takim jak ipycache może działać, ale wydaje się to trochę zbyt skomplikowane.
Notatki
Usuwanie (usuwanie) danych wyjściowych
- Gdy notebook jest uruchomiony, można użyć
Cell/All Output/Clear
opcji menu do usunięcia danych wyjściowych. - Istnieją skrypty do usuwania danych wyjściowych, takie jak skrypt nbstripout.py, które usuwają dane wyjściowe, ale nie generują takich samych danych wyjściowych, jak przy użyciu interfejsu notebooka. Zostało to ostatecznie uwzględnione w repozytorium ipython / nbconvert , ale zostało to zamknięte, stwierdzając, że zmiany są teraz zawarte w ipython / ipython , ale odpowiednia funkcjonalność wydaje się, że nie została jeszcze uwzględniona. (aktualizacja) To powiedziawszy, rozwiązanie Gregory Crosswhite pokazuje, że jest to dość łatwe, nawet bez wywoływania ipython / nbconvert, więc to podejście jest prawdopodobnie wykonalne, jeśli można je właściwie podłączyć. (Dołączenie go do każdego systemu kontroli wersji nie wydaje się jednak dobrym pomysłem - powinno to jakoś podłączyć się do mechanizmu notebooka).
Grupy dyskusyjne
Problemy
- 977: Żądania funkcji notebooka (otwarte) .
- 1280: Wyczyść wszystko po zapisaniu (Otwórz) . (Wynika z tej dyskusji .)
- 3295: automatycznie eksportowane notebooki: eksportuj tylko wyraźnie zaznaczone komórki (zamknięte) . Rozwiązane przez rozszerzenie 11 Dodaj magię zapisu i wykonania (Połączone) .
Wyciągnij wnioski
- 1621: wyczyść W [] numery zachęty na „Wyczyść wszystkie dane wyjściowe” (Scalone) . (Zobacz także 2519 (Scalony) .)
- 1563: ulepszenia clear_output (Scalone) .
- 3065: diff -ability of notebooks (Closed) .
- 3291: Dodaj opcję pomijania komórek wyjściowych podczas zapisywania. (Zamknięty) . Wydaje się to niezwykle istotne, jednak zostało zamknięte z sugestią użycia filtra „czyszczenie / rozmazywanie”. Odpowiednie pytanie, czego możesz użyć, jeśli chcesz usunąć dane wyjściowe przed uruchomieniem git diff? wydaje się, że nie otrzymano odpowiedzi.
- 3312: WIP: Haki do zapisywania w notatniku (zamknięte) .
- 3747: ipynb -> transformator ipynb (zamknięty) . Jest to oparte na 4175 .
- 4175: nbconvert: Baza eksporterów Jinjaless (Scalona) .
- 142: Użyj STDIN w nbstripout, jeśli nie podano danych wejściowych (Otwórz) .
--script
opcję, ale została ona usunięta. Czekam na wdrożenie (po planowaniu ) haczyków po zapisaniu, w którym momencie myślę, że będę w stanie zapewnić akceptowalne rozwiązanie łączące kilka technik.