15

我想找到将文件包含在 git 未跟踪的 python sdist 中的正确方法。

语境

我的项目中的.mo文件没有被跟踪git(就像其他一些.txt需要在安装时创建的文件一样)。

我写了一个小函数setup.py来在安装时创建它们,我调用它setup()

setup(
    .
    .
    .
    data_files=create_extra_files(),
    include_package_data=True,
    .
    .
    .
)

请注意,它们应该属于,data_dir因为文档说

data_files 选项可用于指定模块分发所需的其他文件:配置文件、消息目录、数据文件,以及不属于前面类别的任何内容。

因此,这适用于python3 setup.py installbdist也适用于)。.mo文件生成并存储在正确的位置。

但是,如果我希望它与 一起使用sdist,那么我必须将它们包含在MANIFEST.in(例如recursive-include mathmaker *.mo)中。文档确实说

在 3.1 版更改:如果没有提供模板,所有匹配 data_files 的文件都将被添加到 MANIFEST 文件 中。请参阅指定要分发的文件

(该链接没有多大帮助)。

我不愿意在其中包含*.mo文件,MANIFEST.in因为 git 不会跟踪它们。而check-manifest不喜欢这种情况,它抱怨这样一个事实lists of files in version control and sdist do not match!

那么,有没有办法解决这个丑陋的情况呢?

重现情况的步骤

环境与项目

为避免污染您的环境,请在您选择的目录中创建并激活专用虚拟环境(python3.4+):

$ pyvenv-3.4 v0
$ source v0/bin/activate
(v0) $

project0在目录中重现以下树:

.
├── .gitignore
├── MANIFEST.in
├── README.rst
├── setup.py
└── project0
    ├── __init__.py
    ├── main.py
    └── data
        └── dummy_versioned.po

其中README.rst,__init__.pydummy_versioned.po为空。

其他文件的内容:

  • .gitignore

    build/
    dist/
    *.egg-info
    project0/data/*.txt
    *~
    
  • MANIFEST.in

    recursive-include project0 *.po
    recursive-include project0 *.txt
    
  • main.py

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    
    def entry_point():
        with open('project0/data/a_file.txt', mode='rt') as f:
            print(f.read())
    
  • setup.py

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import platform
    from setuptools import setup, find_packages
    
    
    def create_files():
        txt_file_path = 'project0/data/a_file.txt'
        with open(txt_file_path, mode='w+') as f:
            f.write("Some dummy platform information: " + platform.platform())
        return [('project0/data', [txt_file_path])]
    
    
    setup(
        name='project0',
        version='0.0.1',
        author='J. Doe',
        author_email='j.doe@someprovider.com',
        url='http://myproject.url',
        packages=find_packages(),
        data_files=create_files(),
        include_package_data=True,
        entry_points={
            'console_scripts': ['myscript0 = project0.main:entry_point'],
        }
    )
    

启动本地git仓库:

(v0) $ git init
(v0) $ git add .

安装check-manifest

(v0) $ pip3 install check-manifest

安装和测试

install作品:

(v0) $ python3 setup.py install
.
.
.
copying project0/data/a_file.txt -> build/lib/project0/data
.
.
.
Finished processing dependencies for project0==0.0.1
(v0) $ myscript0 
Some dummy platform information: Linux-3.16.0-29-generic-x86_64-with-Ubuntu-14.04-trusty

如果您rm project0/data/a_file.txt,则myscript0不再工作,但重新安装它并再次工作,如预期的那样。

构建 sdist 还包括a_file.txt

(v0) $ python3 setup.py sdist
.
.
.
hard linking project0/data/a_file.txt -> project0-0.0.1/project0/data
.
.
.

请注意,要将这个文件包含在 sdist 中,看起来有必要(如下面的“上下文”部分所述)recursive-include project0 *.txtMANIFEST.in. 您是否会删除此行,不再python3 setup.py sdist提及a_file.txt(不要忘记删除任何以前的build/dist/目录来观察这一点)。

结论

因此,一切都按原样运行,但存在这种差异:a_file.txt不被 跟踪git,但被包含在MANIFEST.in.

check-manifest清楚地告诉:

lists of files in version control and sdist do not match!
missing from VCS:
  project0/data/a_file.txt

那么,有没有合适的方法来处理这种情况呢?

4

1 回答 1

2

就我得到您的问题而言,您想添加要与 git 存储库一起分发的文件,但您不想跟踪它们的更改。

这可以通过这四个简单的步骤来完成:

第 0 步: 首先确保path/a_file.txt文件内的内容与您要分发的内容匹配。据我所知,它不能为空,因此如果您只是希望此文件存在,请在其中添加换行符/空格字符。

第 1 步: 使用将文件添加到 gitgit add path/a_file.txt

第 2 步: 提交文件 ( git commit path/a_file.txt)

第 3 步: 更新 git 的索引并告诉 git 它应该忽略对文件的进一步更改 git update-index --assume-unchanged path/a_file.txt

如果您想对该文件进行一些更改,并再次进行跟踪,您可以简单地使用该--no-assume-unchanged标志在 git 的索引中将其设置为活动状态,然后提交更改。

请注意,创建一个.gitignore告诉 git 忽略文件(在克隆存储库的所有机器上)和使用的文件git add --force path/a_file.txt将不起作用,因为 git 将(force)将其添加到索引并跟踪更改

于 2017-04-26T05:52:00.687 回答