GIT浅克隆Sub-Module
写于2022年04月15日

在使用deployer部署站点的时候,那么会执行一条类似 git clone -b "branchName" --depth 1 --recursive git@PATH_TO_GIT RELEASE_PATH 的命令。

但如果项目使用了子模块,会发现子模块并没有执行浅克隆,而是把子模块完整clone到部署目录。

这时候需要把git命令改成 git clone -b "branchName" --depth 1 --shallow-submodules --recursive git@PATH_TO_GIT RELEASE_PATH 就可以浅克隆子模块了。但这个命令要 git 2.9 以上才支持。

所以要做的事情是:

  1. 确认部署服务器上的git版本在2.9以上,CentOS默认应该还在1.8.3版本,版本太低的话,要先升级上去。
  2. 调整deployer脚本,把deploy:update_code这个task里加入--shallow-submodules参数,或是换一个新的task。

参考代码如下,保存为 new_update_code.php,并修改 deploy.php 文件里 task('deploy', function()) 里指定的 deploy:update_code 换成 deploy:new_update_code,完事

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
/* (c) Anton Medvedev <anton@medv.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Deployer;

/**
* Get current git HEAD branch as default branch to deploy.
*/
set('branch', function () {
try {
$branch = runLocally('git rev-parse --abbrev-ref HEAD');
} catch (\Throwable $exception) {
$branch = null;
}

if ($branch === 'HEAD') {
$branch = null; // Travis-CI fix
}

if (input()->hasOption('branch') && !empty(input()->getOption('branch'))) {
$branch = input()->getOption('branch');
}

return $branch;
});

/**
* Whether to use git cache.
*
* Faster cloning by borrowing objects from existing clones.
*/
set('git_cache', function () {
$gitVersion = run('{{bin/git}} version');
$regs = [];
if (preg_match('/((\d+\.?)+)/', $gitVersion, $regs)) {
$version = $regs[1];
} else {
$version = "1.0.0";
}
return version_compare($version, '2.3', '>=');
});
desc('Update code');
task('deploy:new_update_code', function () {
$repository = get('repository');
$branch = get('branch');
$git = get('bin/git');
$gitCache = get('git_cache');
$recursive = get('git_recursive', true) ? '--recursive' : '';
$dissociate = get('git_clone_dissociate', true) ? '--dissociate' : '';
$quiet = isQuiet() ? '-q' : '';
$depth = $gitCache ? '' : '--depth 1';
$options = [
'tty' => get('git_tty', false),
];

$at = '';
if (!empty($branch)) {
$at = "-b \"$branch\"";
}

// If option `tag` is set
if (input()->hasOption('tag')) {
$tag = input()->getOption('tag');
if (!empty($tag)) {
$at = "-b \"$tag\"";
}
}

// If option `tag` is not set and option `revision` is set
if (empty($tag) && input()->hasOption('revision')) {
$revision = input()->getOption('revision');
if (!empty($revision)) {
$depth = '';
}
}

// Enter deploy_path if present
if (has('deploy_path')) {
cd('{{deploy_path}}');
}

if($recursive) {
$recursive .= ' --shallow-submodules';
}

if ($gitCache && has('previous_release')) {
try {
run("$git clone $at $recursive $quiet --reference {{previous_release}} $dissociate $repository {{release_path}} 2>&1", $options);
} catch (\Throwable $exception) {
// If {{deploy_path}}/releases/{$releases[1]} has a failed git clone, is empty, shallow etc, git would throw error and give up. So we're forcing it to act without reference in this situation
run("$git clone $at $recursive $quiet $repository {{release_path}} 2>&1", $options);
}
} else {
// if we're using git cache this would be identical to above code in catch - full clone. If not, it would create shallow clone.
run("$git clone $at $depth $recursive $quiet $repository {{release_path}} 2>&1", $options);
}

if (!empty($revision)) {
run("cd {{release_path}} && $git checkout $revision");
}
});