m-git 2.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +85 -0
- data/lib/m-git.rb +66 -0
- data/lib/m-git/argv.rb +170 -0
- data/lib/m-git/argv/opt.rb +38 -0
- data/lib/m-git/argv/opt_list.rb +71 -0
- data/lib/m-git/argv/parser.rb +66 -0
- data/lib/m-git/base_command.rb +271 -0
- data/lib/m-git/command/add.rb +41 -0
- data/lib/m-git/command/branch.rb +90 -0
- data/lib/m-git/command/checkout.rb +106 -0
- data/lib/m-git/command/clean.rb +64 -0
- data/lib/m-git/command/commit.rb +84 -0
- data/lib/m-git/command/config.rb +202 -0
- data/lib/m-git/command/delete.rb +99 -0
- data/lib/m-git/command/fetch.rb +32 -0
- data/lib/m-git/command/forall.rb +81 -0
- data/lib/m-git/command/info.rb +74 -0
- data/lib/m-git/command/init.rb +324 -0
- data/lib/m-git/command/log.rb +73 -0
- data/lib/m-git/command/merge.rb +381 -0
- data/lib/m-git/command/pull.rb +364 -0
- data/lib/m-git/command/push.rb +311 -0
- data/lib/m-git/command/rebase.rb +348 -0
- data/lib/m-git/command/reset.rb +31 -0
- data/lib/m-git/command/self.rb +223 -0
- data/lib/m-git/command/stash.rb +189 -0
- data/lib/m-git/command/status.rb +135 -0
- data/lib/m-git/command/sync.rb +327 -0
- data/lib/m-git/command/tag.rb +67 -0
- data/lib/m-git/command_manager.rb +24 -0
- data/lib/m-git/error.rb +20 -0
- data/lib/m-git/foundation.rb +25 -0
- data/lib/m-git/foundation/constants.rb +107 -0
- data/lib/m-git/foundation/dir.rb +25 -0
- data/lib/m-git/foundation/duration_recorder.rb +92 -0
- data/lib/m-git/foundation/git_message_parser.rb +50 -0
- data/lib/m-git/foundation/lock.rb +32 -0
- data/lib/m-git/foundation/loger.rb +129 -0
- data/lib/m-git/foundation/mgit_config.rb +222 -0
- data/lib/m-git/foundation/operation_progress_manager.rb +139 -0
- data/lib/m-git/foundation/timer.rb +74 -0
- data/lib/m-git/foundation/utils.rb +361 -0
- data/lib/m-git/hooks_manager.rb +96 -0
- data/lib/m-git/manifest.rb +181 -0
- data/lib/m-git/manifest/cache_manager.rb +44 -0
- data/lib/m-git/manifest/internal.rb +182 -0
- data/lib/m-git/manifest/light_repo.rb +108 -0
- data/lib/m-git/manifest/light_repo_generator.rb +87 -0
- data/lib/m-git/manifest/linter.rb +153 -0
- data/lib/m-git/open_api.rb +427 -0
- data/lib/m-git/open_api/script_download_info.rb +37 -0
- data/lib/m-git/output/output.rb +461 -0
- data/lib/m-git/plugin_manager.rb +112 -0
- data/lib/m-git/repo.rb +133 -0
- data/lib/m-git/repo/status.rb +481 -0
- data/lib/m-git/repo/sync_helper.rb +254 -0
- data/lib/m-git/template.rb +9 -0
- data/lib/m-git/template/local_manifest.rb +27 -0
- data/lib/m-git/template/manifest_hook.rb +28 -0
- data/lib/m-git/template/post_download_hook.rb +29 -0
- data/lib/m-git/template/post_hook.rb +31 -0
- data/lib/m-git/template/pre_exec_hook.rb +31 -0
- data/lib/m-git/template/pre_hook.rb +29 -0
- data/lib/m-git/template/pre_push_hook.rb +32 -0
- data/lib/m-git/version.rb +6 -0
- data/lib/m-git/workspace.rb +648 -0
- data/lib/m-git/workspace/path_helper.rb +56 -0
- data/lib/m-git/workspace/workspace_helper.rb +159 -0
- data/m-git +1 -0
- data/mgit +19 -0
- metadata +218 -0
@@ -0,0 +1,181 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
require 'm-git/manifest/light_repo'
|
4
|
+
require 'm-git/manifest/linter'
|
5
|
+
require 'm-git/manifest/internal'
|
6
|
+
|
7
|
+
module MGit
|
8
|
+
|
9
|
+
# Sample: 'm-git/manifest/manifest.sample'
|
10
|
+
#
|
11
|
+
class Manifest
|
12
|
+
include Linter
|
13
|
+
include Internal
|
14
|
+
|
15
|
+
# [Hash] 配置内容
|
16
|
+
attr_reader :config
|
17
|
+
|
18
|
+
# [String] 配置表内容哈希
|
19
|
+
# attr_reader :config_hash
|
20
|
+
attr_reader :hash_sha1
|
21
|
+
|
22
|
+
# [Array<LightRepo>] 与config中‘repositories’字段对应的Manifest::LightRepo对象数组,包含git仓库和非git仓库
|
23
|
+
attr_reader :light_repos
|
24
|
+
|
25
|
+
# [Array<LightRepo>] 类型同light_repos,表示上次操作,但本次未操作的仓库
|
26
|
+
attr_reader :previous_extra_light_repos
|
27
|
+
|
28
|
+
# [LightRepo] 包含配置表的配置仓库
|
29
|
+
attr_reader :config_repo
|
30
|
+
|
31
|
+
# [String] 配置文件路径
|
32
|
+
attr_reader :path
|
33
|
+
|
34
|
+
# [String] 缓存文件路径
|
35
|
+
attr_reader :cache_path
|
36
|
+
|
37
|
+
# [Hash] 上次改动生成的配置缓存
|
38
|
+
attr_reader :previous_config
|
39
|
+
|
40
|
+
# 在mgit根目录中搜索配置文件并根据配置文件生成对应LightRepo对象。
|
41
|
+
#
|
42
|
+
# [!!!!!] 请勿随意修改该接口
|
43
|
+
#
|
44
|
+
# @param root [String] mgit工作区根目录
|
45
|
+
#
|
46
|
+
# @param mgit_managed_only [Boolean] default: false,是否只获取mgit管理的git仓库
|
47
|
+
#
|
48
|
+
# @param only_exist [Boolean] default: false,是否只获取实际存在的仓库
|
49
|
+
#
|
50
|
+
# @param exclude_dummy [Boolean] default: false,是否排除dummy仓库
|
51
|
+
#
|
52
|
+
# @return [Array<LightRepo>] 仓库列表
|
53
|
+
#
|
54
|
+
def self.generate_light_repos(root, mgit_managed_only: false, only_exist:false, exclude_dummy:false)
|
55
|
+
config_path = File.join(root, Constants::PROJECT_DIR[:source_config])
|
56
|
+
config = self.parse(config_path)
|
57
|
+
|
58
|
+
if mgit_managed_only
|
59
|
+
repos = config.repo_list
|
60
|
+
elsif exclude_dummy
|
61
|
+
repos = config.light_repos.select { |repo| !repo.dummy }
|
62
|
+
else
|
63
|
+
repos = config.light_repos
|
64
|
+
end
|
65
|
+
|
66
|
+
if only_exist
|
67
|
+
existing_repos = []
|
68
|
+
repos.each { |repo|
|
69
|
+
abs_path = repo.abs_dest(root)
|
70
|
+
# 被管理的仓库验证是否是git仓库,不被管理的仓库只验证文件夹是否存在
|
71
|
+
if (repo.mgit_excluded && Dir.exist?(abs_path)) || (!repo.mgit_excluded && Repo.is_git_repo?(abs_path))
|
72
|
+
existing_repos.push(repo)
|
73
|
+
end
|
74
|
+
}
|
75
|
+
repos = existing_repos
|
76
|
+
end
|
77
|
+
|
78
|
+
return repos
|
79
|
+
end
|
80
|
+
|
81
|
+
# 全流程校验,除了字段合法性校验外,还包含缓存生成/校验,local配置文件校验/合并
|
82
|
+
#
|
83
|
+
# @param config_path [String] 配置文件本地路径
|
84
|
+
#
|
85
|
+
# @param strict_mode [Boolean] default: true 如果为true,出错直接报错退出,如果为false,出错抛出异常(MGit::Error)
|
86
|
+
#
|
87
|
+
# @return [Manifest] 配置对象
|
88
|
+
#
|
89
|
+
def self.parse(config_path, strict_mode:true)
|
90
|
+
config = Manifest.new
|
91
|
+
config.__setup(config_path, strict_mode)
|
92
|
+
return config
|
93
|
+
end
|
94
|
+
|
95
|
+
# 简单校验,仅校验配置内容,无缓存生成/校验,无local配置文件校验/合并
|
96
|
+
#
|
97
|
+
# @param config_content [String/Hash] 配置表json字符串或字典(key值需为String)
|
98
|
+
#
|
99
|
+
# @param strict_mode [Boolean] default: true 如果为true,出错直接报错退出,如果为false,出错抛出异常(MGit::Error)
|
100
|
+
#
|
101
|
+
# @return [Manifest] 配置对象
|
102
|
+
#
|
103
|
+
def self.simple_parse(config_content, strict_mode:true)
|
104
|
+
config = Manifest.new
|
105
|
+
config.__simple_setup(config_content, strict_mode)
|
106
|
+
return config
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
# 返回所有git仓库列表
|
111
|
+
#
|
112
|
+
# @param selection [Array<String>] default: nil,需要筛选的仓库名数组
|
113
|
+
#
|
114
|
+
# @param exclusion [Array<String>] default: nil,需要排除的仓库名数组
|
115
|
+
#
|
116
|
+
# @param all [Boolean] default: false 若指定为true,则忽略mgit_excluded的字段值,只要remote url存在(即有对应远程仓库),则选取
|
117
|
+
#
|
118
|
+
# @return [Array<LightRepo>] 被mgit管理的仓库生成的LightRepo数组
|
119
|
+
#
|
120
|
+
def repo_list(selection: nil, exclusion: nil, all:false)
|
121
|
+
list = []
|
122
|
+
light_repos.each { |light_repo|
|
123
|
+
if !light_repo.mgit_excluded || (all && !light_repo.url.nil?)
|
124
|
+
# 选取指定仓库
|
125
|
+
if (selection.nil? && exclusion.nil?) ||
|
126
|
+
(!selection.nil? && selection.is_a?(Array) && selection.any? { |e| e.downcase == light_repo.name.downcase }) ||
|
127
|
+
(!exclusion.nil? && exclusion.is_a?(Array) && !exclusion.any? { |e| e.downcase == light_repo.name.downcase })
|
128
|
+
list.push(light_repo)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
}
|
132
|
+
list
|
133
|
+
end
|
134
|
+
|
135
|
+
# 获取全局配置
|
136
|
+
#
|
137
|
+
# @param key [Symbol] 配置字段【符号】
|
138
|
+
#
|
139
|
+
# @return [Object] 对应配置字段的值,可能是字符串,也可能是字典
|
140
|
+
#
|
141
|
+
def global_config(key)
|
142
|
+
key_str = Constants::CONFIG_KEY[key]
|
143
|
+
value = config[key_str]
|
144
|
+
terminate!("无法获取多仓库配置必需字段\"#{key}\"的值!") if value.nil? && Constants::REQUIRED_CONFIG_KEY.include?(key_str)
|
145
|
+
value
|
146
|
+
end
|
147
|
+
|
148
|
+
# 更新缓存
|
149
|
+
#
|
150
|
+
# @param root [String] 多仓库根目录
|
151
|
+
#
|
152
|
+
# @param config_content [Hash] 配置Hash
|
153
|
+
#
|
154
|
+
def update_cache_with_content(root, config_content)
|
155
|
+
config_dir = File.join(root, Constants::PROJECT_DIR[:source_config])
|
156
|
+
cache_path = File.join(config_dir, Constants::CONFIG_FILE_NAME[:manifest_cache])
|
157
|
+
sha1 = __generate_hash_sha1(config_content.to_json)
|
158
|
+
CacheManager.save_to_cache(cache_path, sha1, config_content)
|
159
|
+
end
|
160
|
+
|
161
|
+
# 更新(对比上次操作)冗余的轻量仓库对象
|
162
|
+
#
|
163
|
+
# @param root [String] 多仓库根目录
|
164
|
+
#
|
165
|
+
def update_previous_extra_light_repos(root)
|
166
|
+
cache_path = File.join(root, Constants::PROJECT_DIR[:source_config], Constants::CONFIG_FILE_NAME[:manifest_cache])
|
167
|
+
__load_cache(cache_path)
|
168
|
+
end
|
169
|
+
|
170
|
+
def terminate!(msg, type:nil)
|
171
|
+
if @strict_mode
|
172
|
+
Foundation.help!(msg)
|
173
|
+
else
|
174
|
+
raise Error.new(msg, type:type)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
RepoConfig = Manifest
|
181
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module MGit
|
3
|
+
class Manifest
|
4
|
+
class CacheManager
|
5
|
+
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :hash_sha1
|
8
|
+
attr_reader :hash_data
|
9
|
+
|
10
|
+
def load_path(cache_path)
|
11
|
+
return unless File.exist?(cache_path)
|
12
|
+
begin
|
13
|
+
cache = JSON.parse(File.read(cache_path))
|
14
|
+
rescue => _
|
15
|
+
Output.puts_fail_message("配置文件缓存解析失败!将根据原配置文件进行仓库配置。")
|
16
|
+
end
|
17
|
+
|
18
|
+
@path = cache_path
|
19
|
+
@hash_sha1 = cache[Constants::CONFIG_CACHE_KEY[:hash]]
|
20
|
+
@hash_data = cache[Constants::CONFIG_CACHE_KEY[:cache]]
|
21
|
+
end
|
22
|
+
|
23
|
+
# 缓存配置文件
|
24
|
+
#
|
25
|
+
# @param cache_path [string] 配置文件目录
|
26
|
+
#
|
27
|
+
# @param hash_sha1 [String] 配置哈希字符串
|
28
|
+
#
|
29
|
+
# @param hash_data [Hash] 配置字典
|
30
|
+
#
|
31
|
+
def self.save_to_cache(cache_path, hash_sha1, hash_data)
|
32
|
+
FileUtils.mkdir_p(File.dirname(cache_path))
|
33
|
+
File.open(cache_path, 'w') do |file|
|
34
|
+
file.write({
|
35
|
+
Constants::CONFIG_CACHE_KEY[:hash] => hash_sha1,
|
36
|
+
Constants::CONFIG_CACHE_KEY[:cache] => hash_data
|
37
|
+
}.to_json)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
|
2
|
+
require 'm-git/manifest/cache_manager'
|
3
|
+
|
4
|
+
module MGit
|
5
|
+
class Manifest
|
6
|
+
module Internal
|
7
|
+
|
8
|
+
|
9
|
+
# 配置对象
|
10
|
+
#
|
11
|
+
# @param config_path [String] 配置文件路径或目录
|
12
|
+
#
|
13
|
+
# @param strict_mode [Boolean] 是否使用严格模式。在严格模式下,出错将终止执行。在非严格模式下,出错将抛出异常,程序有机会继续执行。
|
14
|
+
#
|
15
|
+
def __setup(config_path, strict_mode)
|
16
|
+
@strict_mode = strict_mode
|
17
|
+
if File.directory?(config_path)
|
18
|
+
config_dir = config_path
|
19
|
+
config_path = File.join(config_dir, Constants::CONFIG_FILE_NAME[:manifest])
|
20
|
+
else
|
21
|
+
config_dir = File.dirname(config_path)
|
22
|
+
config_path = File.join(config_dir, File.basename(config_path))
|
23
|
+
end
|
24
|
+
|
25
|
+
local_path = File.join(config_dir, Constants::CONFIG_FILE_NAME[:local_manifest])
|
26
|
+
cache_path = File.join(config_dir, Constants::CONFIG_FILE_NAME[:manifest_cache])
|
27
|
+
|
28
|
+
__load_config(config_path, local_config_path: local_path, cache_path: cache_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
# 简单配置对象,部分属性为nil
|
32
|
+
#
|
33
|
+
# @param config_content [Hash] 配置Hash
|
34
|
+
#
|
35
|
+
# @param strict_mode [Boolean] 是否使用严格模式。在严格模式下,出错将终止执行。在非严格模式下,出错将抛出异常,程序有机会继续执行。
|
36
|
+
#
|
37
|
+
def __simple_setup(config_content, strict_mode)
|
38
|
+
@strict_mode = strict_mode
|
39
|
+
|
40
|
+
if config_content.is_a?(Hash)
|
41
|
+
@config = config_content.deep_clone
|
42
|
+
else
|
43
|
+
@config = JSON.parse(config_content)
|
44
|
+
end
|
45
|
+
lint_raw_json!(config)
|
46
|
+
|
47
|
+
@light_repos = __generate_light_repos(config)
|
48
|
+
@config_repo = light_repos.find { |light_repo| light_repo.is_config_repo }
|
49
|
+
|
50
|
+
# 计算配置文件哈希
|
51
|
+
@hash_sha1 = __generate_hash_sha1(config.to_json)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def cache_manager
|
58
|
+
@cache_manager ||= CacheManager.new
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# 加载配置文件
|
63
|
+
#
|
64
|
+
def __load_config(config_path, config_content: nil, local_config_path: nil, cache_path: nil)
|
65
|
+
if config_content
|
66
|
+
config_hash = __parse_manifest_json(config_content)
|
67
|
+
else
|
68
|
+
# 校验配置文件路径
|
69
|
+
lint_manifest_path(config_path)
|
70
|
+
|
71
|
+
# 读取配置文件
|
72
|
+
config_hash = __parse_manifest(config_path)
|
73
|
+
end
|
74
|
+
|
75
|
+
lint_raw_json!(config_hash)
|
76
|
+
|
77
|
+
if local_config_path && File.exist?(local_config_path)
|
78
|
+
lint_local_manifest_path(local_config_path)
|
79
|
+
local_config_hash = __parse_manifest(local_config_path)
|
80
|
+
|
81
|
+
__merge_manifest_hash(config_hash, local_config_hash)
|
82
|
+
end
|
83
|
+
|
84
|
+
@light_repos = __generate_light_repos(config_hash)
|
85
|
+
@config_repo = light_repos.find { |light_repo| light_repo.is_config_repo }
|
86
|
+
lint_light_repos!
|
87
|
+
|
88
|
+
@path = config_path
|
89
|
+
@config = config_hash
|
90
|
+
# 计算配置文件哈希
|
91
|
+
@hash_sha1 = __generate_hash_sha1(config_hash.to_json)
|
92
|
+
|
93
|
+
__load_cache(cache_path)
|
94
|
+
if previous_config.nil? || previous_config != config_hash
|
95
|
+
# 更新缓存
|
96
|
+
@cache_path = cache_path
|
97
|
+
@previous_config = config
|
98
|
+
CacheManager.save_to_cache(cache_path, hash_sha1, config)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def __load_cache(cache_path)
|
103
|
+
if cache_path && File.exist?(cache_path)
|
104
|
+
cache_manager.load_path(cache_path)
|
105
|
+
@cache_path = cache_manager.path
|
106
|
+
@previous_config = cache_manager.hash_data
|
107
|
+
|
108
|
+
@previous_extra_light_repos = __generate_extra_light_repos(config, previous_config)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def __parse_manifest_json(raw_string)
|
113
|
+
begin
|
114
|
+
raw_json = JSON.parse(raw_string)
|
115
|
+
rescue => _
|
116
|
+
terminate!("manifest文件解析错误,请检查json文件格式是否正确!")
|
117
|
+
end
|
118
|
+
|
119
|
+
raw_json
|
120
|
+
end
|
121
|
+
|
122
|
+
def __parse_manifest(path)
|
123
|
+
begin
|
124
|
+
raw_string = File.read(path)
|
125
|
+
rescue => e
|
126
|
+
terminate!("配置文件#{path}读取失败:#{e.message}")
|
127
|
+
end
|
128
|
+
__parse_manifest_json(raw_string)
|
129
|
+
end
|
130
|
+
|
131
|
+
def __generate_light_repos(config_hash)
|
132
|
+
light_repos = []
|
133
|
+
repositories = config_hash[Constants::CONFIG_KEY[:repositories]]
|
134
|
+
repositories.each do |repo_name, repo_cfg|
|
135
|
+
light_repos << LightRepoGenerator.light_repo_with(repo_name, repo_cfg, config_hash)
|
136
|
+
end
|
137
|
+
light_repos
|
138
|
+
end
|
139
|
+
|
140
|
+
def __generate_extra_light_repos(current_hash, previous_hash)
|
141
|
+
return if previous_hash.nil?
|
142
|
+
extra_light_repos = []
|
143
|
+
repositories = current_hash[Constants::CONFIG_KEY[:repositories]]
|
144
|
+
previous_repos = previous_hash[Constants::CONFIG_KEY[:repositories]]
|
145
|
+
extra_keys = previous_repos.keys - repositories.keys
|
146
|
+
extra_keys.each do |repo_name|
|
147
|
+
extra_light_repos << LightRepoGenerator.light_repo_with(repo_name, previous_repos[repo_name], previous_hash)
|
148
|
+
end
|
149
|
+
extra_light_repos
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
# 计算配置文件的哈希
|
154
|
+
def __generate_hash_sha1(json_string)
|
155
|
+
begin
|
156
|
+
return Digest::SHA256.hexdigest(json_string)
|
157
|
+
rescue => e
|
158
|
+
terminate!("配置文件哈希计算失败:#{e.message}")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def __merge_manifest_hash(base_hash, attach_hash)
|
163
|
+
dict = base_hash
|
164
|
+
attach_hash.each { |key, value|
|
165
|
+
if key == Constants::CONFIG_KEY[:repositories] && value.is_a?(Hash)
|
166
|
+
dict[key] = {} if dict[key].nil?
|
167
|
+
value.each { |repo_name, config|
|
168
|
+
dict[key][repo_name] = {} if dict[key][repo_name].nil?
|
169
|
+
if config.is_a?(Hash)
|
170
|
+
config.each { |r_key, r_value|
|
171
|
+
dict[key][repo_name][r_key] = r_value if Constants::REPO_CONFIG_KEY.values.include?(r_key)
|
172
|
+
}
|
173
|
+
end
|
174
|
+
}
|
175
|
+
elsif Constants::CONFIG_KEY.values.include?(key)
|
176
|
+
dict[key] = value
|
177
|
+
end
|
178
|
+
}
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
require_relative 'light_repo_generator'
|
4
|
+
|
5
|
+
module MGit
|
6
|
+
class Manifest
|
7
|
+
# @!scope manifest.json 配置的reponsitories 对象
|
8
|
+
# 该类用于配置解析后的初步处理,其字段与配置文件一致,但不保证与本地仓库状态一致。
|
9
|
+
# 而Repo类则会校验本地仓库,其状态与本地仓库状态一致,主要用于执行多仓库操作。
|
10
|
+
#
|
11
|
+
LightRepo = Struct.new(
|
12
|
+
# [String] 仓库名
|
13
|
+
:name,
|
14
|
+
|
15
|
+
# [String] 仓库相对mgit根目录的存放路径(完整路径如:<.mgit所在路径>/path/<repo_name>),或绝对路径(指定abs-dest)
|
16
|
+
# 绝对路径
|
17
|
+
:path,
|
18
|
+
|
19
|
+
# [String] 仓库配置分支
|
20
|
+
:branch,
|
21
|
+
|
22
|
+
# [String] 仓库配置commit id
|
23
|
+
:commit_id,
|
24
|
+
|
25
|
+
# [String] 仓库配置tag
|
26
|
+
:tag,
|
27
|
+
|
28
|
+
# [String] 仓库的git地址
|
29
|
+
:url,
|
30
|
+
|
31
|
+
# [Boolean] 是否纳入mgit管理
|
32
|
+
:mgit_excluded,
|
33
|
+
|
34
|
+
# [Boolean] 是否是占位仓库【2.3.0废弃】
|
35
|
+
:dummy,
|
36
|
+
|
37
|
+
# [Boolean] 是否是配置仓库(包含配置表的仓库),若是,则某些操作如merge,checkout等会优先操作配置仓库,确保配置表最新
|
38
|
+
:is_config_repo,
|
39
|
+
|
40
|
+
# [Boolean] 是否锁定仓库(即任何操作均保证仓库状态与指定配置一致)
|
41
|
+
:lock
|
42
|
+
) do
|
43
|
+
|
44
|
+
# 根据解析内容拼接一个clone地址
|
45
|
+
#
|
46
|
+
# @param root [String] mgit根目录
|
47
|
+
# @param local_url [String] default: nil 如果从本地clone,可传入一个本地的xxx.git实体地址
|
48
|
+
#
|
49
|
+
# @return [String] clone地址
|
50
|
+
#
|
51
|
+
def clone_url(root, local_url:nil, clone_branch:nil)
|
52
|
+
url = local_url.nil? ? self.url : local_url
|
53
|
+
|
54
|
+
if !clone_branch.nil? && Utils.branch_exist_on_remote?(clone_branch, url)
|
55
|
+
branch_opt = "-b #{clone_branch}"
|
56
|
+
elsif !self.branch.nil? && Utils.branch_exist_on_remote?(self.branch, url)
|
57
|
+
branch_opt = "-b #{self.branch}"
|
58
|
+
else
|
59
|
+
branch_opt = ''
|
60
|
+
end
|
61
|
+
|
62
|
+
"git clone #{branch_opt} -- #{url} #{abs_dest(root)}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# 生成绝对路径
|
66
|
+
#
|
67
|
+
# @param root [String] 多仓库根目录
|
68
|
+
#
|
69
|
+
# @return [String] 仓库绝对路径
|
70
|
+
#
|
71
|
+
def abs_dest(root)
|
72
|
+
Utils.expand_path(self.path, base:root)
|
73
|
+
end
|
74
|
+
|
75
|
+
# 生成.git存储的完整路径
|
76
|
+
#
|
77
|
+
# @param root [String] 多仓库根目录
|
78
|
+
#
|
79
|
+
# @return [String] .git存储的完整路径
|
80
|
+
#
|
81
|
+
def git_store_dir(root)
|
82
|
+
# 替换key值中的‘/’字符,避免和路径混淆
|
83
|
+
name = self.name.gsub(/\//,':')
|
84
|
+
|
85
|
+
# 删除冗余字符
|
86
|
+
url = Utils.normalize_url(self.url)
|
87
|
+
|
88
|
+
git_store = Utils.generate_git_store(root, url)
|
89
|
+
if git_store.nil?
|
90
|
+
git_dir = File.join(root, Constants::PROJECT_DIR[:source_git])
|
91
|
+
git_store = File.join(git_dir, name)
|
92
|
+
end
|
93
|
+
|
94
|
+
git_store
|
95
|
+
end
|
96
|
+
|
97
|
+
# 生成缓存存放完整路径
|
98
|
+
#
|
99
|
+
# @param root [String] 多仓库根目录
|
100
|
+
#
|
101
|
+
# @return [String] 缓存存放完整路径
|
102
|
+
#
|
103
|
+
def cache_store_dir(root)
|
104
|
+
File.join(git_store_dir(root), 'cache')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|