Last active
November 27, 2019 20:14
-
-
Save hynekcer/476a593a3fc584278b87 to your computer and use it in GitHub Desktop.
Git post-checkout hook for Python to remove orphan *.pyc files and empty dir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env python | |
# This work is licensed under the terms of the MIT license. | |
# For a copy, see <https://opensource.org/licenses/MIT>. | |
""" | |
A hook to git that removes orphan files "*.pyc" and "*.pyo" for "*.py" | |
beeing deleted or renamed by git checkout. It also removes their empty parent | |
directories. | |
Place it to "my_local_repository/.git/hooks/post-checkout" and make it executable. | |
Nothing is cleaned for .py files deleted manually or by "git rm" etc. | |
Related to http://stackoverflow.com/q/1504724/448474 | |
""" | |
import glob | |
import os | |
import sys | |
from subprocess import Popen, PIPE | |
#print("HOOK POST-CHECKOUT") | |
oldrev, newrev, _ = sys.argv[1:] | |
cmd = 'git diff --name-only --diff-filter=DR {0}..{1}'.format(oldrev, newrev) | |
dirs = set() | |
p = Popen(cmd.split(), stdout=PIPE) | |
for line in p.stdout: | |
filepath = line.strip() | |
root, srcext = os.path.splitext(filepath) | |
if srcext == '.py' and not os.path.isfile(filepath): | |
parent_dir = os.path.dirname(root) | |
cache_dir = os.path.join(parent_dir, '__pycache__') | |
for ext in ('.pyc', '.pyo'): | |
if os.path.isdir(cache_dir): | |
for pycfile in glob.iglob(os.path.join(cache_dir, '*' + ext)): | |
os.remove(pycfile) | |
if not os.listdir(cache_dir): | |
os.rmdir(cache_dir) | |
dirs.add(parent_dir) | |
if os.path.isfile(root + ext): | |
os.remove(root + ext) | |
dirs.add(parent_dir) | |
p.stdout.close() | |
p.wait() | |
for pdir in sorted(dirs, key=lambda x: len(x.split(os.path.sep)), reverse=True): | |
if os.path.isdir(pdir) and not os.listdir(pdir): | |
os.rmdir(pdir) |
I missed your old question about the license. I didn't know how to do it correctly on Gist. I hope that the MIT license can be designated by these two lines, without any "(C)" line.
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This hook is very useful; thanks for sharing it.
What licence does it have? I'd like to use it with a private git repo, but since we store our hooks as part of the repo I'd technically be distributing it, and don't want to run afoul of licence issues.