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,73 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module MGit
|
4
|
+
|
5
|
+
# @!scope 查询多仓库的日志
|
6
|
+
#
|
7
|
+
class Log < BaseCommand
|
8
|
+
|
9
|
+
OPT_LIST = {
|
10
|
+
:number => '--number',
|
11
|
+
:number_s => '-n'
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def options
|
15
|
+
return [
|
16
|
+
ARGV::Opt.new(OPT_LIST[:number], short_key:OPT_LIST[:number_s], default:500, info:"指定需要显示的提交log个数,默认500。", type: :string)
|
17
|
+
].concat(super)
|
18
|
+
end
|
19
|
+
|
20
|
+
def revise_option_value(opt)
|
21
|
+
opt.value = Integer(opt.value) if opt.key == OPT_LIST[:number]
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute(argv)
|
25
|
+
repo_name = parse_repo_name(argv)
|
26
|
+
repo = all_repos.find { |e| e.name.downcase == repo_name.downcase }
|
27
|
+
number = argv.opt(OPT_LIST[:number]).value
|
28
|
+
if repo.nil?
|
29
|
+
Output.puts_fail_message("未找到与输入仓库名\"#{repo_name}\"匹配的仓库,请重试!") && return
|
30
|
+
return
|
31
|
+
end
|
32
|
+
# print(Output.processing_message("正在提取#{repo.name}最新的#{number}条log信息..."))
|
33
|
+
success, output = repo.execute_git_cmd(argv.cmd, "-n #{number}")
|
34
|
+
if success
|
35
|
+
if output.length > 0
|
36
|
+
Output.puts_in_pager(output.gsub(/commit.*/) { |s| Output.yellow_message(s) })
|
37
|
+
# print("\r")
|
38
|
+
else
|
39
|
+
Output.puts_remind_message("无提交记录")
|
40
|
+
end
|
41
|
+
else
|
42
|
+
Output.puts_fail_message("执行失败:#{output}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_repo_name(argv)
|
47
|
+
return nil if argv.git_opts.nil?
|
48
|
+
repo = argv.git_opts.split(' ')
|
49
|
+
extra_opts = repo.select { |e| argv.is_option?(e) }
|
50
|
+
Foundation.help!("输入非法参数:#{extra_opts.join(',')}。请通过\"mgit #{argv.cmd} --help\"查看用法。") if extra_opts.length > 0
|
51
|
+
Foundation.help!("未输入查询仓库名!请使用这种形式查询:mgit log some_repo") if repo.length == 0
|
52
|
+
Foundation.help!("仅允许查询一个仓库!") if repo.length > 1
|
53
|
+
repo.first
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_integer?(string)
|
57
|
+
true if Integer(string) rescue false
|
58
|
+
end
|
59
|
+
|
60
|
+
def enable_short_basic_option
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.description
|
65
|
+
"输出指定(单个)仓库的提交历史。"
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.usage
|
69
|
+
"mgit log <repo> [-n] [-h]"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,381 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module MGit
|
4
|
+
|
5
|
+
# @!scope 类似 git merge
|
6
|
+
#
|
7
|
+
class Merge < BaseCommand
|
8
|
+
|
9
|
+
PROGRESS_STAGE = {
|
10
|
+
:new_start => 0,
|
11
|
+
:did_pull_config => 1,
|
12
|
+
:did_refresh_config => 2,
|
13
|
+
:did_pull_sub => 3
|
14
|
+
}.freeze
|
15
|
+
PROGRESS_STAGE_KEY = 'progress_stage'
|
16
|
+
|
17
|
+
PROGRESS_AUTO = 'auto_exec'
|
18
|
+
|
19
|
+
OPT_LIST = {
|
20
|
+
:pull => '--pull'
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
def options
|
24
|
+
return [
|
25
|
+
ARGV::Opt.new(OPT_LIST[:pull], info:'可选参数,指定后在合并仓库前会自动拉取远程分支更新代码,否则会有交互式询问。如:"mgit merge --pull"。', type: :boolean)
|
26
|
+
].concat(super)
|
27
|
+
end
|
28
|
+
|
29
|
+
def __progress_type
|
30
|
+
OperationProgressManager::PROGRESS_TYPE[:merge]
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute(argv)
|
34
|
+
return if do_abort(argv)
|
35
|
+
|
36
|
+
Workspace.check_branch_consistency
|
37
|
+
|
38
|
+
Output.puts_start_cmd
|
39
|
+
|
40
|
+
config_repo = generate_config_repo
|
41
|
+
|
42
|
+
if mgit_try_to_continue?
|
43
|
+
# 不处于中间态禁止执行
|
44
|
+
Foundation.help!("当前并不处于操作中间态,无法进行continue操作!") if !OperationProgressManager.is_in_progress?(Workspace.root, __progress_type)
|
45
|
+
|
46
|
+
# 读取指令缓存失败禁止执行
|
47
|
+
context, _ = OperationProgressManager.load_context(Workspace.root, __progress_type)
|
48
|
+
Foundation.help!("缓存指令读取失败,continue无法继续进行,请重新执行完整指令。") if context.nil? || !context.validate?
|
49
|
+
|
50
|
+
# 分支不匹配禁止执行
|
51
|
+
Foundation.help!("当前主仓库所在分支跟上次操作时所在分支(#{context.branch})不一致,请切换后重试。") if config_repo.status_checker.current_branch(use_cache:true) != context.branch
|
52
|
+
|
53
|
+
if !context.repos.nil?
|
54
|
+
Output.puts_processing_message("加载上次即将操作的子仓库...")
|
55
|
+
Workspace.update_all_repos(context.repos)
|
56
|
+
end
|
57
|
+
|
58
|
+
cmd = context.cmd
|
59
|
+
opts = context.opts
|
60
|
+
config_error = continue_execute(cmd, opts, config_repo, context.other[PROGRESS_STAGE_KEY], context.other[PROGRESS_AUTO])
|
61
|
+
if config_error
|
62
|
+
Output.puts_fail_block([config_repo.name], "主仓库操作失败:#{config_error}")
|
63
|
+
return
|
64
|
+
end
|
65
|
+
else
|
66
|
+
# 处于中间态则提示
|
67
|
+
if OperationProgressManager.is_in_progress?(Workspace.root, __progress_type)
|
68
|
+
if Output.continue_with_user_remind?("当前处于操作中间态,建议取消操作并执行\"mgit merge --continue\"继续操作未完成仓库。\n 继续执行将清除中间态并重新操作所有仓库,是否取消?")
|
69
|
+
Output.puts_cancel_message
|
70
|
+
return
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
cmd = argv.cmd
|
75
|
+
opts = argv.git_opts
|
76
|
+
if !opts.include?('--continue') && !opts.include?('--abort')
|
77
|
+
# 自动添加--no-ff
|
78
|
+
if !opts.include?('--no-ff') && !opts.include?('--ff') && !opts.include?('--ff-only') && !opts.include?('--squash')
|
79
|
+
opts += ' --no-ff'
|
80
|
+
end
|
81
|
+
|
82
|
+
# 检测提示
|
83
|
+
if !opts.include?('--no-commit') &&
|
84
|
+
!opts.include?('--commit') &&
|
85
|
+
!opts.include?('-m ') &&
|
86
|
+
Output.continue_with_user_remind?("未添加\"-m\"或\"--no-commit\",建议使用:\n 1. mgit merge <branch> -m \"xxx comment...\"\n 2. 或 mgit merge <branch> --no-commit\n 更新本次提交的comment,是否取消并重新输入?")
|
87
|
+
|
88
|
+
Output.puts_cancel_message
|
89
|
+
return
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# 优先操作配置仓库
|
95
|
+
config_error = merge_config_repo(cmd, opts, config_repo, argv.opt_list.did_set_opt?(OPT_LIST[:pull]))
|
96
|
+
if config_error
|
97
|
+
Output.puts_fail_block([config_repo.name], "主仓库操作失败:#{config_error}")
|
98
|
+
return
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
do_repos = []
|
103
|
+
dirty_repos = []
|
104
|
+
detached_repos = []
|
105
|
+
no_tracking_repos = []
|
106
|
+
|
107
|
+
Output.puts_processing_message("检查各仓库状态...")
|
108
|
+
Workspace.serial_enumerate_with_progress(all_repos) { |repo|
|
109
|
+
next if !config_repo.nil? && repo.name == config_repo.name
|
110
|
+
|
111
|
+
status = repo.status_checker.status
|
112
|
+
branch_status = repo.status_checker.branch_status
|
113
|
+
|
114
|
+
if status == Repo::Status::GIT_REPO_STATUS[:clean] &&
|
115
|
+
branch_status != Repo::Status::GIT_BRANCH_STATUS[:detached] &&
|
116
|
+
branch_status != Repo::Status::GIT_BRANCH_STATUS[:no_tracking]
|
117
|
+
do_repos.push(repo)
|
118
|
+
else
|
119
|
+
if status == Repo::Status::GIT_REPO_STATUS[:dirty]
|
120
|
+
dirty_repos.push(repo)
|
121
|
+
end
|
122
|
+
if branch_status == Repo::Status::GIT_BRANCH_STATUS[:detached]
|
123
|
+
detached_repos.push(repo)
|
124
|
+
elsif branch_status == Repo::Status::GIT_BRANCH_STATUS[:no_tracking]
|
125
|
+
no_tracking_repos.push(repo)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
}
|
129
|
+
Output.puts_success_message("检查完成!\n")
|
130
|
+
|
131
|
+
if dirty_repos.length > 0 || no_tracking_repos.length > 0 || detached_repos.length > 0
|
132
|
+
remind_repos = []
|
133
|
+
remind_repos.push(['有本地改动', dirty_repos.map { |e| e.name }])
|
134
|
+
remind_repos.push(['未追踪远程分支(建议:mgit branch -u origin/<branch>)', no_tracking_repos.map { |e| e.name }]) if no_tracking_repos.length > 0
|
135
|
+
remind_repos.push(['HEAD游离,当前不在任何分支上', detached_repos.map { |e| e.name }]) if detached_repos.length > 0
|
136
|
+
Output.interact_with_multi_selection_combined_repos(remind_repos, "以上仓库状态异常", ['a: 跳过并继续', 'b: 强制执行', 'c: 终止']) { |input|
|
137
|
+
if input == 'b'
|
138
|
+
do_repos += dirty_repos
|
139
|
+
do_repos += detached_repos
|
140
|
+
do_repos += no_tracking_repos
|
141
|
+
do_repos.uniq! { |repo| repo.name }
|
142
|
+
elsif input == 'c' || input != 'a'
|
143
|
+
Output.puts_cancel_message
|
144
|
+
return
|
145
|
+
end
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
error_repos = {}
|
150
|
+
if do_repos.length == 0
|
151
|
+
Output.puts_remind_message("没有仓库需要执行merge指令!") if config_repo.nil?
|
152
|
+
else
|
153
|
+
Output.puts_processing_message("开始merge子仓库...")
|
154
|
+
_, error_repos = Workspace.execute_git_cmd_with_repos(cmd, opts, do_repos)
|
155
|
+
end
|
156
|
+
|
157
|
+
if config_error.nil? && error_repos.length == 0
|
158
|
+
Output.puts_succeed_cmd("#{cmd} #{opts}")
|
159
|
+
end
|
160
|
+
|
161
|
+
# 清除中间态
|
162
|
+
OperationProgressManager.remove_progress(Workspace.root, __progress_type)
|
163
|
+
end
|
164
|
+
|
165
|
+
# 合并主仓库
|
166
|
+
#
|
167
|
+
# @param cmd [String] 合并指令
|
168
|
+
#
|
169
|
+
# @param opts [String] 合并参数
|
170
|
+
#
|
171
|
+
# @param repo [Repo] 配置仓库对象
|
172
|
+
#
|
173
|
+
# @param exec_repos [Array<Repo>] 本次操作的所有仓库(含配置仓库)
|
174
|
+
#
|
175
|
+
def merge_config_repo(cmd, opts, repo, auto_update)
|
176
|
+
if !repo.nil?
|
177
|
+
branch_status = repo.status_checker.branch_status
|
178
|
+
if branch_status == Repo::Status::GIT_BRANCH_STATUS[:detached]
|
179
|
+
remind_config_repo_fail("主仓库\"#{repo.name}\"HEAD游离,当前不在任何分支上,无法执行!")
|
180
|
+
elsif branch_status == Repo::Status::GIT_BRANCH_STATUS[:no_tracking]
|
181
|
+
remind_config_repo_fail("主仓库\"#{repo.name}\"未跟踪对应远程分支,无法执行!(需要执行'mgit branch -u origin/<branch>')")
|
182
|
+
elsif repo.status_checker.status == Repo::Status::GIT_REPO_STATUS[:dirty]
|
183
|
+
remind_config_repo_fail("主仓库\"#{repo.name}\"有改动,无法执行\"#{cmd}\"!")
|
184
|
+
else
|
185
|
+
return continue_execute(cmd, opts, repo, PROGRESS_STAGE[:new_start], auto_update)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def continue_execute(cmd, opts, repo, check_point, auto_update)
|
191
|
+
|
192
|
+
# 现场信息
|
193
|
+
exec_subrepos = all_repos(except_config:true)
|
194
|
+
is_all = Workspace.is_all_exec_sub_repos?(exec_subrepos)
|
195
|
+
context = OperationProgressContext.new(__progress_type)
|
196
|
+
context.cmd = cmd
|
197
|
+
context.opts = opts
|
198
|
+
context.repos = is_all ? nil : exec_subrepos.map { |e| e.name } # nil表示操作所有子仓库
|
199
|
+
context.branch = repo.status_checker.current_branch(use_cache:true)
|
200
|
+
|
201
|
+
# 更新主仓库
|
202
|
+
update_config_repo(repo, context, auto_update) if check_point < PROGRESS_STAGE[:did_pull_config]
|
203
|
+
|
204
|
+
if check_point < PROGRESS_STAGE[:did_refresh_config]
|
205
|
+
# 操作主仓库
|
206
|
+
config_error = exec_config_repo(repo, cmd, opts)
|
207
|
+
return config_error if config_error
|
208
|
+
# 更新配置表
|
209
|
+
refresh_config(repo, context, auto_update)
|
210
|
+
end
|
211
|
+
|
212
|
+
if check_point < PROGRESS_STAGE[:did_pull_sub]
|
213
|
+
# 如果本次操作所有子仓库,则再次获取所有子仓库(因为配置表可能已经更新,子仓库列表也有更新,此处获取的仓库包含:已有的子仓库 + 合并后新下载仓库 + 从缓存弹出的仓库)
|
214
|
+
exec_subrepos = all_repos(except_config:true) if is_all
|
215
|
+
# 更新子仓库
|
216
|
+
update_subrepos(exec_subrepos, context, auto_update)
|
217
|
+
end
|
218
|
+
|
219
|
+
config_error
|
220
|
+
end
|
221
|
+
|
222
|
+
def update_config_repo(repo, context, auto)
|
223
|
+
if auto || Output.continue_with_user_remind?("即将合并主仓库,是否先拉取远程代码更新?")
|
224
|
+
Output.puts_processing_message("正在更新主仓库...")
|
225
|
+
success, output = repo.execute_git_cmd('pull', '')
|
226
|
+
if !success
|
227
|
+
context.other = {
|
228
|
+
PROGRESS_STAGE_KEY => PROGRESS_STAGE[:did_pull_config],
|
229
|
+
PROGRESS_AUTO => auto
|
230
|
+
}
|
231
|
+
OperationProgressManager.trap_into_progress(Workspace.root, context)
|
232
|
+
show_progress_error("主仓库更新失败", "#{output}")
|
233
|
+
else
|
234
|
+
Output.puts_success_message("更新成功!\n")
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def exec_config_repo(repo, cmd, opts)
|
240
|
+
error = nil
|
241
|
+
Output.puts_processing_message("开始操作主仓库...")
|
242
|
+
success, output = repo.execute_git_cmd(cmd, opts)
|
243
|
+
if success
|
244
|
+
Output.puts_success_message("操作成功!\n")
|
245
|
+
else
|
246
|
+
Output.puts_fail_message("操作失败!\n")
|
247
|
+
error = output
|
248
|
+
end
|
249
|
+
return error
|
250
|
+
end
|
251
|
+
|
252
|
+
# 刷新配置表
|
253
|
+
def refresh_config(repo, context, auto)
|
254
|
+
begin
|
255
|
+
Workspace.update_config(strict_mode:false) { |missing_repos|
|
256
|
+
if missing_repos.length > 0
|
257
|
+
# 这里分支引导仅根据主仓库来进行,如果使用all_repos来作为引导
|
258
|
+
# 基准,可能不准确(因为all_repos可能包含merge分支已有的本地
|
259
|
+
# 仓库,而这些仓库所在分支可能五花八门,数量也可能多于处于正确
|
260
|
+
# 分支的仓库)。
|
261
|
+
success_missing_repos = Workspace.guide_to_checkout_branch(missing_repos, [repo], append_message:"拒绝该操作本次执行将忽略以上仓库")
|
262
|
+
all_repos.concat(success_missing_repos)
|
263
|
+
# success_missing_repos包含新下载的和当前分支已有的新仓库,其中已有仓库包含在@all_repos内,需要去重
|
264
|
+
all_repos.uniq! { |repo| repo.name }
|
265
|
+
end
|
266
|
+
}
|
267
|
+
refresh_context(context)
|
268
|
+
rescue Error => e
|
269
|
+
if e.type == MGIT_ERROR_TYPE[:config_generate_error]
|
270
|
+
context.other = {
|
271
|
+
PROGRESS_STAGE_KEY => PROGRESS_STAGE[:did_refresh_config],
|
272
|
+
PROGRESS_AUTO => auto
|
273
|
+
}
|
274
|
+
OperationProgressManager.trap_into_progress(Workspace.root, context)
|
275
|
+
show_progress_error("配置表生成失败", "#{e.msg}")
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def update_subrepos(subrepos, context, auto)
|
281
|
+
if auto || Output.continue_with_user_remind?("即将合并子仓库,是否先拉取远程代码更新?")
|
282
|
+
Output.puts_processing_message("正在更新子仓库...")
|
283
|
+
_, error_repos = Workspace.execute_git_cmd_with_repos('pull', '', subrepos)
|
284
|
+
if error_repos.length > 0
|
285
|
+
context.other = {
|
286
|
+
PROGRESS_STAGE_KEY => PROGRESS_STAGE[:did_pull_sub],
|
287
|
+
PROGRESS_AUTO => auto
|
288
|
+
}
|
289
|
+
OperationProgressManager.trap_into_progress(Workspace.root, context)
|
290
|
+
show_progress_error("子仓库更新失败", "见上述输出")
|
291
|
+
else
|
292
|
+
Output.puts_success_message("更新成功!\n")
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def refresh_context(context)
|
298
|
+
exec_subrepos = all_repos(except_config:true)
|
299
|
+
is_all = Workspace.is_all_exec_sub_repos?(exec_subrepos)
|
300
|
+
context.repos = is_all ? nil : exec_subrepos.map { |e| e.name } # nil表示操作所有子仓库
|
301
|
+
end
|
302
|
+
|
303
|
+
def remind_config_repo_fail(msg)
|
304
|
+
Output.puts_fail_message(msg)
|
305
|
+
if Output.continue_with_user_remind?("是否继续操作其余仓库?")
|
306
|
+
return
|
307
|
+
else
|
308
|
+
Output.puts_cancel_message
|
309
|
+
exit
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def do_abort(argv)
|
314
|
+
if argv.git_opts.include?('--abort')
|
315
|
+
Output.puts_start_cmd
|
316
|
+
OperationProgressManager.remove_progress(Workspace.root, __progress_type)
|
317
|
+
do_repos = all_repos.select { |repo| repo.status_checker.is_in_merge_progress? }
|
318
|
+
|
319
|
+
if do_repos.length > 0
|
320
|
+
append_message = ",另有#{all_repos.length - do_repos.length}个仓库无须操作" if do_repos.length < all_repos.length
|
321
|
+
Output.puts_processing_block(do_repos.map { |e| e.name }, "开始操作以上仓库#{append_message}...")
|
322
|
+
_, error_repos = Workspace.execute_git_cmd_with_repos(argv.cmd, argv.git_opts, do_repos)
|
323
|
+
Output.puts_succeed_cmd(argv.absolute_cmd) if error_repos.length == 0
|
324
|
+
else
|
325
|
+
Output.puts_success_message("没有仓库需要操作!")
|
326
|
+
end
|
327
|
+
|
328
|
+
return true
|
329
|
+
else
|
330
|
+
return false
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
def show_progress_error(summary, detail)
|
335
|
+
error = "#{summary} 已进入操作中间态。
|
336
|
+
|
337
|
+
原因:
|
338
|
+
#{detail}
|
339
|
+
|
340
|
+
可选:
|
341
|
+
- 使用\"mgit merge --continue\"继续合并。
|
342
|
+
- 使用\"mgit merge --abort\"取消合并。"
|
343
|
+
Foundation.help!(error, title:'暂停')
|
344
|
+
end
|
345
|
+
|
346
|
+
def enable_repo_selection
|
347
|
+
return true
|
348
|
+
end
|
349
|
+
|
350
|
+
def enable_continue_operation
|
351
|
+
return true
|
352
|
+
end
|
353
|
+
|
354
|
+
def self.description
|
355
|
+
return "合并两个或多个开发历史。"
|
356
|
+
end
|
357
|
+
|
358
|
+
def self.usage
|
359
|
+
return "mgit merge [<git-merge-option>] [--pull] [(--mrepo|--el-mrepo) <repo>...] [--help]\nmgit merge --continue\nmgit merge --abort"
|
360
|
+
end
|
361
|
+
|
362
|
+
# 判断是否需要fast forward
|
363
|
+
# def is_fast_forward?(argv, repos)
|
364
|
+
# git_opts = argv.git_opts(raw:false)
|
365
|
+
# git_opts.each { |opt_arr|
|
366
|
+
# if !argv.is_option?(opt_arr.first)
|
367
|
+
# repos.each { |repo|
|
368
|
+
# opt_arr.each { |branch|
|
369
|
+
# if repo.status_checker.is_ancestor_of_branch?(branch)
|
370
|
+
# return true
|
371
|
+
# end
|
372
|
+
# }
|
373
|
+
# }
|
374
|
+
# end
|
375
|
+
# }
|
376
|
+
# return false
|
377
|
+
# end
|
378
|
+
|
379
|
+
end
|
380
|
+
|
381
|
+
end
|