m-git 2.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|