在 Python 中从克隆的 GitHub 存储库创建 Zip 存档

Posted

技术标签:

【中文标题】在 Python 中从克隆的 GitHub 存储库创建 Zip 存档【英文标题】:Create a Zip Archive from a cloned GitHub repo in Python 【发布时间】:2017-11-30 17:02:23 【问题描述】:

我正在使用 python(3.6) 开发一个项目,在该项目中我需要创建一个 zip 存档,其中包含来自 GitHub 存储库的所有文件。用户将提供 git 存储库 URL,然后我需要克隆此存储库并创建一个 zip 存档,其中包含来自 GitHub 存储库的所有文件。

这是我尝试过的:

                ARCHIVE_NAME = func_obj.fname + '.zip'
                zip_archive = zipfile.ZipFile(ARCHIVE_NAME, "w")
                # Write files to the archive
                zip_archive.write(git.Repo.clone_from(func_obj.sc_github, to_path=os.path.join(ARCHIVE_NAME)))
                zip_archive.close()
                file_path = os.path.join(IGui.settings.BASE_DIR, ARCHIVE_NAME)

这是更新后的代码,它克隆了 repo 并生成了 zip 存档,但它还有另一个问题,如下所述:

                ARCHIVE_NAME = func_obj.fname + '.zip'
                zip_archive = zipfile.ZipFile(ARCHIVE_NAME, "w")
                # Write files to the archive
                tempdir = tempfile.mkdtemp()
                # Ensure the file is read/write by the creator only
                saved_umask = os.umask(0o077)
                temppath = os.path.join(tempdir)
                print(temppath)
                git.Repo.clone_from(func_obj.sc_github, to_path=temppath)
                dirList = os.listdir(temppath)
                for file in dirList:
                    get_file = str(os.path.join(temppath, file))
                    print(get_file)
                    zip_archive.write(get_file)
                os.umask(saved_umask)
                shutil.rmtree(tempdir)

问题是:** 例如,如果 temppath 是:/var/folders/lf/pc01_3zj38q0qv1vq9r6rxs00000gn/T/tmpca2fv8eg,则 zip 档案创建为:当我们提取 zip 档案时,它包含 var 目录,然后在 var dir 中我们有文件夹目录,然后在文件夹中目录我们有 lf 目录,直到 tmpca2fv8eg 目录,然后在这个目录中我们有我们的 repo 文件,但是当我们提取它时,我需要将我的 repo 文件直接放在 zip 存档中,我们得到所有文件,而不是任何目录。**

请帮帮我!

提前致谢!

【问题讨论】:

哪些部分不能正常工作? 它返回:`文件“/Users/abdul/Documents/IVirEnv/lib/python3.6/site-packages/git/cmd.py”,第 418 行,等待引发 GitCommandError(self. args, status, errstr) git.exc.GitCommandError: Cmd('git') failed due to: exit code(128) cmdline: git clone -v github.com/arycloud/testing.git hjh.zip stderr: 'fatal: destination path 'hjh.zip ' 已经存在并且不是一个空目录。` 如果你想覆盖它,你必须确保该文件不存在。 实际上,我想从克隆的 repo 创建一个存档! 【参考方案1】:

创建存储库存档的另一种方法是使用支持ziptar 格式的git archive command:

import git
import tempfile
import os

tempdir = tempfile.mkdtemp()
temppath = os.path.join(tempdir)
print(temppath)
repo = git.Repo.clone_from(
    'https://github.com/serebrov/nodejs-typescript.git',
    to_path=temppath)

with open("archive.zip", "wb") as zipfile:
    repo.archive(zipfile, format='zip')

生成的archive.zip 包含存储库文件:

(venv) $ unzip -l archive.zip 
Archive:  archive.zip
c55ff81ef2934670cb273b5fadd555d932081f2e
  Length      Date    Time    Name
---------  ---------- -----   ----
       18  2017-11-10 22:57   .gitignore
      552  2017-11-10 22:57   README.md
        0  2017-11-10 22:57   client/
      305  2017-11-10 22:57   client/client.ts
      146  2017-11-10 22:57   client/tsconfig.json
      586  2017-11-10 22:57   package.json
        0  2017-11-10 22:57   server/
      488  2017-11-10 22:57   server/app.ts
      195  2017-11-10 22:57   server/tsconfig.json
        0  2017-11-10 22:57   views/
      169  2017-11-10 22:57   views/index.html
---------                     -------
     2459                     11 files

【讨论】:

