0

Long story short: we're using Jupyter notebooks (.ipynb files) and have set up the Jupyter config to save .py copies (à la this answer on SO, for the purposes of nicer git diffs).

So every time I save a .ipynb file, it saves a .py version, with otherwise the same filename. If no .py version already existed, it creates a new one.

Is it possible to automatically add / track these newly created .py files, perhaps by putting something in the git config?

Edit

So this may be possible using a git pre-commit hook, having read up about it. However, I don't really know enough to write a hook from scratch.

To reiterate what I want: I save foo_bar.ipynb, automatically creating foo_bar.py. I want the pre-commit hook to add foo_bar.py if I do, e.g., git commit -a. To emphasise, I don't want it to add any old .py files, only ones that have the same filename as an existing .ipynb file.

Community
  • 1
  • 1
binaryfunt
  • 6,401
  • 5
  • 37
  • 59
  • 1
    Possible duplicate of [Can a Git hook automatically add files to the commit?](https://stackoverflow.com/questions/3284292/can-a-git-hook-automatically-add-files-to-the-commit) – underscore_d Jul 25 '17 at 14:40
  • or [git commit auto add new folders or files?](https://stackoverflow.com/questions/8956522/git-commit-auto-add-new-folders-or-files) – underscore_d Jul 25 '17 at 14:40
  • In order to run the pre-commit hook you have to commit, in the first place. `git add .` before `git commit` should be enough. – axiac Jul 25 '17 at 15:20
  • @axiac I don't want to add any old `.py` files, just ones that have identical filenames to existing `.ipynb` files – binaryfunt Jul 25 '17 at 15:22
  • 1
    No matter what you want to add, Git doesn't do anything by itself. A pre-commit hook runs as part of a `git commit` command. Somebody (a human or a script) must run this command. The same person or script can `git add` the appropriate files before running `git commit`. There is no need for a hook for such a simple task. More than that, there is no commit (and I think also the hooks do not run) if nothing is staged for commit. – axiac Jul 25 '17 at 15:25
  • @axiac If a team member forgets to add the `.py` version, it would cause confusion, hence I want it automated. I see what you're saying though, I guess a pre-commit hook won't work actually. Just have to remind the team to add both versions – binaryfunt Jul 25 '17 at 15:30
  • With a pre-commit hook (needs to be on each users machine...), you could *fail* the commit if there is a new `.ipynb` without a corresponding `.py` file. – crashmstr Jul 25 '17 at 15:41
  • Possible duplicate of [git commit auto add new folders or files?](https://stackoverflow.com/questions/8956522/git-commit-auto-add-new-folders-or-files) – phd Jul 25 '17 at 15:47

1 Answers1

1

Write a script that adds the new and updated files to Git and the commits them. Run it manually or as a cron job. Even better, hook it into the tool that generates the files, if possible, to run every time the tool saves the files or when it exits.

The script could be as simple as:

# Change directory
cd /path/to/the/directory/where/the/py/files/are/saved

# Set this to 1 when a commit is needed
commit=0

# Check all the .ipynb files
for i in *.ipynb; do
    # Generate the name of the corresponding .py file
    p=${i//.ipybn}.py
    # If the .py file exists
    if [ -f $p ]; then
        # Add it to be committed; it doesn't hurt if it is not modified
        git add $p
        # Remember we have to commit at the end
        commit=1
    fi
done

# Avoid running "git commit" when nothing was staged
if [ $commit -eq 1 ]; then
    # Commit, generate an unique (not very useful) commit message.
    git commit -m "automatic commit on $(date +'%Y-%m-%d %H:%I:%S')"
fi

The code above assumes all the .ipynb files are stored in a single directory (no subdirectories) and the corresponding .py files are stored in the same directory.

If the .ipynb files are stored in multiple directories then replace the for line with:

for i in $(find . -name \*.ipynb); do

If the .py file is not stored in the same directory as the corresponding .ipybn file then you have to change the line p=${i//.ipybn}.py.

Multiple conditions can be verified before staging the file.

axiac
  • 68,258
  • 9
  • 99
  • 134