class MGit::Sync
@!scope 同步所有管理的仓库到工作区,可能从远端拉取,可能从本地dump,所以sync后的工作区不一定是分支的最新节点 可通过 mgit sync –pull 进行同步后pull到最新节点
Constants
- OPT_LIST
Public Class Methods
description()
click to toggle source
# File lib/m-git/command/sync.rb, line 317 def self.description "根据配置表(从远端或本地)同步仓库到工作区,包括被锁定仓库,已经在工作的不作处理(默认不执行pull)。" end
usage()
click to toggle source
# File lib/m-git/command/sync.rb, line 321 def self.usage "mgit sync [-a|-n|-c] [<repo>...] [-p] [-o] [-h]" end
Public Instance Methods
check_valid_repos(repo_names)
click to toggle source
# File lib/m-git/command/sync.rb, line 291 def check_valid_repos(repo_names) specified_repos = repo_names.map { |name| name.downcase } all_valid_repos = Workspace.config.light_repos.map { |light_repo| light_repo.name.downcase } error_repo_names = specified_repos - all_valid_repos valid_repo_names = specified_repos - error_repo_names valid_repos = Workspace.config.light_repos.select { |light_repo| valid_repo_names.include?(light_repo.name.downcase) } [valid_repos, error_repo_names] end
enable_short_basic_option()
click to toggle source
# File lib/m-git/command/sync.rb, line 313 def enable_short_basic_option true end
execute(argv)
click to toggle source
# File lib/m-git/command/sync.rb, line 70 def execute(argv) Output.puts_start_cmd if argv.opt_list.did_set_opt?(OPT_LIST[:all]) setup_all_sync_reops(argv) elsif argv.opt_list.did_set_opt?(OPT_LIST[:new_repo]) setup_new_reops elsif argv.opt_list.did_set_opt?(OPT_LIST[:url]) setup_config_url_repos elsif argv.opt_list.did_set_opt?(OPT_LIST[:clone]) return if !setup_download_reops(argv.opt(OPT_LIST[:clone]).value) elsif argv.git_opts.length > 0 return if !setup_specified_repos(argv) else setup_normal_reops(argv) end if (@sync_repos.length + @update_repos.length + @download_repos.length) == 0 Output.puts_success_message("没有仓库需要同步!") return end error_repos = {} if @sync_repos.length > 0 Workspace.concurrent_enumerate_with_progress_bar(@sync_repos, "正在同步(锁定)以上仓库...") { |light_repo| repo = Repo.generate_strictly(Workspace.root, light_repo) error_message = Repo::SyncHelper.sync_exist_repo(repo, light_repo) if !error_message.nil? Lock.mutex_exec { error_repos[light_repo.name] = error_message } end } end if @update_repos.length > 0 Workspace.concurrent_enumerate_with_progress_bar(@update_repos, "正在更新以上仓库...") { |light_repo| repo = Repo.generate_strictly(Workspace.root, light_repo) success, output = repo.execute_git_cmd('pull', '') if !success Lock.mutex_exec { error_repos[light_repo.name] = output } end } end if @download_repos.length > 0 Workspace.sync_new_repos(@download_repos) end if error_repos.length > 0 Workspace.show_error(error_repos) else Output.puts_succeed_cmd(argv.absolute_cmd) end end
options()
click to toggle source
Calls superclass method
MGit::BaseCommand#options
# File lib/m-git/command/sync.rb, line 40 def options return [ ARGV::Opt.new(OPT_LIST[:new_repo], short_key:OPT_LIST[:new_repo_s], info:"下载配置表中指定被mgit管理,但本地不存在的仓库,已有仓库不做任何处理,使用:mgit sync -n。", type: :boolean), ARGV::Opt.new(OPT_LIST[:all], short_key:OPT_LIST[:all_s], info:'对所有(包含不被mgit管理的)仓库操作:1.如果本地缺失则下载。2.如果本地存在且被锁定则同步到锁定状态。注意,如果需要下载代码,需要配置仓库URL,否则跳过,使用:mgit sync -a。', type: :boolean), ARGV::Opt.new(OPT_LIST[:clone], short_key:OPT_LIST[:clone_s], info:'下载一组仓库(包含不被mgit管理的仓库),如: mgit sync -c repo1 repo2。'), ARGV::Opt.new(OPT_LIST[:pull], short_key:OPT_LIST[:pull_s], info:'同步本地仓库后执行pull操作更新,配合其他指令使用,如: mgit sync -a -p。', type: :boolean), ARGV::Opt.new(OPT_LIST[:url], short_key:OPT_LIST[:url_s], info:'校验并同步URL与配置不一致的仓库,如: mgit sync -u。', type: :boolean) ].concat(super) end
parse_repo_name(argv)
click to toggle source
# File lib/m-git/command/sync.rb, line 303 def parse_repo_name(argv) return if argv.git_opts.nil? repos = argv.git_opts.split(' ') extra_opts = repos.select { |e| argv.is_option?(e) } Foundation.help!("输入非法参数:#{extra_opts.join(',')}。请通过\"mgit #{argv.cmd} --help\"查看用法。") if extra_opts.length > 0 Foundation.help!("未输入查询仓库名!请使用这种形式查询:mgit info repo1 repo2 ...") if repos.length == 0 repos.map { |e| e.downcase } end
post_exec()
click to toggle source
# File lib/m-git/command/sync.rb, line 33 def post_exec # 打点结束 duration = MGit::DurationRecorder.end MGit::Loger.info("~~~ #{@argv.absolute_cmd}, 耗时:#{duration} s ~~~") end
pre_exec()
click to toggle source
— 覆写前后hook,不需要预设操作 —
# File lib/m-git/command/sync.rb, line 24 def pre_exec MGit::DurationRecorder.start Workspace.setup_multi_repo_root # 配置log MGit::Loger.config(Workspace.root) MGit::Loger.info("~~~ #{@argv.absolute_cmd} ~~~") Workspace.setup_config end
prepare_repo_category()
click to toggle source
# File lib/m-git/command/sync.rb, line 124 def prepare_repo_category @sync_repos = [] @update_repos = [] @download_repos = [] end
setup_all_sync_reops(argv)
click to toggle source
mgit sync –all [–pull] 下载仓库:NE|U,同步仓库:E|L,更新仓库: E|NL|U(可选)
# File lib/m-git/command/sync.rb, line 211 def setup_all_sync_reops(argv) prepare_repo_category Workspace.config.light_repos.each { |light_repo| repo_exist = Dir.exist?(light_repo.abs_dest(Workspace.root)) if !repo_exist && !light_repo.url.nil? @download_repos.push(light_repo) elsif repo_exist && light_repo.lock @sync_repos.push(light_repo) elsif repo_exist && !light_repo.url.nil? && argv.opt_list.did_set_opt?(OPT_LIST[:pull]) @update_repos.push(light_repo) end } end
setup_config_url_repos()
click to toggle source
mgit sync -u 同步仓库:E | url不一致
# File lib/m-git/command/sync.rb, line 261 def setup_config_url_repos() prepare_repo_category warning_repos = [] missing_repos = [] Workspace.config.light_repos.each { |light_repo| if !light_repo.mgit_excluded repo, _ = Repo.generate_softly(Workspace.root, light_repo) if !repo.nil? original_url = repo.status_checker.default_url target_url = light_repo.url warning_repos.push(light_repo) if !Utils.url_consist?(original_url, target_url) else missing_repos.push(light_repo) end end } Output.puts_remind_block(missing_repos.map { |repo| repo.name }, "以上仓库本地缺失,无法校验URL,请执行\"mgit sync -n\"重新下载后重试!") if missing_repos.length > 0 if warning_repos.length > 0 if Output.continue_with_interact_repos?(warning_repos.map { |repo| repo.name }, "以上仓库的当前URL(origin)和配置表指定URL不一致,建议\n 1. 执行\"mgit delete repo1 repo2...\"删除仓库.\n 2. 执行\"mgit sync -n\"重新下载。\n 继续强制设置可能导致仓库出错,是否继续?") @sync_repos = warning_repos else Output.puts_cancel_message exit end end end
setup_download_reops(repo_names)
click to toggle source
mgit sync –clone repo1 repo2 … 下载仓库:NE|U(指定)
# File lib/m-git/command/sync.rb, line 227 def setup_download_reops(repo_names) prepare_repo_category existing_repos = [] valid_repos, error_repo_names = check_valid_repos(repo_names) valid_repos.each { |light_repo| repo_exist = Dir.exist?(light_repo.abs_dest(Workspace.root)) if !repo_exist if !light_repo.url.nil? @download_repos.push(light_repo) else error_repo_names.push(light_repo.name) end else error_repo_names.push(light_repo.name) if light_repo.url.nil? existing_repos.push(light_repo.name) end } should_continue = true error_repos = [] error_repos.push(['配置表中未定义(或未指定"remote-path")', error_repo_names]) if error_repo_names.length > 0 error_repos.push(['本地已经存在', existing_repos]) if existing_repos.length > 0 Output.interact_with_multi_selection_combined_repos(error_repos, "以上仓库状态异常", ['a: 跳过并继续', 'b: 终止']) { |input| if input == 'b' Output.puts_cancel_message should_continue = false end } if error_repos.length > 0 return should_continue end
setup_new_reops()
click to toggle source
mgit sync –new 下载仓库:M|NE|U
# File lib/m-git/command/sync.rb, line 199 def setup_new_reops prepare_repo_category Workspace.config.light_repos.each { |light_repo| if !light_repo.mgit_excluded repo_exist = Dir.exist?(light_repo.abs_dest(Workspace.root)) @download_repos.push(light_repo) if !repo_exist && !light_repo.url.nil? end } end
setup_normal_reops(argv)
click to toggle source
mgit sync [–pull] 下载仓库:M|NE|U, 同步仓库:M|E|L, 更新仓库:M|E|U(可选)
# File lib/m-git/command/sync.rb, line 178 def setup_normal_reops(argv) prepare_repo_category should_pull = argv.opt_list.did_set_opt?(OPT_LIST[:pull]) Workspace.config.light_repos.each { |light_repo| if !light_repo.mgit_excluded repo_exist = Dir.exist?(light_repo.abs_dest(Workspace.root)) if !repo_exist && !light_repo.url.nil? @download_repos.push(light_repo) elsif repo_exist && light_repo.lock @sync_repos.push(light_repo) end if repo_exist && should_pull && !light_repo.url.nil? @update_repos.push(light_repo) end end } end
setup_specified_repos(argv)
click to toggle source
mgit sync repo1 repo2 … [–pull] 针对一组指定仓库进行:下载仓库:NE|U,同步仓库:E|L,更新仓库: E|U(可选)
# File lib/m-git/command/sync.rb, line 137 def setup_specified_repos(argv) prepare_repo_category should_pull = argv.opt_list.did_set_opt?(OPT_LIST[:pull]) valid_repos, error_repo_names = check_valid_repos(parse_repo_name(argv)) valid_repos.each { |light_repo| repo_exist = Dir.exist?(light_repo.abs_dest(Workspace.root)) if !repo_exist if !light_repo.url.nil? @download_repos.push(light_repo) else error_repo_names.push(light_repo.name) end else if light_repo.lock @sync_repos.push(light_repo) end if should_pull if !light_repo.url.nil? @update_repos.push(light_repo) else error_repo_names.push(light_repo.name) end end end } should_continue = true error_repos = [] error_repos.push(['配置表中未定义(或未指定"remote-path")', error_repo_names]) if error_repo_names.length > 0 Output.interact_with_multi_selection_combined_repos(error_repos, "以上仓库状态异常", ['a: 跳过并继续', 'b: 终止']) { |input| if input == 'b' Output.puts_cancel_message should_continue = false end } if error_repos.length > 0 return should_continue end
validate(argv)
click to toggle source
# File lib/m-git/command/sync.rb, line 62 def validate(argv) opt_all = argv.opt(OPT_LIST[:all]) opt_clone = argv.opt(OPT_LIST[:clone]) opt_new = argv.opt(OPT_LIST[:new_repo]) invalid = [opt_all, opt_clone, opt_new].select { |e| !e.nil? }.length > 1 Foundation.help!("请勿同时指定[#{OPT_LIST[:all]}|#{OPT_LIST[:all_s]}],[#{OPT_LIST[:clone]}|#{OPT_LIST[:clone_s]}]和[#{OPT_LIST[:new_repo]}|#{OPT_LIST[:new_repo_s]}]。") if invalid end