【问题标题】:Is it possible to add a file to a git repo without having it checked out locally?是否可以将文件添加到 git repo 而无需在本地签出?
【发布时间】:2011-12-24 16:28:00
【问题描述】:

目标:将新文件添加到远程 git 存储库,而无需在本地检查整个文件。

为什么: 我正在构建一个将文件添加到用户的 git 存储库的应用程序。其中一些存储库将是数百兆。有些人会很少接触。我想避免占用 TB 的磁盘空间来保持检查不会经常触及的大型存储库,并且我不想招致签出 200Mb 存储库(大量二进制文件)的不可避免的延迟,以便向其中添加一个新文件并将该文件推回原点。

我假设默认的 git 客户端不能执行此操作,但我希望有人编写了可以提交到远程 repo(不关心什么语言)的东西,而无需在本地检查整个内容。 Cloud9 IDE 会做这样的事情吗?

该应用程序可以通过 SSH 或 GitHub 用于 oAuthed 应用程序以调整 repos 的任何机制来完全访问用户 git repo。

【问题讨论】:

    标签: git github


    【解决方案1】:

    根据存储库的结构,您可以使用稀疏签出来避免下载大文件:

    http://schacon.github.com/git/git-read-tree.html#_sparse_checkout

    (更多信息Checkout subdirectories in Git?

    【讨论】:

    • 这是一个好主意,但似乎稀疏签出通过在本地签出整个(压缩)存储库来工作,但只将其中的一部分放入工作树中。对?除非我理解错了。在这种情况下,我仍然需要为压缩的 repo 分配存储空间,在许多情况下,由于二进制文件(如 jpeg)在 git gzip 压缩它们之前已经对它们进行了适当的压缩,因此在许多情况下它仍然是数百兆。
    • 如果是这样的话,也许submodules 是要走的路。
    【解决方案2】:

    Git 有几个用于浅克隆和特定文件路径的部分克隆的选项,但这些选项不可推送。

    这里的技巧是在您结帐时使用 --lightweight 标志 - 在这种情况下,您将能够推送到有限的存储库。

    但是,这些解决方案似乎非常不理想......似乎更直观,如果应用程序具有对 git 存储库的编程访问权限,那么您应该能够创建或要求在安装时创建特定的 git 项目根据您的应用程序的需要,它是空的。

    【讨论】:

    • 浅克隆没有帮助,因为在许多情况下,即使没有历史记录,这些也将是数百兆。我不太赞同你关于空仓库的想法,因为这里的目标是向填充的仓库添加一个有用的文件。
    • 我想你可能就在这里。我现在开始意识到您的问题有多么困难.. 因为 git 旨在在本地维护整个 repo,这与您的需求背道而驰..
    【解决方案3】:

    如果您对 repos 有 shell 访问权限,您可以创建一个快速导入文件(有关文件格式的详细信息,请参阅 git-fast-import 的手册页),并在远程存储库中执行 git fast-import

    当您没有 shell 访问权限时,解决方案会更加hackier。您需要执行以下任务才能将更改推送到远程仓库:

    • 创建所有文件的内容(=生成新文件的哈希,并找到未更改文件的哈希[从当前树中获取])
    • 创建树
    • 创建提交
    • 推送新文件内容、树并提交到远程仓库
    • 将分支移动推送到服务器

    我会从 hg-git 扩展名开始,因为我猜有些代码可以做类似的事情。

    【讨论】:

    • hg-git 是一个好的开始,但事实证明 Dulwich(用 Python 实现的 git)是在那里进行所有真正的 git 交互的库,那里的(相当少的)文档让我终极解决方案。对于任何希望直接与 Python Dulwich 的 git repos 交互的人来说,这似乎是一个潜在的好解决方案。有点像 Ruby 的 Grit,除了 Grit 缺乏的远程支持。
    【解决方案4】:

    警告:以下答案不再适用于最新版本的 Git

    (我愿意接受有关如何使用当前 git 版本进行这项工作的建议。)

    事实证明,答案非常简单,证明了 Git 是多么的棒。

    • 创建一个全新的 git 存储库。
    • 添加新文件并将其提交给它。
    • 告诉新仓库远程仓库在哪里(git remote add ...)
    • 推送到远程仓库。

    注意:远程仓库必须是裸仓库或将 receive.denyCurrentBranch 设置为“ignore”或“warn”

    这是基于以下假设:您添加的文件是新的,并且不会与 repo 中的任何其他文件冲突。

    远程存储库的现有内容无关紧要,只要您可以确定不会与任何内容发生冲突。

    附:感谢所有发布潜在解决方法的人。

    【讨论】:

    • 我在 github 上试过,但没有用。我收到“更新被拒绝,因为遥控器包含您所做的工作。”重现步骤:gist.github.com/chris-gunawardena/c88a0d11e0e59368ec45
    • 随着 git 的更新版本,情况似乎发生了变化。我在答案中注意到了这一点。谢谢你的例子。我创建了不需要 github 测试的 an annotated example of your gist。我已经尝试了几件事,但还没有想出一个可行的解决方案。将在/如果我这样做时更新这张票。
    【解决方案5】:

    第二个轻量级存储库如何,只包含您需要添加的文件,其末端的脚本可以检查存储库并添加您的文件。该脚本还可以从您的新存储库中删除使用的文件以保持轻量级。

    【讨论】:

    • 这听起来像是一种解决方法,但我正在尝试创建一些不需要在存储库上/周围进行任何特殊操作的东西,文件最终将被添加到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 2019-07-21
    • 2018-02-13
    • 2017-07-18
    • 2012-01-21
    • 2022-12-25
    • 2014-04-23
    相关资源
    最近更新 更多