Automatically delete * .pyc files and otherwise empty directories when checking for a new branch

So, an interesting situation when using git and python, and I am sure that this happens for other situations as well.

Let's say I create a git repository with the / foo / folder. In this folder I put /foo/program.py. I run program.py and program.pyc. I have * .pyc in a .gitignore file, so git does not track it.

Now let me say that I am doing another branch, dev. In this dev branch, I completely delete the / foo / folder.

Now I switch back to the main branch and / foo / appears again. I run program.py and the program.pyc file appears again. All right.

I am going back to my dev branch. The directory / foo / should disappear. It exists only in the master branches, and not in the dev branches. However, it still exists. What for? Since the ignored program.pyc file prevents the folder from being deleted when switching branches.

The solution to this problem is to recursively delete all * .pyc files before switching branches. I can easily do this with this command.

find . -name "*.pyc" -exec rm '{}' ';' 

The problem is that the annoyance needs to be remembered in order to do this almost every time I change branches. I could make an alias for this command, but then I still have to remember to enter it every time I change branches. I could also make an alias for git-branch, but nothing good. The git branch command does things other than change branch changes, and I don't want to delete all pyc files every time I use them. Damn, I’d even use it in disrepute, then what?

Is there a way to set a git hook that only executes when changing branches? Or is there some other way that all * .pyc files are deleted whenever I switch branches?

+52
git python bash
01 Oct '09 at 15:41
source share
4 answers

There is a post-checkout hook that should be placed in .git / hooks / post-checkout. There probably is a sample, possibly named .sample or maybe not executable, depending on your version of git. Short description: it receives three parameters: the previous HEAD, the new HEAD and the flag, which is 1 if the branch is changed, and 0 if it is just a file check. See man githooks for more info! You should be able to write a shell script to do what you need and put it there.

Edit: I understand that you are looking for this preliminary check so that the check automatically cleans directories that become empty. There is no pre-check hook, so you have to use your script to remove directories.

Another note: Aliases are part of gitconfig, which can be local to the repository (in .git / config, not ~ / .gitconfig). If you decide to do this with aliases (for git -checkout, not git-branch), you can easily place them only in python-related repositories. Also in this case, I would make an alias specifically for this purpose (e.g. cc to verify cleanup). You can use checkout (or another alias) if you don't want to clear the pyc files.

+40
01 Oct '09 at 15:48
source share

Just copy and update the good Apreche solution, which was buried in the comments:

Save this shell script to the file /path/to/repo/.git/hooks/post-checkout and make it executable.

 #! /bin/sh # Start from the repository root. cd ./$(git rev-parse --show-cdup) # Delete .pyc files and empty directories. find . -name "*.pyc" -delete find . -type d -empty -delete 
+35
Nov 27 '09 at 18:46
source share

Another option is not to solve this problem as a git problem in general, but as a Python problem. You can use the PYTHONDONTWRITEBYTECODE environment variable to not write Python .pyc files in the first place. Then you will have nothing to clean up when you switch branches.

+4
Oct 12 '14 at 12:54 on
source share

My solution is more compatible with git : Git only removes enpty directories where any file has been deleted by verification. He is not looking for a complete processing tree. This is useful for large repositories or repositories with a very large ignored tree, such as virtual environments, through a tox package to test many different versions of Python, etc.

My first implementation very clearly explains the principle: Only pyc files associated with version control files are cleared. This is for reasons of effectiveness and unwanted side effects.

 #!/bin/bash # A hook that removes orphan "*.pyc" files for "*.py" beeing deleted. # It doesn not clean anything eg for .py files deleted manually. oldrev="$1" newrev="$2" # ignored param: branchcheckout="$3" for x in $(git diff --name-only --diff-filter=DR $oldrev..$newrev | grep "\.py$") do if test -a ${x}c && ! test -a ${x}; then rm ${x}c fi done 

The post-checkout hook receives three useful parameters that let you know exactly which files were deleted using git checkout, without looking for a complete tree.

After reading the question, I rewrote my hook code in Python and expanded it to suit your requirements for empty directories.

My complete short source code (Python) is in
https://gist.github.com/hynekcer/476a593a3fc584278b87#file-post-checkout-py

Doc line:

 """ 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. Nothing is cleaned for .py files deleted manually or by "git rm" etc. Place it to "my_local_repository/.git/hooks/post-checkout" and make it executable """ 
  • The problem with * .pyc files is not important for Python 3 because the * .pyc files in __pycache__ cannot be executed without the associated * .py * file in its parent directory.

  • No change catalog is required, since hooks are triggered every time in the root of the repository.

  • The cache directories for the compiled __pycache__ code __pycache__ completely cleared because they are never important (do not participate in any binary distribution), and also for high efficiency, since deleting in parts of __pycache__/some_name.*.pyc can be slow.
+2
12 Oct '14 at 0:09
source share



All Articles