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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
# File 'lib/m-git/command/push.rb', line 47
def execute(argv)
__setup_option_value(argv)
if argv.git_opts&.length > 0
raws_string = ''
argv.raw_opts.each do |raws|
raws_string += ' '
raws_string += raws.join(' ')
end
Foundation.help!("禁止使用参数 #{argv.git_opts}\n" + Output.remind_message("建议直接使用mgit #{argv.cmd}#{raws_string}"))
end
Workspace.check_branch_consistency
Output.puts_start_cmd
Workspace.pre_fetch
do_repos = []
diverged_repos = []
do_nothing_repos = []
detached_repos = []
no_remote_repos = []
no_tracking_repos = []
remote_inconsist_repos = []
dirty_repos = []
Output.puts_processing_message("检查各仓库状态...")
Workspace.serial_enumerate_with_progress(all_repos) { |repo|
Timer.start(repo.name)
url_consist = repo.url_consist?
branch_status = repo.status_checker.branch_status
remote_inconsist_repos.push(repo) if !url_consist
if branch_status == Repo::Status::GIT_BRANCH_STATUS[:diverged]
diverged_repos.push(repo)
elsif branch_status == Repo::Status::GIT_BRANCH_STATUS[:ahead] && url_consist
do_repos.push(repo)
elsif branch_status == Repo::Status::GIT_BRANCH_STATUS[:no_remote]
no_remote_repos.push(repo)
elsif branch_status == Repo::Status::GIT_BRANCH_STATUS[:no_tracking]
no_tracking_repos.push(repo)
elsif branch_status == Repo::Status::GIT_BRANCH_STATUS[:detached]
detached_repos.push(repo)
else
do_nothing_repos.push(repo.name)
end
if repo.status_checker.status == Repo::Status::GIT_REPO_STATUS[:dirty]
dirty_repos.push(repo)
end
Timer.stop(repo.name)
}
Output.puts_success_message("检查完成!\n")
do_repos += no_remote_repos
no_remote_repos = []
if diverged_repos.length > 0 ||
detached_repos.length > 0 ||
no_remote_repos.length > 0 ||
no_tracking_repos.length > 0 ||
remote_inconsist_repos.length > 0 ||
dirty_repos.length > 0
remind_repos = []
remind_repos.push(['远程分支不存在', no_remote_repos.map { |e| e.name }]) if no_remote_repos.length > 0
remind_repos.push(['未追踪远程分支(建议:mgit branch -u origin/<branch>)', no_tracking_repos.map { |e| e.name }]) if no_tracking_repos.length > 0
remind_repos.push(['HEAD游离,当前不在任何分支上', detached_repos.map { |e| e.name }]) if detached_repos.length > 0
remind_repos.push(['当前分支与远程分支分叉,需先pull本地合并', diverged_repos.map { |e| e.name }]) if diverged_repos.length > 0
remind_repos.push(['实际url与配置不一致', remote_inconsist_repos.map { |e| e.name }]) if remote_inconsist_repos.length > 0
remind_repos.push(['有本地改动', dirty_repos.map { |e| e.name }]) if dirty_repos.length > 0
Output.interact_with_multi_selection_combined_repos(remind_repos, "以上仓库状态异常", ['a: 跳过并继续', 'b: 强制执行', 'c: 终止']) { |input|
if input == 'b'
do_repos += diverged_repos
do_repos += detached_repos
do_repos += no_remote_repos
do_repos += no_tracking_repos
do_repos += remote_inconsist_repos
do_repos.uniq! { |repo| repo.name }
elsif input == 'c' || input != 'a'
Output.puts_cancel_message
return
end
}
end
if do_repos.length == 0
Output.puts_remind_message("仓库均无新提交,无须执行!")
return
end
HooksManager.execute_mgit_pre_push_hook(argv.cmd, argv.pure_opts, do_repos.map { |e| e.config })
skip_repos = do_repos.select { |repo|
branch_status = repo.status_checker.branch_status
branch_status == Repo::Status::GIT_BRANCH_STATUS[:detached] ||
branch_status == Repo::Status::GIT_BRANCH_STATUS[:no_tracking]
}
Output.puts_remind_block(skip_repos.map { |e| e.name }, "以上仓库无法强制执行,已跳过。") if skip_repos.length > 0
do_repos -= skip_repos
if do_repos.length == 0
Output.puts_success_message("仓库均无新提交,无须执行!")
return
end
no_remote_repo_names = do_repos.select { |repo|
branch_status = repo.status_checker.branch_status
branch_status == Repo::Status::GIT_BRANCH_STATUS[:no_remote]
}.map { |repo| repo.name }
count_msg = ",另有#{do_nothing_repos.length}个仓库无须执行" if do_nothing_repos.length > 0
Output.puts_remind_block(do_repos.map { |repo| repo.name }, "开始push以上仓库#{count_msg}...")
total_task = do_repos.length
Output.update_progress(total_task, 0)
config_repo_arr = do_repos.select { |repo| repo.config.is_config_repo }
do_repos_without_config_repo = do_repos - config_repo_arr
sub_error_repos, sub_cr_repos = __execute_push(argv, do_repos_without_config_repo) { |progress|
Output.update_progress(total_task, progress)
}
sub_task_count = do_repos_without_config_repo.length
config_error_repos, config_cr_repos = __execute_push(argv, config_repo_arr) { |progress|
Output.update_progress(total_task, progress + sub_task_count)
}
puts "\n"
error_repos = sub_error_repos.merge(config_error_repos)
Workspace.show_error(error_repos) if error_repos.length > 0
success_push_branch_repo_names = no_remote_repo_names - error_repos.keys
if success_push_branch_repo_names.length > 0
Output.puts_remind_block(success_push_branch_repo_names, "为以上仓库推送了新分支。")
puts "\n"
end
if gerrit_enabled
success_output = ''
all_cr_repos = sub_cr_repos.keys + config_cr_repos.keys
all_cr_repos.uniq!
all_cr_repos.each do |repo_name|
cr_url = sub_cr_repos[repo_name] || config_cr_repos[repo_name]
success_output += Output.generate_title_block(repo_name, has_separator: false) { cr_url } + "\n\n"
end
if success_output.length > 0
Output.puts_remind_message("以下本地提交代码评审链接,请联系仓库负责人评审后合入:")
puts success_output
end
if topic_id
success_push_code_repo_names = do_repos.map { |e| e.name } - error_repos.keys - success_push_branch_repo_names
if success_push_code_repo_names.length > 0
Output.puts_remind_message("本次push的topic id:#{topic_id}\n") if !topic_id.nil? && topic_id.length > 0
end
end
end
if error_repos.empty?
Output.puts_succeed_cmd(argv.absolute_cmd)
Timer.show_time_consuming_repos
elsif topic_id
group_repo_names = error_repos.keys
group_repo_name_str = group_repo_names.join(' ')
is_all = Workspace.is_all_exec_sub_repos_by_name?(group_repo_names)
mrepo_str = is_all ? '' : " --mrepo #{group_repo_name_str}"
Output.puts_processing_block(group_repo_names, "以上仓库组推送失败,请处理后用以下指令再次推送:\n\n mgit push --topic #{topic_id}#{mrepo_str}\n")
end
end
|