git clone的深度是什么意思?

Mac*_*hta 5 git git-clone

我们试图加快工作中的一个软件项目的CI生成速度。在项目生命早期,有人提交了一些(按git的标准)巨大的二进制文件。仅仅为了摆脱它们而重写git的历史似乎太麻烦了,因此我们认为做一个浅表克隆可以避免那些大的早期提交就足够了。

我使用--depth克隆参数进行了一些实验,并遇到了一些奇怪的行为。这是git clone对此的帮助:

--depth <depth>
           Create a shallow clone with a history truncated to the specified number of commits. Implies
           --single-branch unless --no-single-branch is given to fetch the histories near the tips of all
           branches. If you want to clone submodules shallowly, also pass --shallow-submodules.
Run Code Online (Sandbox Code Playgroud)

这将表明<depth>它将等于克隆期间将获取的提交数量,但事实并非如此。这是我尝试不同的深度值时得到的:

| depth   | commit count linux repo | commit count git repo |
|---------|-------------------------|-----------------------|
| 1       | 1                       | 1                     |
| 5       | 15                      | 13                    |
| 10      | 80                      | 46                    |
| 100     | 93133                   | 39552                 |
| 1000    | 788718                  | 53880                 |
Run Code Online (Sandbox Code Playgroud)

对于克隆,我使用了此命令git clone --depth 10 https://github.com/torvalds/linux.gitgit clone --depth 100 https://github.com/git/git.git对于计数提交,我使用了此命令git log --oneline | wc -l。(在工作中,我在GitLab服务器上观察到了同样的情况,因此它不能成为GitHub工作原理的产物。)

有人知道发生了什么吗?深度值如何与下载的实际数据量相对应?我是否错误地理解了文档,或者有错误?

编辑:我添加了第二次回购的结果

Cod*_*ard 22

--depth表示克隆时要获取的提交数量。

默认情况下 git 下载所有分支的所有历史记录。这意味着您的副本将具有所有历史记录,因此您将能够“切换”(签出)到您希望的任何提交。

添加--depth克隆大小限制并仅签出 X 个最后提交

# Cloning a  single branch with the following:
# clone specific branch and limit the history to last X commits
git clone --branch<...> --depth=<X>
Run Code Online (Sandbox Code Playgroud)

深度值如何与实际下载的数据量相对应?使用--depthgit 只会下载给定范围内提交对应的内容,因此当该值较大时,repo 的大小会增加


这表明将等于在该期间将获取的提交数量

并非总是如此,如果这些提交中有任何一个是合并(例如没有快进),您将获得超过 X 次提交。


如何清理你的二进制文件:

重写 git 的历史只是为了摆脱它们似乎太麻烦了

这个工具可以为你做到这一点:

https://rtyley.github.io/bfg-repo-cleaner

### BFG Repo-Cleaner git-filter-branch 的替代品。

BFG 是 git-filter-branch 的更简单、更快速的替代方案,用于清除Git 存储库历史记录中的不良数据:

*** 删除疯狂的大文件***

  • 删除密码、凭据和其他私人数据

示例(来自官方网站) 在所有这些示例中,bfg 是 java -jar bfg.jar 的别名。

# Delete all files named 'id_rsa' or 'id_dsa' :
bfg --delete-files id_{dsa,rsa}  my-repo.git
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但它没有回答问题。我知道有这方面的工具(我什至以前使用过这个工具)。但除非有一种方法可以在不重写历史的情况下做到这一点,否则这对我来说是不行的。 (2认同)

tor*_*rek 6

正如Jonathon Reinhart所说,您正在看到合并的效果。

--depth参数指的是Git从每个起点进行“行走”的深度。正如您引用的文档中提到的那样,它还暗含--single-branch,这简化了对此的讨论。这里的重点是,遍历会访问每个提交的所有父级,对于每个深度级别,如果提交本身是合并的,则不止一个提交。

假设我们有一个如下的提交图:

$ git log --graph --oneline master
* cf68824 profile: fix PATH with GOPATH
* 7c2376b profile: add Ruby gem support
* 95c8270 profile: set GOPATH
* 26a9cc3 vimrc: fiddle with netrw directory display
* 80b88a5 add ruby gems directory to path
[snip]
Run Code Online (Sandbox Code Playgroud)

在这里,每个提交只有一个父对象。如果使用,--depth 3我们将在尖端2处拾取尖端commit cf68824,其父级7c2376b在深度3处拾取95c8270,然后停止,并进行三次提交。

但是,使用Git的Git存储库:

$ git log --graph --oneline master
*   965798d1f2 Merge branch 'es/format-patch-range-diff-fix-fix'
|\  
| * ac0edf1f46 range-diff: always pass at least minimal diff options
* |   5335669531 Merge branch 'en/rebase-consistency'
|\ \  
| * | 6fcbad87d4 rebase docs: fix incorrect format of the section Behavioral Differences
* | | 7e75a63d74 RelNotes 2.20: drop spurious double quote
* | | 7a49e44465 RelNotes 2.20: clarify sentence
[snip]
Run Code Online (Sandbox Code Playgroud)

随着--depth 3我们开始965798d1f2,然后换深度为2拾起双方的父母,ac0edf1f465335669531。为了添加depth-3提交,我们选择了这两个提交的所有父级。的(唯一)父级在ac0edf1f46这里看不到,而的两个父级5335669531是(即6fcbad87d47e75a63d74)。要获取父母的哈希ID,ac0edf1f46我们可以使用:

$ git rev-parse ac0edf1f46^@
d8981c3f885ceaddfec0e545b0f995b96e5ec58f
Run Code Online (Sandbox Code Playgroud)

这样就给了我们六个提交:主提示(当前为合并提交),该提交的两个父级,其中一个父级的一个父级,以及另一个父级的两个父级。

取决于运行Git克隆的确切时间,最尖端master通常不是合并,而是经常以合并作为其直接父级,因此--depth 2通常会得到3次提交,--depth 3因此至少会得到5次提交,具体取决于尖端的两个父母master本身是否合并。

(将以上git rev-parse输出与:

$ git rev-parse 965798d1f2^@
5335669531d83d7d6c905bcfca9b5f8e182dc4d4
ac0edf1f46fcf9b9f6f1156e555bdf740cd56c5f
Run Code Online (Sandbox Code Playgroud)

例如。该^@后缀是指的所有家长承诺,而不是承诺本身。)