将内容添加到Git裸仓库

5

我知道如果在裸仓库中有文件,可以使用 git show HEAD:path/to/file 来访问它们。

但是,我能否在不克隆和修改工作树的情况下向裸仓库添加新内容呢?


1
你可以使用低级别的git命令来构建提交,这是一种完全正当的方式,但很少比方便命令更好;而且你可以不使用工作树来完成,甚至有很多选项可供选择,但选择合理的方法取决于你想要构建的历史记录与已有历史记录之间的关系。那么,请问你在什么情况下提出这个问题? - jthill
该git仓库的内容是小文件,有一天可能会达到数百万个。虽然我知道随着事物变得越来越大,性能成本会增加,但在服务器上运行这些数百万个小文件和文件夹的担忧并不好。使用裸仓库可以缓解一些问题,同时也在寻找替代方案。 - Tom J Nowell
一个单独的提交可能包含数百万个文件,你通常不希望一次检出所有这些文件,对吧?好的,这非常有帮助。下一个问题是:你是想避免那个庞大的检出操作,所以才需要 no-clone 要求吗?要更新一个仓库,你必须在同一文件系统上或者推送到它,唯一剩下的问题是在哪里做这项工作以及提交结构的细节方面的权衡。 - jthill
每个文件都有一个相关的提交记录,它们只会被添加/读取,从不被删除/修改。目前主要关注的问题是具有大量文件/文件夹树的文件系统和磁盘性能。 - Tom J Nowell
好的。Git被设计成可扩展到这样的领域,再次强调,这只是一个如何继续的最佳方式的问题,所以,如果您不想检出所有文件,是否有理由让每个提交都包含它们?...但是,实际上,这里有足够多的问题,我认为对系统进行相当完整的叙述描述以及您当前如何看待Git适合其中将是最快的,然后我们将能够更清楚地了解您的起点并建议下一步操作。 - jthill
看起来我需要创建一个 blob 对象,将其附加到树上,然后将该树对象附加到提交中。虽然我怀疑我不会在我的项目中使用它,但我仍然很好奇原始问题的确切解决方法。(如果我添加1个文件,那么只有这1个文件在该提交中,也就是说我们添加了一些新内容并且现在已经确定下来。使用 git 的目的是让我可以使用 push/pull/remote 来同步数据,同时使用每台机器上已经可用的工具。) - Tom J Nowell
1个回答

7
如果我添加了一个文件,那么在提交中只会有这个文件,也就是说我们添加了新东西并将其固定下来。在裸仓库的主分支顶部添加单个文件提交有几种方便的方法。因此看起来我需要创建一个 blob 对象,将其附加到一个树上,然后将该树对象附加到提交中。所有提交任何内容的方式都归结为这样做,只是问题在于方便命令如何适合您的目的。git add 创建一个 blob 并在索引中为其创建一个条目;git commit 做了一个 git write-tree,用于添加索引中内容的任何新树,以及一个 git commit-tree,用于添加最终树的顶层提交,以及一个 git update-ref 以使 HEAD 保持最新。裸仓库通常有一个 HEAD 提交,通常附加到(即符号 ref)像 master 这样的分支上。所以 git 的方便命令已经几乎完全做到了你想要的。特别是只有一个文件时,这将非常容易。例如,假设您的文件位于 ~server/data/logs/,您用于分发的裸仓库位于 ~server/repo.git,您希望提交的文件位于仓库中的 data/logs,并且您始终希望提交最新的日志文件:
#!/bin/sh
cd ~server

# supply locations git ordinarily does on its own in working i.e. non-bare repos:

export GIT_DIR=$PWD/repo.git                  # bare repos don't have defaults for these
export GIT_WORK_TREE=$PWD                     # so supply some to suit our purpose
export GIT_INDEX_FILE=$GIT_DIR/scratch-index  # ...

# payload:  commit (only) the latest file in data/logs:

git read-tree --empty                       # make the index all pretty, and 
git add data/logs/`ls -1t data/logs|sed q`  # everything's ordinary from here - add and 
git commit -m'new logfile'                  # commit

git read-tree 从提交的树中加载索引条目。它是 checkout、merge 和 reset 的基础,可能还有一些我暂时忘记的功能。在这里,我们只想要一个空的索引来开始,因此使用 --empty

使用 push/pull/remote 同步数据,同时使用每台机器上已经可用的工具

你说过随着时间的推移会有“数百万”个文件,如果你不想分发完整的历史记录,那么像你已经怀疑的那样,rsync 可能是更好的选择。但是,如果每分钟只传输一个新文件,那么累积一百万个文件需要两年时间。所以,?

无论如何,上述过程对于每次提交的小规模文件非常高效可扩展。对于大量工作,有更好的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接