给出了以下情况。
我的期望是,已经上传的文件不会再使用 git push 上传。但是实际发生的情况是,当创建一个新分支时,所有文件(即使是数千个较小的源文件,而不是一个10 is文件)都会被一次又一次地上传。
git push
我的问题是:如何让Git检测到10 My文件已经上传了?您知道如何解决/修复Git在推送提交时检测服务器上已经存在的对象吗?Git通过它的sha检测文件,因此它应该能够检测到提交树中的某些文件已经存在于服务器上。
可能的用例:我有两个完全不同的分支,但是在这两个分支中共享了一些常见的文件。当我推动一个分支,我不想再上传普通文件时,我推动第二个分支。
实际用例:我使用Python脚本和一些较小的数据集(1MB -10 1MB)做了很多机器学习实验。每次我开始一个实验时,我都会将所有必要的实验文件添加到一个新的Git树中,并在没有分支的新提交中使用该树。该提交将完全免费挂起,然后使用一个新的Git引用(例如,推荐/作业/我的-实验名称)。现在,当我对几乎相同的文件(以及两个引用)进行两次实验时,当我推送这些引用时,Git再次推送所有对象。我的带宽很低,这真的减慢了我的工作速度。
$ mkdir git-test && cd git-test $ git init $ git remote add origin git@gitlab.com:username/projectname.git # create dummy 10MB file $ head -c 10000000 /dev/urandom > dummy $ git add dummy $ git commit -m 'init' # first push, uploads everything - makes sense $ git push origin master Counting objects: 3, done. Delta compression using up to 6 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 9.54 MiB | 1.13 MiB/s, done. Total 3 (delta 0), reused 0 (delta 0) # create new empty branch, not based from master $ git checkout --orphan branch2 # add same files again $ git add dummy $ git commit -m 'init on branch2' # this uploads now again the dummy file (10MB), although the server # has that object alread $ git push origin branch3 Counting objects: 3, done. Delta compression using up to 6 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 9.54 MiB | 838.00 KiB/s, done.
在技术方面,我们有:
回答(我不能再回答了,因为有人把这个标记为副本)。
不幸的是,解决办法并不那么简单。
每次Git想同步两个存储库时,它都会构建一个包文件,其中包含所有必需的对象(比如文件、提交、树)。执行 git push 时,远程将所有现有引用(分支)及其头提交SHA发送到客户端。这就是问题所在: 包协议 不是用于每个对象,而是用于每个提交。因此,根据协议本身,上述解释的行为是正确的。为了解决这个问题,我构建了一个简单的脚本,每个脚本都可以用于基于对象执行 git push ,而不是提交。
你可以在这里找到它: https://github.com/marcj/git-objects-sync
它所做的:
当然,这也有一些缺点,但我在链接的Github存储库中对它们进行了描述。
有了上面的脚本,您现在可以看到以下内容:
marc@osx ~/git-test (branch11*) $ # added new branch11 as explained at the very top