这样它仍然在zip存档中创建一个文件夹archive,我只需要直接在zip存档中而不是在文件夹中的文件,当我们提取存档时,我们应该直接获取所有文件。我怎样才能做到这一点? 你试过了吗?它不会在 zip 中创建文件夹“存档”,存储库的内容直接在存档中,请参阅imgur.com/a/y1Wm9。 是的,我尝试过:tempdir = tempfile.mkdtemp() # Ensure the file is read/write by the creator only saved_umask = os.umask(0o077) temppath = os.path.join(tempdir) print(temppath) repo = git.Repo.clone_from(func_obj.sc_github, to_path=temppath) with open("archive.zip", "wb") as zipfile: repo.archive(zipfile, format='zip') os.umask(saved_umask) shutil.rmtree(tempdir) 我看不出如何在 zip 中创建“归档”文件夹,考虑到完成这项工作的 repo.archive 命令对归档文件名一无所知。我在答案中发布的 sn-p 功能齐全,您可以运行它并查看它是如何工作的(因为我可以测试您的代码,因为它不是我可以运行的完整示例)。 您的示例代码还在 zip 存档中创建存档文件夹!【参考方案2】:

您正在尝试将 git repo 直接从 git.Repo.clone_from 命令保存到 ZipFile 中。这不起作用,因为 git 库无法立即将 repo 保存到 zip 文件中。您需要做的是选择一个临时路径来保存 repo,然后将该路径提供给zip_archive.write

你想要的是:

tempPath = "/Users/abdul/temp/temp_zip" # you can change this, this is temporary

git.Repo.clone_from(func_obj.sc_github, to_path=os.path.join(tempPath))

files = os.listdir(tempPath)

for singleFile in files:
    zip_archive.write(os.path.join(tempPath, singleFile), singleFile)

# you can now delete the folder at tempPath

代替:

zip_archive.write(git.Repo.clone_from(func_obj.sc_github, to_path=os.path.join(ARCHIVE_NAME)))

您的 git 存储库 (https://github.com/arycloud/sis-testing.git) 的示例输出:

注意:这是 zip 文件的根目录,中间没有目录。这是使用这个确切的代码:

import git, os, zipfile

zip_archive = zipfile.ZipFile("C:\\Users\\Attoa\\Desktop\\testos.zip", "w")

tempPath = "C:\\Users\\Attoa\\AppData\\Local\\Temp\\temp_zip\\" # you can change this, this is temporary

git.Repo.clone_from("https://github.com/arycloud/sis-testing.git", to_path=os.path.join(tempPath))

files = os.listdir(tempPath)

for singleFile in files:
    zip_archive.write(os.path.join(tempPath, singleFile), singleFile)

我希望这会有所帮助!

【讨论】:

我试过这个:tempPath = os.path.join(IGui.settings.BASE_DIR, 'git_source') git.Repo.clone_from(func_obj.sc_github, to_path=os.path.join(tempPath)) zip_archive.write(tempPath) zip_archive.close() 但它没有将刚刚创建的文件夹从桌面克隆到我的项目目录,文件夹在另一个文件夹中,然后是另一个文件夹...... @AbdulRehman 我非常建议您听从我的建议并使用zip_archive.write(tempPath, <github repo name or just a name you like>) 而不仅仅是zip_archive.write(tempPath),但为了更清楚地说明,我需要知道IGui.settings.BASE_DIR 实际上适用于您的代码。 这是我项目的根目录! @AbdulRehman 实际问题是什么? tempPath 的值是多少,随机目录在哪里创建? Repo 已被克隆到 git_source 目录,但现在我需要制作一个 zip 文件,其中包含 git_source 目录中的所有文件,仅文件直接压缩不文件夹,而且我不知道 git_source 目录中有多少文件以及名称是什么?那么,如何通过循环将这些文件添加到我的 zip 存档中?【参考方案3】:

您可以直接从 GitHub 下载存储库的存档,而不是自己创建 zip 文件

您需要调用的网址 是http://github.com/user/repository/archive/master.zip

您可以对标签和分支名称执行相同的操作,方法是将上面 URL 中的 master 替换为分支或标签的名称。

【讨论】:

我需要将它上传到谷歌云存储,它不能作为 blob 上传。

以上是关于在 Python 中从克隆的 GitHub 存储库创建 Zip 存档的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TFS 2017 中从多个来源克隆代码?

使用 hggit 克隆 github 存储库 - 中止:未找到存储库

我从 GitHub 克隆了存储库,但我的本地克隆存储库中缺少提交

克隆 github 存储库

Git:在 git 中克隆远程存储库时无法解决主机 github.com 错误

克隆 GitHub 存储库是啥意思?