def sub_cmd_list(): """ 获取git二级指令列表 :return: list """ global __sub_cmd_list if __sub_cmd_list: return __sub_cmd_list git_help = ihelper.popen('git help -a').splitlines() lst = [] flag = False for line in git_help: if not line: continue if not flag and match(line, 'sub_cmd_start', True): flag = True continue elif flag and match(line, 'sub_cmd_end', True): break if flag: lst += filter(lambda x:x, line.split(' ')) __sub_cmd_list = lst return lst
def dir_is_repository(path=None): """ 检查目录是不是git仓库 :param path: :return: """ path = path or os.getcwd() if not os.path.isdir(path): return False curr_dir = os.getcwd() if curr_dir != path: os.chdir(path) result = True out = ihelper.popen('git branch') if match(out, 'not_repository'): result = False if curr_dir != path: os.chdir(curr_dir) return result
def current_branch(): """ 获取当前分支 :return: """ branch = filter(lambda x:str(x).find('*') != -1, ihelper.popen('git branch').splitlines()) return branch[0].replace('*', '').strip() if branch else None
def workspace_status(text=False, match_status=0, raw_text='', use_cache=False): """ 工作空间状态 :param text: :return: :return: """ out = raw_text if raw_text else ihelper.popen('git status') __status = 0 now = time.time() if use_cache and iglobal.GIT_LAST_STATUS and iglobal.GIT_LAST_STATUS_TIME + 5 > now: __status = iglobal.GIT_LAST_STATUS #检查是否匹配某状态 if match_status: if __status: return __status & match_status else: return __workspace_match_status(out, match_status) #获取工作空间状态 if not __status: for s_code, patterns in iglobal.GIT_STATUS_PATTEN.items(): if __workspace_match_status(out, s_code): __status |= s_code iglobal.GIT_LAST_STATUS = __status iglobal.GIT_LAST_STATUS_TIME = now if not text: return __status else: return __status_code_to_text(__status)
def get_config(key=None): """ 获取git配置列表 :param key: :return: """ config = dict(map(lambda x:x.split('='), ihelper.popen('git config -l').splitlines())) return config[key] if key and config.has_key(key) else config
def fetch(output=False, useCache=True, branch=None): if iglobal.PROJECT not in iglobal.LAST_FETCH_TIME: iglobal.LAST_FETCH_TIME[iglobal.PROJECT] = 0 if branch: useCache = False now = time.time() if useCache and now - iglobal.LAST_FETCH_TIME[iglobal.PROJECT] < 10: # 10秒内只fetch一次 return cmd = 'git fetch' if branch: cmd = cmd + ' origin %s' % branch if output: ihelper.system(cmd) else: ihelper.popen(cmd) if not branch: iglobal.LAST_FETCH_TIME[iglobal.PROJECT] = now
def check_product_branch_has_new_update(): """ 检查生产分支是否有更新内容 检查方法:获取远程生产分支的最近一次commitid,检验该commitid是否出现在当前分支中 :return: """ prod_branch = product_branch() curr_branch = current_branch() if curr_branch in [prod_branch, test_branch()]: return #一天只检验一次 last_merge_date = ihelper.read_runtime('last_merge_date') if last_merge_date \ and last_merge_date.has_key(curr_branch) \ and last_merge_date[curr_branch] == datetime.datetime.now().strftime('%Y-%m-%d'): return info(u'正在检查%s分支有无更新...' % prod_branch) #拉取最新生产分支 fetch(branch = prod_branch) #拉取最新当前分支 fetch(branch=curr_branch) #获取生产分支最新一次提交的commit_id last_cmt_id = __get_last_commit_id(prod_branch) if not last_cmt_id: return #检查该commit_id是否在当前分支上 if not ihelper.popen("git branch --list -a --contains %s *%s" % (last_cmt_id, curr_branch)).splitlines(): warn(u'%s分支已有更新,请执行merge指令合并到当前分支' % prod_branch) else: set_last_sync_master_date(curr_branch)
def check_workspace_health(): """ 检查工作区是否健康:是否处于conflict、rebasing状态 :return: """ text = ihelper.popen('git status') if workspace_at_status(iglobal.GIT_CONFLICT, raw_text=text, use_cache=True): if workspace_at_status(iglobal.GIT_REBASING, raw_text=text, use_cache=True): warn(u'rebase出现冲突。请手工解决冲突后执行 git add . && git rebase --continue 继续完成操作。或者执行 git rebase --abort取消操作') elif workspace_at_status(iglobal.GIT_CHERRING, raw_text=text, use_cache=True): warn(u'cherry-pick出现冲突。请手工解决冲突后执行 git add . && git cherry-pick --continue 继续完成操作。或者执行git cherry-pick --abort取消操作') elif workspace_at_status(iglobal.GIT_MERGING, raw_text=text, use_cache=True): warn(u'merge出现冲突。请手工解决冲突后执行 git add . && git commit 完成合并操作。或者执行 git merge --abort取消操作') else: warn(u'当前工作区存在冲突,请手工处理冲突后执行 git add . && git commit 解决冲突') elif workspace_at_status(iglobal.GIT_REBASING, raw_text=text, use_cache=True): warn(u'工作区正处于rebasing中,请执行 git rebase --continue 完成操作') elif workspace_at_status(iglobal.GIT_CHERRING, raw_text=text, use_cache=True): warn(u'工作区正处于cherry picking中,请执行 git cherry-pick --continue 完成操作') elif workspace_at_status(iglobal.GIT_MERGING, raw_text=text, use_cache=True): warn(u'工作区正处于merging中,请执行 git commit 完成操作') elif ihelper.read_runtime('publish_branches'): warn(u'上次发布尚未完成,请解决冲突后执行 ft p --continue 继续完成发布。或者执行 ft p --abort 结束该发布')
def __get_last_commit_id(branch, remote=True): if remote: branch = 'origin/' + branch return ihelper.popen("git log -1 --pretty=%H " + branch)
def git_version(): """ 获取git版本 :return: """ return re.search('[0-9]{,2}\.[0-9]{,2}\.[0-9]{,2}', ihelper.popen('git version')).group(0).split('.')
def local_branches(): """ 所有的本地分支列表 :return list """ return map(lambda x:str(x).lstrip('*').strip(), ihelper.popen('git branch').splitlines())