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,66 @@
|
|
1
|
+
|
2
|
+
module MGit
|
3
|
+
class ARGV
|
4
|
+
module Parser
|
5
|
+
|
6
|
+
# @param [Array] argv
|
7
|
+
#
|
8
|
+
# @return [String, Array, Array]
|
9
|
+
# 返回cmd 和 参数列表
|
10
|
+
# # 将参数初步分解,便于后续处理
|
11
|
+
# 如:argv = [command zzzz -u sdfsd sdf --mmmm yoo ssss qqq --test asdfa asd ad f --xxx asd as dfa --yoo="ajsdaf" --ppp -abc]
|
12
|
+
# 分解为:command, [zzzz], [[-u, sdfsd, sdf], [--mmmm, yoo, ssss, qqq], [--test, asdfa, asd, ad, f], [--xxx, asd, as, dfa], [--yoo, "ajsdaf"], [--ppp], [-a], [-b], [-c]]
|
13
|
+
#
|
14
|
+
# 初步解析参数
|
15
|
+
def self.parse(argv)
|
16
|
+
absolute_cmd = argv.join(' ')
|
17
|
+
cmd = argv.shift
|
18
|
+
pure_opts = argv.join(' ')
|
19
|
+
|
20
|
+
# 将参数初步分解,便于后续处理
|
21
|
+
# 如:zzzz -u sdfsd sdf --mmmm yoo ssss qqq --test asdfa asd ad f --xxx asd as dfa --yoo="ajsdaf" --ppp -abc
|
22
|
+
# 分解为:[[zzzz], [-u, sdfsd, sdf], [--mmmm, yoo, ssss, qqq], [--test, asdfa, asd, ad, f], [--xxx, asd, as, dfa], [--yoo, "ajsdaf"], [--ppp], [-a], [-b], [-c]]
|
23
|
+
temp = []
|
24
|
+
raw_opts = []
|
25
|
+
argv.each_with_index { |e, idx|
|
26
|
+
|
27
|
+
Foundation.help!("参数\"#{e}\"格式错误,请使用格式如:\"--long\"或\"-s\"") if (e =~ /---/) == 0
|
28
|
+
|
29
|
+
# 检查是否是带'--'或'-'的参数
|
30
|
+
if (e =~ /-/) == 0
|
31
|
+
# 回收缓存
|
32
|
+
raw_opts.push(temp) if temp.length != 0
|
33
|
+
# 清空临时缓存
|
34
|
+
temp = []
|
35
|
+
|
36
|
+
# 如果是合并的短指令,如'-al = -a + -l',则分拆后直接装入raw_opts数组
|
37
|
+
# 因为只有不需要传入值的短参数才能合并,因此不利用临时缓存读取后续参数值
|
38
|
+
if e.length > 2 && (e =~ /--/).nil? && !e.include?('=')
|
39
|
+
e.split('')[1..-1].each { |s|
|
40
|
+
raw_opts.push(["-#{s}"])
|
41
|
+
}
|
42
|
+
next
|
43
|
+
end
|
44
|
+
|
45
|
+
# 处理带‘=’的传值参数
|
46
|
+
loc = (e =~ /=/)
|
47
|
+
if loc
|
48
|
+
temp.unshift(e[(loc + 1)..-1])
|
49
|
+
temp.unshift(e[0..loc - 1])
|
50
|
+
elsif e.length != 0
|
51
|
+
temp.push(e)
|
52
|
+
end
|
53
|
+
|
54
|
+
elsif e.length != 0
|
55
|
+
temp.push(e)
|
56
|
+
end
|
57
|
+
|
58
|
+
if idx == argv.length - 1
|
59
|
+
raw_opts.push(temp)
|
60
|
+
end
|
61
|
+
}
|
62
|
+
ARGV.new(cmd, pure_opts, absolute_cmd, raw_opts)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,271 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'm-git/command_manager'
|
5
|
+
|
6
|
+
module MGit
|
7
|
+
class BaseCommand
|
8
|
+
|
9
|
+
def self.inherited(sub_klass)
|
10
|
+
CommandManager.register_command(sub_klass.cmd, sub_klass)
|
11
|
+
end
|
12
|
+
|
13
|
+
# 当前命令行的命令比如checkout / status /..
|
14
|
+
def self.cmd
|
15
|
+
name.split('::').last.downcase
|
16
|
+
end
|
17
|
+
|
18
|
+
# 引入所有自定义指令
|
19
|
+
Dir[File.join(__dir__, 'command', '*.rb')].each { |cmd|
|
20
|
+
require cmd
|
21
|
+
}
|
22
|
+
|
23
|
+
HIGH_PRIORITY_OPT_LIST = {
|
24
|
+
:help => '--help',
|
25
|
+
:help_s => '-h',
|
26
|
+
:auto_exec => '--auto-exec'
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
# 注意使用时跟指令自身设置的参数对比,避免冲突
|
30
|
+
SELECTABLE_OPT_LIST = {
|
31
|
+
:mrepo => '--mrepo',
|
32
|
+
:mrepo_s => '-m',
|
33
|
+
:exclude_mrepo => '--el-mrepo',
|
34
|
+
:exclude_mrepo_s => '-e',
|
35
|
+
:include_lock => '--include-lock',
|
36
|
+
:include_lock_s => '-i',
|
37
|
+
:continue => '--continue',
|
38
|
+
:abort => '--abort',
|
39
|
+
}.freeze
|
40
|
+
|
41
|
+
# 初始化
|
42
|
+
#
|
43
|
+
# @param argv [ARGV::Opt] 输入参数对象
|
44
|
+
#
|
45
|
+
def initialize(argv)
|
46
|
+
# 指令解析
|
47
|
+
setup_argv(argv)
|
48
|
+
process_highest_priority_option(argv)
|
49
|
+
validate(argv)
|
50
|
+
@argv = argv
|
51
|
+
end
|
52
|
+
|
53
|
+
#--- 禁止覆写 ---
|
54
|
+
# 执行主方法
|
55
|
+
def run
|
56
|
+
begin
|
57
|
+
__config_repo_filter
|
58
|
+
pre_exec
|
59
|
+
execute(@argv)
|
60
|
+
post_exec
|
61
|
+
rescue SystemExit, Interrupt
|
62
|
+
did_interrupt
|
63
|
+
end
|
64
|
+
end
|
65
|
+
#---------------
|
66
|
+
# Workspace Bridge
|
67
|
+
def all_repos(except_config:false)
|
68
|
+
Workspace.all_repos(except_config: except_config)
|
69
|
+
end
|
70
|
+
|
71
|
+
def locked_repos
|
72
|
+
Workspace.locked_repos
|
73
|
+
end
|
74
|
+
|
75
|
+
def exec_light_repos
|
76
|
+
Workspace.exec_light_repos
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_config_repo
|
80
|
+
Workspace.generate_config_repo
|
81
|
+
end
|
82
|
+
# -----------
|
83
|
+
private
|
84
|
+
def __config_repo_filter
|
85
|
+
cfg = Workspace.filter_config
|
86
|
+
cfg.include_lock = !@argv.opt(SELECTABLE_OPT_LIST[:include_lock]).nil? || include_lock_by_default
|
87
|
+
cfg.select_repos = @argv.opt(SELECTABLE_OPT_LIST[:mrepo])
|
88
|
+
cfg.exclude_repos = @argv.opt(SELECTABLE_OPT_LIST[:exclude_mrepo])
|
89
|
+
cfg.auto_exec = @argv.opt_list.did_set_opt?(HIGH_PRIORITY_OPT_LIST[:auto_exec])
|
90
|
+
end
|
91
|
+
#--- 基类调用,禁止覆写 ---
|
92
|
+
# 配置参数对象
|
93
|
+
def setup_argv(argv)
|
94
|
+
argv.register_opts(options)
|
95
|
+
argv.resolve!
|
96
|
+
|
97
|
+
argv.opt_list.opts.each do |opt|
|
98
|
+
next if opt.empty?
|
99
|
+
revise_option_value(opt)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# 处理最高优指令
|
104
|
+
def process_highest_priority_option(argv)
|
105
|
+
if argv.opt_list.did_set_opt?(HIGH_PRIORITY_OPT_LIST[:help])
|
106
|
+
usage(argv)
|
107
|
+
exit
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#-------------------------------------------------------
|
112
|
+
|
113
|
+
#--- 可选覆写 ---
|
114
|
+
# 此处有pre hook,覆写时需要先调用super, 特殊指令除外
|
115
|
+
def pre_exec
|
116
|
+
# 开始计时
|
117
|
+
MGit::DurationRecorder.start
|
118
|
+
# 配置根目录
|
119
|
+
Workspace.setup_multi_repo_root
|
120
|
+
|
121
|
+
# 配置log
|
122
|
+
MGit::Loger.config(Workspace.root)
|
123
|
+
MGit::Loger.info("~~~ #{@argv.absolute_cmd} ~~~")
|
124
|
+
|
125
|
+
# 执行前置hook
|
126
|
+
HooksManager.execute_mgit_pre_hook(@argv.cmd, @argv.pure_opts)
|
127
|
+
|
128
|
+
# 解析配置文件
|
129
|
+
Workspace.setup_config
|
130
|
+
|
131
|
+
# 校验实体仓库
|
132
|
+
Workspace.setup_all_repos
|
133
|
+
end
|
134
|
+
|
135
|
+
# 此处有post hook,覆写时需要最后调用super, 特殊指令除外
|
136
|
+
def post_exec
|
137
|
+
# 执行后置hook
|
138
|
+
HooksManager.execute_mgit_post_hook(@argv.cmd, @argv.pure_opts, Workspace.exec_light_repos)
|
139
|
+
# 打点结束
|
140
|
+
duration = MGit::DurationRecorder.end
|
141
|
+
MGit::Loger.info("~~~ #{@argv.absolute_cmd}, 耗时:#{duration} s ~~~")
|
142
|
+
end
|
143
|
+
|
144
|
+
# 【子类按需覆写修改返回值】返回true表示可以支持自动执行
|
145
|
+
def enable_auto_execution
|
146
|
+
false
|
147
|
+
end
|
148
|
+
|
149
|
+
# 【子类按需覆写修改返回值】返回true表示可以支持"--mrepo"等可选选项
|
150
|
+
def enable_repo_selection
|
151
|
+
false
|
152
|
+
end
|
153
|
+
|
154
|
+
# 【子类按需覆写修改返回值】是否使默认添加选项(如‘--help’)和可选添加的选项(如‘--mrepo’)支持短指令
|
155
|
+
def enable_short_basic_option
|
156
|
+
false
|
157
|
+
end
|
158
|
+
|
159
|
+
# 【子类按需覆写修改返回值】是否添加操作lock仓库的选项(如‘--include-lock’)
|
160
|
+
def enable_lock_operation
|
161
|
+
false
|
162
|
+
end
|
163
|
+
|
164
|
+
# 【子类按需覆写修改返回值】是否自动将lock仓库加入到操作集中
|
165
|
+
def include_lock_by_default
|
166
|
+
false
|
167
|
+
end
|
168
|
+
|
169
|
+
# 【子类按需覆写修改返回值】是否添加‘--continue’参数,要在指令中自行控制中间态操作
|
170
|
+
def enable_continue_operation
|
171
|
+
false
|
172
|
+
end
|
173
|
+
|
174
|
+
# 【子类按需覆写修改返回值】是否添加‘--abort’参数
|
175
|
+
def enable_abort_operation
|
176
|
+
false
|
177
|
+
end
|
178
|
+
|
179
|
+
# 【子类按需覆写修改实现】按下ctrl+c后调用
|
180
|
+
def did_interrupt
|
181
|
+
end
|
182
|
+
|
183
|
+
# 可覆写该方法,返回该指令的描述
|
184
|
+
def self.description
|
185
|
+
end
|
186
|
+
|
187
|
+
# 可覆写该方法,返回该指令的用法
|
188
|
+
def self.usage
|
189
|
+
end
|
190
|
+
#---------------
|
191
|
+
|
192
|
+
#--- 强制覆写 ---
|
193
|
+
# 子类指令执行主方法
|
194
|
+
def execute(argv)
|
195
|
+
Foundation.help!("请覆写父类方法: \"execute(argv)\"")
|
196
|
+
end
|
197
|
+
#---------------
|
198
|
+
|
199
|
+
#--- 如果要接管某个指令(即为它添加自定义参数) ---
|
200
|
+
# --- 强制覆写(若该指令不带任何自定义参数,则无须覆写) ---
|
201
|
+
# 注册选项,覆写时注意返回"[...].concat(super)"
|
202
|
+
def options
|
203
|
+
opts = [
|
204
|
+
ARGV::Opt.new(HIGH_PRIORITY_OPT_LIST[:help],
|
205
|
+
short_key:(HIGH_PRIORITY_OPT_LIST[:help_s] if enable_short_basic_option),
|
206
|
+
info:"显示帮助。",
|
207
|
+
type: :boolean)
|
208
|
+
]
|
209
|
+
|
210
|
+
opts.push(
|
211
|
+
ARGV::Opt.new(HIGH_PRIORITY_OPT_LIST[:auto_exec],
|
212
|
+
info:'指定该参数会跳过所有交互场景,并自动选择需要的操作执行。该参数主要用于脚本调用mgit进行自动化操作,日常RD开发不应当使用。',
|
213
|
+
type: :boolean)
|
214
|
+
) if enable_auto_execution
|
215
|
+
|
216
|
+
opts.push(
|
217
|
+
ARGV::Opt.new(SELECTABLE_OPT_LIST[:mrepo],
|
218
|
+
short_key:(SELECTABLE_OPT_LIST[:mrepo_s] if enable_short_basic_option),
|
219
|
+
info:'指定需要执行该指令的仓库,可指定一个或多个,空格隔开,大小写均可,如:"--mrepo boxapp BBAAccount",若缺省则对所有仓库执行指令。'),
|
220
|
+
ARGV::Opt.new(SELECTABLE_OPT_LIST[:exclude_mrepo],
|
221
|
+
short_key:(SELECTABLE_OPT_LIST[:exclude_mrepo_s] if enable_short_basic_option),
|
222
|
+
info:'指定不需要执行该指令的仓库,可指定一个或多个,空格隔开,大小写均可,如:"--el-mrepo boxapp BBAAccount",若缺省则对所有仓库执行指令。与"--mrepo"同时指定时无效。')
|
223
|
+
) if enable_repo_selection
|
224
|
+
|
225
|
+
opts.push(
|
226
|
+
ARGV::Opt.new(SELECTABLE_OPT_LIST[:include_lock], info:'指定该参数意味着同时也操作lock仓库。',
|
227
|
+
type: :boolean)
|
228
|
+
) if enable_lock_operation
|
229
|
+
|
230
|
+
opts.push(
|
231
|
+
ARGV::Opt.new(SELECTABLE_OPT_LIST[:continue],
|
232
|
+
info:'MGit自定义参数,仅在操作多仓库过程中出现问题停止,执行状态进入中间态后可用。该参数只能单独使用,解决问题后可执行"mgit <cmd> --continue"继续操作其余仓库。',
|
233
|
+
type: :boolean)
|
234
|
+
) if enable_continue_operation
|
235
|
+
|
236
|
+
opts.push(
|
237
|
+
ARGV::Opt.new(SELECTABLE_OPT_LIST[:abort],
|
238
|
+
info:'MGit自定义参数,仅在操作多仓库过程中出现问题停止,执行状态进入中间态后可用。该参数用于清除操作中间态,且只能单独使用:"mgit <cmd> --abort"。',
|
239
|
+
type: :boolean)
|
240
|
+
) if enable_abort_operation
|
241
|
+
|
242
|
+
opts
|
243
|
+
end
|
244
|
+
|
245
|
+
# 解析参数并更新参数值到列表中
|
246
|
+
def revise_option_value(opt)
|
247
|
+
end
|
248
|
+
|
249
|
+
# --- 可选覆写(若该指令不带任何自定义参数,则无须覆写) ---
|
250
|
+
# 判断是否有必须参数漏传或数据格式不正确
|
251
|
+
def validate(argv)
|
252
|
+
end
|
253
|
+
|
254
|
+
# mgit是否输入--continue希望继续上次操作
|
255
|
+
def mgit_try_to_continue?
|
256
|
+
@argv.opt_list.did_set_opt?(SELECTABLE_OPT_LIST[:continue])
|
257
|
+
end
|
258
|
+
|
259
|
+
def mgit_try_to_abort?
|
260
|
+
@argv.opt_list.did_set_opt?(SELECTABLE_OPT_LIST[:abort])
|
261
|
+
end
|
262
|
+
|
263
|
+
# 显示指令使用信息
|
264
|
+
def usage(argv)
|
265
|
+
puts "#{Output.blue_message("[指令说明]")}\n#{self.class.description}"
|
266
|
+
puts "\n#{Output.blue_message("[指令格式]")}\n#{self.class.usage}"
|
267
|
+
argv.show_info
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module MGit
|
4
|
+
|
5
|
+
# @!scope [command] add
|
6
|
+
# follow git add
|
7
|
+
# eg: mgit add .
|
8
|
+
#
|
9
|
+
class Add < BaseCommand
|
10
|
+
|
11
|
+
# @overload
|
12
|
+
#
|
13
|
+
def execute(argv)
|
14
|
+
Workspace.check_branch_consistency
|
15
|
+
Output.puts_start_cmd
|
16
|
+
_, error_repos = Workspace.execute_git_cmd_with_repos(argv.cmd, argv.git_opts, all_repos)
|
17
|
+
Output.puts_succeed_cmd(argv.absolute_cmd) if error_repos.length == 0
|
18
|
+
end
|
19
|
+
|
20
|
+
# @overload
|
21
|
+
# @return [Boolean]
|
22
|
+
#
|
23
|
+
def enable_repo_selection
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
# @overload
|
28
|
+
#
|
29
|
+
def self.description
|
30
|
+
"将文件改动加入暂存区。"
|
31
|
+
end
|
32
|
+
|
33
|
+
# @overload
|
34
|
+
#
|
35
|
+
def self.usage
|
36
|
+
"mgit add [<git-add-option>] [(--mrepo|--el-mrepo) <repo>...] [--help]"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#coding=utf-8
|
2
|
+
|
3
|
+
module MGit
|
4
|
+
|
5
|
+
# @!scope [command] branch
|
6
|
+
# follow git branch
|
7
|
+
# eg: mgit branch --compact
|
8
|
+
#
|
9
|
+
class Branch < BaseCommand
|
10
|
+
|
11
|
+
OPT_LIST = {
|
12
|
+
:compact => '--compact',
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
def options
|
16
|
+
[
|
17
|
+
ARGV::Opt.new(OPT_LIST[:compact], info:"以归类的方式显示所有仓库的当前分支。", type: :boolean)
|
18
|
+
].concat(super)
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute(argv)
|
22
|
+
Output.puts_start_cmd
|
23
|
+
|
24
|
+
if argv.opt(OPT_LIST[:compact])
|
25
|
+
show_compact_branches(argv)
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
# 无自定义参数则透传
|
30
|
+
extcute_as_common(argv)
|
31
|
+
end
|
32
|
+
|
33
|
+
# 常规执行
|
34
|
+
def extcute_as_common(argv)
|
35
|
+
error_repos = {}
|
36
|
+
all_repos.sort_by { |repo| repo.name }.each { |repo|
|
37
|
+
success, output = repo.execute_git_cmd(argv.cmd, argv.git_opts)
|
38
|
+
if success && output.length > 0
|
39
|
+
puts Output.generate_title_block(repo.name) {
|
40
|
+
output
|
41
|
+
} + "\n"
|
42
|
+
elsif !success
|
43
|
+
error_repos[repo.name] = output
|
44
|
+
end
|
45
|
+
}
|
46
|
+
if error_repos.length > 0
|
47
|
+
Workspace.show_error(error_repos)
|
48
|
+
else
|
49
|
+
Output.puts_succeed_cmd(argv.absolute_cmd)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# 以紧凑模式执行
|
54
|
+
def show_compact_branches(argv)
|
55
|
+
show_branches_for_repos(all_repos, false)
|
56
|
+
show_branches_for_repos(locked_repos, true)
|
57
|
+
Output.puts_succeed_cmd(argv.absolute_cmd)
|
58
|
+
end
|
59
|
+
|
60
|
+
# 紧凑地显示一组仓库分支
|
61
|
+
def show_branches_for_repos(repos, locked)
|
62
|
+
return if repos.nil?
|
63
|
+
|
64
|
+
list = {}
|
65
|
+
repos.sort_by { |repo| repo.name }.each { |repo|
|
66
|
+
branch = repo.status_checker.current_branch(strict_mode:false)
|
67
|
+
branch = 'HEAD游离,不在任何分支上!' if branch.nil?
|
68
|
+
list[branch] = [] if list[branch].nil?
|
69
|
+
list[branch].push(repo.name)
|
70
|
+
}
|
71
|
+
list.each { |branch, repo_names|
|
72
|
+
Output.puts_remind_block(repo_names, "以上仓库的当前分支:#{branch}#{' [锁定]' if locked}")
|
73
|
+
puts "\n"
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def enable_repo_selection
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.description
|
82
|
+
"创建、显示、删除分支。"
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.usage
|
86
|
+
"mgit branch [<git-branch-option>|--compact] [(--mrepo|--el-mrepo) <repo>...] [--help]"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|