{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Git in DataFrames\n", "\n", "python + git + dataframe = [git-pandas](http://wdm0006.github.io/git-pandas/)"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": ["%matplotlib inline"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Repository"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Repository [pyquickhelper] instantiated at directory: ../..\n"]}], "source": ["from gitpandas import Repository\n", "\n", "tries = [\".\", \"../..\", \"../../..\"]\n", "err = None\n", "for t in tries:\n", " try:\n", " repo = Repository(working_dir=t, verbose=True)\n", " err = None\n", " break\n", " except Exception as e:\n", " err = e\n", " continue\n", "if err is not None:\n", " import os\n", " raise Exception(\"issue in current folder '{0}'\".format(os.getcwd())) from err"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
branchlocalrepository
0masterTruepyquickhelper
1masterFalsepyquickhelper
\n", "
"], "text/plain": [" branch local repository\n", "0 master True pyquickhelper\n", "1 master False pyquickhelper"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["repo.branches()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["One funny function. No idea if that gives a good estimation."]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["c:\\python372_x64\\lib\\site-packages\\gitpandas\\repository.py:461: UserWarning: Warning, extensions and ignore_dir will be deprecated in v2.0.0, please use ignore_globs instead\n", " warnings.warn('Warning, extensions and ignore_dir will be deprecated in v2.0.0, please use ignore_globs instead')\n"]}, {"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
committerhours
0sdpython107.178611
1GitHub0.000000
2Ensaegithubxd0.000000
3dupre515.906667
4xavier dupr\u00e9735.555833
5azure provisioned user2.483333
6abotlegacy0.000000
7ped47470.000000
\n", "
"], "text/plain": [" committer hours\n", "0 sdpython 107.178611\n", "1 GitHub 0.000000\n", "2 Ensaegithubxd 0.000000\n", "3 dupre 515.906667\n", "4 xavier dupr\u00e9 735.555833\n", "5 azure provisioned user 2.483333\n", "6 abotlegacy 0.000000\n", "7 ped4747 0.000000"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["try:\n", " use = repo.hours_estimate()\n", "except Exception as e:\n", " # Not always reliable.\n", " print(e)\n", " use = None\n", "use"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": ["170.14055555555547"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["if use is not None:\n", " workdays = use.hours.sum() / 8\n", "else:\n", " workdays = None\n", "workdays"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Not sure what this number reflects."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Logs\n", "\n", "The following cane take some time depending on you repository size."]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["c:\\python372_x64\\lib\\site-packages\\gitpandas\\repository.py:461: UserWarning: Warning, extensions and ignore_dir will be deprecated in v2.0.0, please use ignore_globs instead\n", " warnings.warn('Warning, extensions and ignore_dir will be deprecated in v2.0.0, please use ignore_globs instead')\n"]}, {"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
authorcommittermessagelinesinsertionsdeletionsnet
date
2020-02-20 00:34:22xavier dupr\u00e9xavier dupr\u00e9Update notebook_runner.py\\n2110
2020-02-20 00:26:08xavier dupr\u00e9xavier dupr\u00e9Update config.yml\\n2110
2020-02-20 00:14:36xavier dupr\u00e9xavier dupr\u00e9Fix bug introduced by previous commit\\n2110
2020-02-19 23:57:00xavier dupr\u00e9xavier dupr\u00e9removes some specific code added for older ver...4825232
2020-02-19 19:57:55xavier dupr\u00e9xavier dupr\u00e9Fixes #292, add command to run notebook\\n9183875
\n", "
"], "text/plain": [" author committer \\\n", "date \n", "2020-02-20 00:34:22 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-20 00:26:08 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-20 00:14:36 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-19 23:57:00 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-19 19:57:55 xavier dupr\u00e9 xavier dupr\u00e9 \n", "\n", " message lines \\\n", "date \n", "2020-02-20 00:34:22 Update notebook_runner.py\\n 2 \n", "2020-02-20 00:26:08 Update config.yml\\n 2 \n", "2020-02-20 00:14:36 Fix bug introduced by previous commit\\n 2 \n", "2020-02-19 23:57:00 removes some specific code added for older ver... 48 \n", "2020-02-19 19:57:55 Fixes #292, add command to run notebook\\n 91 \n", "\n", " insertions deletions net \n", "date \n", "2020-02-20 00:34:22 1 1 0 \n", "2020-02-20 00:26:08 1 1 0 \n", "2020-02-20 00:14:36 1 1 0 \n", "2020-02-19 23:57:00 25 23 2 \n", "2020-02-19 19:57:55 83 8 75 "]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["try:\n", " hist = repo.commit_history()\n", "except Exception as e:\n", " # Not always reliable.\n", " print(e)\n", " import pandas\n", " hist = pandas.DataFrame()\n", "hist.head()"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["c:\\python372_x64\\lib\\site-packages\\gitpandas\\repository.py:461: UserWarning: Warning, extensions and ignore_dir will be deprecated in v2.0.0, please use ignore_globs instead\n", " warnings.warn('Warning, extensions and ignore_dir will be deprecated in v2.0.0, please use ignore_globs instead')\n"]}, {"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
authorcommittermessagerevfilenameinsertionsdeletions
date
2020-02-20 00:34:22xavier dupr\u00e9xavier dupr\u00e9Update notebook_runner.py\\nf852c6e373613a8ad04a2cce36f472e6271d4f9csrc/pyquickhelper/ipythonhelper/notebook_runne...11
2020-02-20 00:26:08xavier dupr\u00e9xavier dupr\u00e9Update config.yml\\n6f656a84e49f909dbc16a863e4ee33991a30dbe2.circleci/config.yml11
2020-02-20 00:14:36xavier dupr\u00e9xavier dupr\u00e9Fix bug introduced by previous commit\\nca20e6763fe4b65172b9280de7162cb3dc8506b3src/pyquickhelper/ipythonhelper/notebook_runne...11
2020-02-19 23:57:00xavier dupr\u00e9xavier dupr\u00e9removes some specific code added for older ver...b6bbb285fb7327d96a7e27987b9781d6deabac60_unittests/ut_cli/test_cli_notebook.py92
2020-02-19 23:57:00xavier dupr\u00e9xavier dupr\u00e9removes some specific code added for older ver...b6bbb285fb7327d96a7e27987b9781d6deabac60setup.py114
\n", "
"], "text/plain": [" author committer \\\n", "date \n", "2020-02-20 00:34:22 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-20 00:26:08 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-20 00:14:36 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-19 23:57:00 xavier dupr\u00e9 xavier dupr\u00e9 \n", "2020-02-19 23:57:00 xavier dupr\u00e9 xavier dupr\u00e9 \n", "\n", " message \\\n", "date \n", "2020-02-20 00:34:22 Update notebook_runner.py\\n \n", "2020-02-20 00:26:08 Update config.yml\\n \n", "2020-02-20 00:14:36 Fix bug introduced by previous commit\\n \n", "2020-02-19 23:57:00 removes some specific code added for older ver... \n", "2020-02-19 23:57:00 removes some specific code added for older ver... \n", "\n", " rev \\\n", "date \n", "2020-02-20 00:34:22 f852c6e373613a8ad04a2cce36f472e6271d4f9c \n", "2020-02-20 00:26:08 6f656a84e49f909dbc16a863e4ee33991a30dbe2 \n", "2020-02-20 00:14:36 ca20e6763fe4b65172b9280de7162cb3dc8506b3 \n", "2020-02-19 23:57:00 b6bbb285fb7327d96a7e27987b9781d6deabac60 \n", "2020-02-19 23:57:00 b6bbb285fb7327d96a7e27987b9781d6deabac60 \n", "\n", " filename \\\n", "date \n", "2020-02-20 00:34:22 src/pyquickhelper/ipythonhelper/notebook_runne... \n", "2020-02-20 00:26:08 .circleci/config.yml \n", "2020-02-20 00:14:36 src/pyquickhelper/ipythonhelper/notebook_runne... \n", "2020-02-19 23:57:00 _unittests/ut_cli/test_cli_notebook.py \n", "2020-02-19 23:57:00 setup.py \n", "\n", " insertions deletions \n", "date \n", "2020-02-20 00:34:22 1 1 \n", "2020-02-20 00:26:08 1 1 \n", "2020-02-20 00:14:36 1 1 \n", "2020-02-19 23:57:00 9 2 \n", "2020-02-19 23:57:00 11 4 "]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["try:\n", " histf = repo.file_change_history()\n", "except Exception as e:\n", " # Not always reliable.\n", " print(e)\n", " import pandas\n", " histf = pandas.DataFrame(dict(filename=[\"\"]))\n", "histf.head()"]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
authorcommittermessagerevfilenameinsertionsdeletions
date
2013-12-28 02:32:34sdpythonsdpythonfirst version, doc, unit test, setup\\nb94d02d8e4bc124e7203c936cdde9570b8392d59src/pyquickhelper/sync/file_tree_node.py3990
2013-12-28 02:32:34sdpythonsdpythonfirst version, doc, unit test, setup\\nb94d02d8e4bc124e7203c936cdde9570b8392d59src/pyquickhelper/sync/synchelper.py2560
2013-12-28 02:32:34sdpythonsdpythonfirst version, doc, unit test, setup\\nb94d02d8e4bc124e7203c936cdde9570b8392d59src/pyquickhelper/unittests/__init__.py00
2013-12-28 02:32:34sdpythonsdpythonfirst version, doc, unit test, setup\\nb94d02d8e4bc124e7203c936cdde9570b8392d59src/pyquickhelper/unittests/utils_tests.py2800
2013-12-28 02:32:34sdpythonsdpythonfirst version, doc, unit test, setup\\nb94d02d8e4bc124e7203c936cdde9570b8392d59src/version.txt10
\n", "
"], "text/plain": [" author committer \\\n", "date \n", "2013-12-28 02:32:34 sdpython sdpython \n", "2013-12-28 02:32:34 sdpython sdpython \n", "2013-12-28 02:32:34 sdpython sdpython \n", "2013-12-28 02:32:34 sdpython sdpython \n", "2013-12-28 02:32:34 sdpython sdpython \n", "\n", " message \\\n", "date \n", "2013-12-28 02:32:34 first version, doc, unit test, setup\\n \n", "2013-12-28 02:32:34 first version, doc, unit test, setup\\n \n", "2013-12-28 02:32:34 first version, doc, unit test, setup\\n \n", "2013-12-28 02:32:34 first version, doc, unit test, setup\\n \n", "2013-12-28 02:32:34 first version, doc, unit test, setup\\n \n", "\n", " rev \\\n", "date \n", "2013-12-28 02:32:34 b94d02d8e4bc124e7203c936cdde9570b8392d59 \n", "2013-12-28 02:32:34 b94d02d8e4bc124e7203c936cdde9570b8392d59 \n", "2013-12-28 02:32:34 b94d02d8e4bc124e7203c936cdde9570b8392d59 \n", "2013-12-28 02:32:34 b94d02d8e4bc124e7203c936cdde9570b8392d59 \n", "2013-12-28 02:32:34 b94d02d8e4bc124e7203c936cdde9570b8392d59 \n", "\n", " filename insertions \\\n", "date \n", "2013-12-28 02:32:34 src/pyquickhelper/sync/file_tree_node.py 399 \n", "2013-12-28 02:32:34 src/pyquickhelper/sync/synchelper.py 256 \n", "2013-12-28 02:32:34 src/pyquickhelper/unittests/__init__.py 0 \n", "2013-12-28 02:32:34 src/pyquickhelper/unittests/utils_tests.py 280 \n", "2013-12-28 02:32:34 src/version.txt 1 \n", "\n", " deletions \n", "date \n", "2013-12-28 02:32:34 0 \n", "2013-12-28 02:32:34 0 \n", "2013-12-28 02:32:34 0 \n", "2013-12-28 02:32:34 0 \n", "2013-12-28 02:32:34 0 "]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["histf.tail()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Check removed files"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/plain": ["1199"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["unique = set(histf.filename)\n", "len(unique)"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": ["import os\n", "sorted_unique = list(sorted(unique))\n", "full_path = [os.path.join(repo.repo.working_dir, _) for _ in sorted_unique]"]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": ["import numpy\n", "exists = [os.path.exists(f) for f in full_path]\n", "sizes = [os.stat(f).st_size if os.path.exists(f) else numpy.nan for f in full_path]"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nameexistssize
339_unittests/ut_helpgen/notebooks_slides/js_boke...True424724.0
1084src/pyquickhelper/sphinxext/revealjs/templates...True476557.0
579_unittests/ut_pycode/data/coverage/coverage_re...True507382.0
677_unittests/ut_sphinxext/data/video/mur.mp4True625634.0
260_unittests/ut_helpgen/data/completion_profilin...True1402712.0
\n", "
"], "text/plain": [" name exists size\n", "339 _unittests/ut_helpgen/notebooks_slides/js_boke... True 424724.0\n", "1084 src/pyquickhelper/sphinxext/revealjs/templates... True 476557.0\n", "579 _unittests/ut_pycode/data/coverage/coverage_re... True 507382.0\n", "677 _unittests/ut_sphinxext/data/video/mur.mp4 True 625634.0\n", "260 _unittests/ut_helpgen/data/completion_profilin... True 1402712.0"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas\n", "removed = pandas.DataFrame(dict(name=sorted_unique, exists=exists, size=sizes))\n", "removed.sort_values(\"size\").dropna().tail()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["How many files not exist anymore?"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": ["(261, 3)"]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["removed[~removed.exists].shape"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nameexistssize
0\"_unittests/ut_sync/data/bug/bugged/Pr\\303\\251...FalseNaN
1\"_unittests/ut_sync/data/bug/bugged/Pr\\303\\251...FalseNaN
2.circle.ymlFalseNaN
3.circle.yml => circle.ymlFalseNaN
5.coveragercFalseNaN
\n", "
"], "text/plain": [" name exists size\n", "0 \"_unittests/ut_sync/data/bug/bugged/Pr\\303\\251... False NaN\n", "1 \"_unittests/ut_sync/data/bug/bugged/Pr\\303\\251... False NaN\n", "2 .circle.yml False NaN\n", "3 .circle.yml => circle.yml False NaN\n", "5 .coveragerc False NaN"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["removed[~removed.exists].head()"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": ["g = repo.repo.git()"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["commit 561c3bbe2e0eb9223a25949187a61645c213bb87\n", "log size 139\n", "Author: xavier dupr\u00e9 \n", "Date: Thu Apr 25 11:19:36 2019 +0200\n", "\n", " Fixes #246, support projects with no src folder\n", "\n", "commit a8db6b4b0a2e38f774300acabb2ab46b9677a981\n", "log size 142\n", "Author: xavier dupr\u00e9 \n", "Date: Mon Mar 25 12:31:53 2019 +0100\n", "\n", " fixes missing names, skip lines marked with # noqa\n", "\n", "commit 7b34578848f96fea15c1fc96c1cece354f87ba90\n", "log size 115\n", "Author: xavier dupr\u00e9 \n", "Date: Sun Jul 22 12:36:29 2018 +0200\n", "\n", " update build_script.bat\n", "\n", "commit 27b203dd00658808925ab0ed24e91e7f34609254\n", "log size 122\n", "Author: xavier dupr\u00e9 \n", "Date: Thu May 17 00:45:25 2018 +0200\n", "\n", " documentation, setup, circleci\n", "\n", "commit 56950d8a1d41163c72e8cb7f1aac45dc2d4e5789\n", "log size 112\n", "Author: xavier dupr\u00e9 \n", "Date: Mon Jan 8 13:22:00 2018 +0100\n", "\n", " fix failing unit test\n", "\n", "commit 69c1a226c2f5724102ca2e5f22a1d6a126e701be\n", "log size 104\n", "Author: xavier dupr\u00e9 \n", "Date: Fri Dec 1 00:50:58 2017 +0100\n", "\n", " fix appeveyor\n", "\n", "commit f6e286c70b44bac822a51eb38cf48f4c387947dc\n", "log size 105\n", "Author: xavier dupr\u00e9 \n", "Date: Wed Nov 29 12:25:19 2017 +0100\n", "\n", " update script\n", "\n", "commit eba47ba0e8fb6cd7b10f62628a6ae71731b7418f\n", "log size 105\n", "Author: xavier dupr\u00e9 \n", "Date: Sat Mar 11 22:24:45 2017 +0100\n", "\n", " update python\n", "\n", "commit 0ca2465e8c2f68762442df1920fbc6300ef09a60\n", "log size 102\n", "Author: dupre \n", "Date: Mon Apr 25 21:18:18 2016 +0200\n", "\n", " update build_script\n", "\n", "commit d0dd08cdd12995b4a3e2423b8434bbfcd38d4e66\n", "log size 120\n", "Author: dupre \n", "Date: Fri Sep 18 00:50:44 2015 +0200\n", "\n", " revert to python 3.4 build_script.bat\n", "\n", "commit 0e2306bf7fc99dc15c6f6d0f8a2abeb74bb6b893\n", "log size 137\n", "Author: dupre \n", "Date: Thu Sep 17 22:05:00 2015 +0200\n", "\n", " update to deal with Python 3.5, minimizes dependencies\n", "\n", "commit 9e6fd6acd73670a3b2aa4098f33f015f5c1ae8a7\n", "log size 155\n", "Author: dupre \n", "Date: Sun May 3 12:49:38 2015 +0200\n", "\n", " add the script automation to the module, it automatically creates scripts\n"]}], "source": ["print(g.execute('git log --log-size --abbrev --follow \"build_script.bat\"').replace(\n", " '@gmail.com', '@').replace(\"@ensae.fr\", \"@\"))"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"data": {"text/plain": ["['xavier dupr\u00e9',\n", " 'f852c6e3',\n", " datetime.datetime(2020, 2, 20, 0, 0),\n", " 'Update notebook_runner.py',\n", " 'f852c6e373613a8ad04a2cce36f472e6271d4f9c',\n", " 'https://github.com/sdpython/pyquickhelper/commit/f852c6e373613a8ad04a2cce36f472e6271d4f9c']"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["from pyquickhelper.loghelper.repositories.pygit_helper import get_repo_log\n", "res = get_repo_log(repo.repo.working_dir)\n", "res[0]"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ownerhashdatetimecommentfull_hashpath
0xavier dupr\u00e9f852c6e32020-02-20Update notebook_runner.pyf852c6e373613a8ad04a2cce36f472e6271d4f9chttps://github.com/sdpython/pyquickhelper/comm...
1xavier dupr\u00e96f656a842020-02-20Update config.yml6f656a84e49f909dbc16a863e4ee33991a30dbe2https://github.com/sdpython/pyquickhelper/comm...
2xavier dupr\u00e9ca20e6762020-02-20Fix bug introduced by previous commitca20e6763fe4b65172b9280de7162cb3dc8506b3https://github.com/sdpython/pyquickhelper/comm...
3xavier dupr\u00e9b6bbb2852020-02-19removes some specific code added for older ver...b6bbb285fb7327d96a7e27987b9781d6deabac60https://github.com/sdpython/pyquickhelper/comm...
4xavier dupr\u00e9907acd7b2020-02-19Fixes #292, add command to run notebook907acd7b2f1da7443d94389da1a9981b8c276e06https://github.com/sdpython/pyquickhelper/comm...
\n", "
"], "text/plain": [" owner hash datetime \\\n", "0 xavier dupr\u00e9 f852c6e3 2020-02-20 \n", "1 xavier dupr\u00e9 6f656a84 2020-02-20 \n", "2 xavier dupr\u00e9 ca20e676 2020-02-20 \n", "3 xavier dupr\u00e9 b6bbb285 2020-02-19 \n", "4 xavier dupr\u00e9 907acd7b 2020-02-19 \n", "\n", " comment \\\n", "0 Update notebook_runner.py \n", "1 Update config.yml \n", "2 Fix bug introduced by previous commit \n", "3 removes some specific code added for older ver... \n", "4 Fixes #292, add command to run notebook \n", "\n", " full_hash \\\n", "0 f852c6e373613a8ad04a2cce36f472e6271d4f9c \n", "1 6f656a84e49f909dbc16a863e4ee33991a30dbe2 \n", "2 ca20e6763fe4b65172b9280de7162cb3dc8506b3 \n", "3 b6bbb285fb7327d96a7e27987b9781d6deabac60 \n", "4 907acd7b2f1da7443d94389da1a9981b8c276e06 \n", "\n", " path \n", "0 https://github.com/sdpython/pyquickhelper/comm... \n", "1 https://github.com/sdpython/pyquickhelper/comm... \n", "2 https://github.com/sdpython/pyquickhelper/comm... \n", "3 https://github.com/sdpython/pyquickhelper/comm... \n", "4 https://github.com/sdpython/pyquickhelper/comm... "]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["df = pandas.DataFrame(data=res,\n", " columns=\"owner hash datetime comment full_hash path\".split())\n", "df.head()"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"data": {"text/plain": ["('xavier dupr\u00e9',\n", " 'f852c6e3',\n", " datetime.datetime(2020, 2, 20, 0, 0),\n", " 'Update notebook_runner.py',\n", " 'f852c6e373613a8ad04a2cce36f472e6271d4f9c',\n", " 'https://github.com/sdpython/pyquickhelper/commit/f852c6e373613a8ad04a2cce36f472e6271d4f9c',\n", " 'src/pyquickhelper/ipythonhelper/notebook_runner.py',\n", " 2,\n", " 0)"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["res = get_repo_log(repo.repo.working_dir, file_detail=True)\n", "res[0]"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ownerhashdatetimecommentfull_hashpathnamenetbytes
0xavier dupr\u00e9f852c6e32020-02-20Update notebook_runner.pyf852c6e373613a8ad04a2cce36f472e6271d4f9chttps://github.com/sdpython/pyquickhelper/comm...src/pyquickhelper/ipythonhelper/notebook_runne...20
1xavier dupr\u00e96f656a842020-02-20Update config.yml6f656a84e49f909dbc16a863e4ee33991a30dbe2https://github.com/sdpython/pyquickhelper/comm....circleci/config.yml20
2xavier dupr\u00e9ca20e6762020-02-20Fix bug introduced by previous commitca20e6763fe4b65172b9280de7162cb3dc8506b3https://github.com/sdpython/pyquickhelper/comm...src/pyquickhelper/ipythonhelper/notebook_runne...20
3xavier dupr\u00e9b6bbb2852020-02-19removes some specific code added for older ver...b6bbb285fb7327d96a7e27987b9781d6deabac60https://github.com/sdpython/pyquickhelper/comm..._unittests/ut_cli/test_cli_notebook.py110
4xavier dupr\u00e9b6bbb2852020-02-19removes some specific code added for older ver...b6bbb285fb7327d96a7e27987b9781d6deabac60https://github.com/sdpython/pyquickhelper/comm...setup.py150
\n", "
"], "text/plain": [" owner hash datetime \\\n", "0 xavier dupr\u00e9 f852c6e3 2020-02-20 \n", "1 xavier dupr\u00e9 6f656a84 2020-02-20 \n", "2 xavier dupr\u00e9 ca20e676 2020-02-20 \n", "3 xavier dupr\u00e9 b6bbb285 2020-02-19 \n", "4 xavier dupr\u00e9 b6bbb285 2020-02-19 \n", "\n", " comment \\\n", "0 Update notebook_runner.py \n", "1 Update config.yml \n", "2 Fix bug introduced by previous commit \n", "3 removes some specific code added for older ver... \n", "4 removes some specific code added for older ver... \n", "\n", " full_hash \\\n", "0 f852c6e373613a8ad04a2cce36f472e6271d4f9c \n", "1 6f656a84e49f909dbc16a863e4ee33991a30dbe2 \n", "2 ca20e6763fe4b65172b9280de7162cb3dc8506b3 \n", "3 b6bbb285fb7327d96a7e27987b9781d6deabac60 \n", "4 b6bbb285fb7327d96a7e27987b9781d6deabac60 \n", "\n", " path \\\n", "0 https://github.com/sdpython/pyquickhelper/comm... \n", "1 https://github.com/sdpython/pyquickhelper/comm... \n", "2 https://github.com/sdpython/pyquickhelper/comm... \n", "3 https://github.com/sdpython/pyquickhelper/comm... \n", "4 https://github.com/sdpython/pyquickhelper/comm... \n", "\n", " name net bytes \n", "0 src/pyquickhelper/ipythonhelper/notebook_runne... 2 0 \n", "1 .circleci/config.yml 2 0 \n", "2 src/pyquickhelper/ipythonhelper/notebook_runne... 2 0 \n", "3 _unittests/ut_cli/test_cli_notebook.py 11 0 \n", "4 setup.py 15 0 "]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["df = pandas.DataFrame(data=res,\n", " columns=\"owner hash datetime comment full_hash path name net bytes\".split())\n", "df.head()"]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ownerhashdatetimecommentfull_hashpathnamenetbytesext
0xavier dupr\u00e9f852c6e32020-02-20Update notebook_runner.pyf852c6e373613a8ad04a2cce36f472e6271d4f9chttps://github.com/sdpython/pyquickhelper/comm...src/pyquickhelper/ipythonhelper/notebook_runne...20.py
1xavier dupr\u00e96f656a842020-02-20Update config.yml6f656a84e49f909dbc16a863e4ee33991a30dbe2https://github.com/sdpython/pyquickhelper/comm....circleci/config.yml20.yml
\n", "
"], "text/plain": [" owner hash datetime comment \\\n", "0 xavier dupr\u00e9 f852c6e3 2020-02-20 Update notebook_runner.py \n", "1 xavier dupr\u00e9 6f656a84 2020-02-20 Update config.yml \n", "\n", " full_hash \\\n", "0 f852c6e373613a8ad04a2cce36f472e6271d4f9c \n", "1 6f656a84e49f909dbc16a863e4ee33991a30dbe2 \n", "\n", " path \\\n", "0 https://github.com/sdpython/pyquickhelper/comm... \n", "1 https://github.com/sdpython/pyquickhelper/comm... \n", "\n", " name net bytes ext \n", "0 src/pyquickhelper/ipythonhelper/notebook_runne... 2 0 .py \n", "1 .circleci/config.yml 2 0 .yml "]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["df[\"ext\"] = df.name.apply(lambda x: os.path.splitext(x)[-1].strip())\n", "df.head(n=2)"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ext.ipynb.py.txt.yml.zip
net70325205934392719340
bytes0000179637
\n", "
"], "text/plain": ["ext .ipynb .py .txt .yml .zip\n", "net 70325 205934 3927 1934 0\n", "bytes 0 0 0 0 179637"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["gr = df[df.ext.isin((\".py\", \".ipynb\", \".txt\", \".zip\", \".yml\"))].groupby(\"ext\").sum()\n", "gr.T"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["gr.plot(kind=\"bar\");"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": []}], "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2"}}, "nbformat": 4, "nbformat_minor": 2}