(我预见到这个问题可能会在3个月前发生,并被告知要努力避免它。昨天,我被它咬了,很难,现在它花了我真钱,我很想解决它。)
如果我将我的一个Python源文件移动到另一个目录中,我需要记住告诉Mercurial它已移动(hg move
)。
当我使用Mercurial将新软件部署到我的服务器时,它会小心地删除旧的Python文件并在新目录中创建它。
但是,Mercurial并不知道同一目录中的pyc文件,并将其遗留下来。旧的pyc优先于同一目录中的其他模块使用新的python文件。
随之而来的不是欢闹。
当我移动python文件时,如何说服Mercurial自动删除旧的pyc文件?还有其他更好的做法吗?试图记住从所有Mercurial存储库中删除pyc文件是行不通的。
答案 0 :(得分:16)
答案 1 :(得分:9)
如何在服务器端使用update hook?将它放在存储库的.hg
目录的hgrc
文件中:
[hooks]
update = find . -name '*.pyc' | xargs rm
每当您在服务器上更新时,这将删除所有.pyc文件。如果你担心重建所有.pyc文件的成本,你总是可以在钩子中更聪明一点,只删除没有.py的.pyc,但这可能有点过分。
答案 2 :(得分:6)
你需要:
1)真正的部署基础架构,即使它只是一个shell脚本,它可以完成所有任务。从源代码控制克隆/签出更新的副本不是部署策略。
2)任何部署系统都应该完全清理目录结构。我通常的偏好是每个部署都发生在以date + timestamp命名的新目录中,并且符号链接(名称如“current”)更新为指向新目录。如果出现问题,这会在每台服务器上为您提供面包屑。
3)修复运行Python代码的任何内容。新的.py源文件应始终优先于缓存的.pyc文件。如果这不是你所看到的行为,那就是一个错误,你需要弄清楚它为什么会发生。
答案 3 :(得分:3)
我实际做了什么:
1)我正在考虑Nicholas Knight关于使用适当部署策略的建议。我一直在阅读Buildout和Collective.hostout以了解详情。我需要决定这样的重量级策略是否值得我的项目相对简单的要求。
2)我在短期内采用了Ry4an的更新钩子概念,直到我决定。
3)我忽略了Ry4an关于矫枉过正的警告,并编写了一个Python脚本来删除流浪的.pyc文件。
#!/usr/bin/env python
""" Searches subdirectories of the current directory looking for .pyc files which
do not have matching .py files, and deletes them.
This is useful as a hook for version control when Python files are moved.
It is dangerous for projects that deliberately include Python
binaries without source.
"""
import os
import os.path
for root, dirs, files in os.walk("."):
pyc_files = filter(lambda filename: filename.endswith(".pyc"), files)
py_files = set(filter(lambda filename: filename.endswith(".py"), files))
excess_pyc_files = filter(lambda pyc_filename: pyc_filename[:-1] not in py_files, pyc_files)
for excess_pyc_file in excess_pyc_files:
full_path = os.path.join(root, excess_pyc_file)
print "Removing old PYC file:", full_path
os.remove(full_path)
我的更新挂钩现在调用此而不是其他人建议的“查找”命令。
答案 4 :(得分:2)
这是一个unix单行程序,每次运行hg update
时都会删除.pyc文件。
将此添加到您的hgrc文件:
[hooks]
preupdate.cleanpyc = hg status --no-status --removed --deleted --include "**.py" --rev .:$HG_PARENT1 --print0 | xargs -0 -I '{}' rm -f '{}c'
这在更新之前运行,并获取将在执行更新时删除或删除的所有.py文件,然后删除相应的.pyc文件。
以下是对其工作原理的快速分析:
hg status --no-status --removed --deleted --include "**.py" --rev .:$HG_PARENT1
这会删除所有文件(例如hg forget
)或删除(hg rm
,hg mv
等)当前版本.
与目标({{1})之间的文件})。如果您使用该功能,也可以添加$HG_PARENT
以获取子存储库中的所有更改。
--subrepos
这只是添加了一个' c'到xargs -0 -I '{}' rm -f '{}c'
返回的每个文件名的末尾,并尝试删除它。如果.pyc文件不存在,hg status
的{{1}}标志可确保它不会出错。
请注意,mercurial会在更新后自动删除空目录,但孤立的.pyc文件通常会导致目录遗留下来。由于这在更新之前运行,因此它确保正确删除空目录。
答案 5 :(得分:1)
我使用.hgignore
文件跳过所有.pyc和.py~(编辑器的临时文件)的版本。例如,这是我的版本:
# use glob syntax.
syntax: glob
.directory
*.pyc
*~
*.o
*.tgz
*.tbz2
*.gz
*.bz2
如果您不仅要忽略噪音而是将其从本地工作空间区域中删除,那么在更新时添加一个钩子以删除它们也是一个有趣的技巧。
答案 6 :(得分:0)
我使用此脚本删除当前文件夹中的.pyc文件,此脚本可以单独使用,也可以将其包含在exit函数中,以便在退出时删除.pyc文件。
import os
files = [f for f in os.listdir('.') if os.path.isfile(f) and '.pyc' in str(f)]
for f in files : os.unlink(os.getcwd()+'/'+f)