切换新分支时自动删除*.pyc文件和空目录
这里有一个有趣的情况,发生在使用git和python的时候,我相信在其他场景下也会遇到类似的问题。
假设我创建了一个git仓库,里面有一个文件夹叫/foo/。在这个文件夹里,我放了一个文件/foo/program.py。我运行了program.py,结果生成了一个program.pyc文件。我在.gitignore文件里加了*.pyc,这样git就不会跟踪这个文件。
接下来,我创建了另一个分支,叫dev。在这个dev分支里,我把/foo/文件夹完全删除了。
然后我切换回主分支master,/foo/文件夹又出现了。我运行program.py,program.pyc文件也重新出现了,一切正常。
接着我又切换回dev分支。理论上,/foo/文件夹应该消失,因为它只存在于master分支,而不在dev分支里。然而,它仍然存在。为什么呢?因为被忽略的program.pyc文件阻止了在切换分支时删除这个文件夹。
解决这个问题的方法是在切换分支之前,递归地删除所有的*.pyc文件。我可以用这个命令轻松做到。
find . -name "*.pyc" -exec rm '{}' ';'
问题是,每次我切换分支时都要记得这么做,实在是太麻烦了。我可以为这个命令设置一个别名,但每次切换分支时我还是得记得输入它。我也可以为git-branch命令设置一个别名,但这样也不太好。因为git branch命令除了切换分支外,还有其他功能,我不想每次使用它时都删除所有的pyc文件。说不定我还会在一个非python的仓库里用它,那该怎么办呢?
有没有办法设置一个git钩子,只在我切换分支时执行?或者有没有其他方法可以在我切换分支时自动删除所有的*.pyc文件?
4 个回答
另一个选择是把这个问题当作Python的问题,而不是git的问题。你可以使用PYTHONDONTWRITEBYTECODE
这个环境变量,这样Python就不会生成.pyc文件了。这样当你切换分支的时候,就不需要清理这些文件了。
这里有一个很好的解决方案,之前被埋在评论里了,我把它复制过来并更新了一下:
把这个脚本保存到文件 /path/to/repo/.git/hooks/post-checkout
,然后记得给它设置可执行权限。
#! /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
在你的项目中,有一个叫做 post-checkout
的钩子,它需要放在 .git/hooks/post-checkout 这个文件夹里。那里可能会有一个示例文件,名字可能是 .sample,或者根据你的 git 版本,它可能无法执行。简单来说,这个钩子会接收三个参数:之前的 HEAD、现在的 HEAD,还有一个标志位。如果分支发生了变化,这个标志位是 1;如果只是简单地检出文件,这个标志位是 0。想了解更多信息,可以查看 man githooks
!你可以写一个 shell 脚本来完成你需要的操作,然后把它放在这个位置。
补充一下:我意识到你想在检出之前就做这个操作,这样在检出时可以自动清理变为空的目录。不过,实际上没有预检出钩子,所以你得用你的脚本来删除这些目录。
还有一点要注意:别名是 gitconfig 的一部分,可以是特定于某个仓库的(在 .git/config 中,而不是 ~/.gitconfig)。如果你选择用别名来处理这个(针对 git-checkout,而不是 git-branch),你可以很方便地只在与 Python 相关的仓库中使用它。此外,在这种情况下,我建议专门为这个目的创建一个别名(比如用 cc 来表示 checkout clean)。如果你不想清理 pyc 文件,仍然可以使用 checkout(或者其他别名形式)。