def f2f(self, args): """ 修复分支转修复分支,默认转到下个迭代 :param list args: :return: """ if '-n' not in args and '-s' not in args: args.append('-n') b_info = self.__branch_and_sprint(args) if not b_info['branch']: raise exception.FlowException(u'未指定分支名称') old_branch = igit.real_branch( b_info['branch'], iconfig.read_config('system', 'branch')['feature_prefix']) new_branch = igit.real_branch( '%s/%s' % (b_info['sprint'], b_info['branch'].split('/')[-1]), iconfig.read_config('system', 'branch')['feature_prefix']) if not old_branch or not new_branch: raise exception.FlowException(u'分支名称不合法') if old_branch not in igit.local_branches(): raise exception.FlowException(u'分支不存在:%s' % old_branch) if ihelper.confirm(u'确定将特性分支%s转为特性分支%s吗?' % (old_branch, new_branch)) == 'y': git.Git('rename', [old_branch, new_branch]).execute() ok() else: ok(u'取消操作')
def f2h(self, args): """ 本迭代的特性分支转修复分支 :return: """ branch = None while args: branch = args.pop(0) if not branch: raise exception.FlowException(u'未指定分支名称') old_branch = igit.real_branch( branch, iconfig.read_config('system', 'branch')['feature_prefix']) new_branch = igit.real_branch( branch.split('/')[-1], iconfig.read_config('system', 'branch')['hotfix_prefix']) if not old_branch or not new_branch: raise exception.FlowException(u'分支名称不合法') if old_branch not in igit.local_branches(): raise exception.FlowException(u'分支不存在:%s' % old_branch) if ihelper.confirm(u'确定将特性分支%s转为修复分支%s吗?' % (old_branch, new_branch)) == 'y': git.Git('rename', [old_branch, new_branch]).execute() ok() else: ok(u'取消操作')
def rename(self): """ 分支重命名。old和new需要时绝对分支名 """ if len(self.args) < 2: raise exception.FlowException('指令格式错误,请输入help查看使用说明') old = self.args[0] new = self.args[1] local_branches = igit.local_branches() if old not in local_branches: raise exception.FlowException(u'分支名称不存在:%s' % old) remote_branches = igit.remote_branches() # 名称重复性检测 if new in local_branches or new in remote_branches: raise exception.FlowException(u'该分支已经存在:%s' % new) info(u'重命名分支:%s -> %s...' % (old, new)) # 重命名本地分支 ihelper.execute('git branch -m ' + old + ' ' + new, raise_err=True) # 删除远程分支(如果有的话) if old in remote_branches: ihelper.execute('git push --delete origin ' + old) # 上传新分支到远程 ihelper.execute('git push -u origin ' + new + ':' + new) #防止重命名后检查master更新情况 igit.set_last_sync_master_date(new)
def match_remoteonly_branch(self, prefix, text=None): """ 匹配远程存在而本地不存在的分支 :param prefix: :param text: :return: """ remote_only_branches = list( set(igit.remote_branches(True)) - set(igit.local_branches())) return self.__match_branch(prefix, text, remote_only_branches)
def match_branch(self, prefix, text=None, include_remote=False): """ 匹配当前项目的本地分支 :param bool include_remote: 是否包括远程分支 :type prefix: str|None :param text: :return: """ branches = igit.local_branches() if include_remote: branches = list(set(branches + igit.remote_branches())) return self.__match_branch(prefix, text, branches)
def delete(self): """ 删除本地匹配模式的多个分支,并删除远程相应分支 :return: """ if not self.args: raise exception.FlowException(u'指令格式错误,请输入help查看使用说明') tag_pattern = None del_remote = True del_branches = [] while self.args: c = self.args.pop(0) if c == '--no-remote': del_remote = False else: tag_pattern = c if not tag_pattern: raise exception.FlowException(u'请指定需要删除的分支匹配模式') for branch in igit.local_branches(): if branch == igit.product_branch(): continue if re.match(tag_pattern, branch): del_branches.append(branch) if not del_branches: warn(u'没有符合条件的分支') return #打印出将要删除的分支列表 warn(u'将要删除以下分支%s:' % ('(以及其对应的远程分支)' if del_remote else '')) for del_branch in del_branches: ok(del_branch) print if (ihelper.confirm( u'确定删除吗%s?' % ('(同时删除远程分支,删除后不可恢复)' if del_remote else ''), 'n') != 'y'): return #删除分支 for del_branch in del_branches: try: igit.delete_branch(del_branch, del_remote) except exception.FlowException, e: warn(str(e))
def create(self, args): """ 创建特性/修复分支。一次只能创建一个,会推到远端,且切换到此分支 :return: """ if not args: raise exception.FlowException(u'指令格式错误,请输入h %s查看使用说明' % self.cmd) branch = None auto_create_from_remote = False push_to_remote = True while args: c = args.pop(0) if c == '-y': auto_create_from_remote = True elif c == '--np' or c == '--no-push': push_to_remote = False else: branch = c if not branch: raise exception.FlowException(u'请输入分支名称') # 分支简称不可与项目、迭代名称相同(防止一些指令出现歧义) simple_branch = igit.simple_branch(branch) if simple_branch == iglobal.SPRINT or simple_branch in ihelper.projects( ): raise exception.FlowException(u'分支简称不可与项目或迭代名同名') branch = igit.real_branch(branch, self.cmd) # 检查当前分支下工作区状态 if not igit.workspace_is_clean(): raise exception.FlowException( u'工作区中尚有未提交的内容,请先用git commit提交或用git stash保存到Git栈中') # 分支名称重复性检查 info(u'检查本地分支...') if branch in igit.local_branches(): raise exception.FlowException(u'该分支名称已经存在') # 本地没有但远程有 create_from_remote = False info(u'检查远程分支...') if branch in igit.remote_branches(): if not auto_create_from_remote and ihelper.confirm( u'远程仓库已存在%s,是否基于该远程分支创建本地分支?' % branch) != 'y': return else: create_from_remote = True say(('white', u'正在创建分支'), ('sky_blue', branch), ('white', '...')) if create_from_remote: # 基于远程分支创建本地分支,会自动追踪该远程分支 ihelper.execute('git checkout -b ' + branch + ' origin/' + branch) else: # 切换到生产分支 p_branch = igit.product_branch() ihelper.execute('git checkout ' + p_branch) igit.pull() # 基于本地生产分支创建新分支 ihelper.execute('git checkout -b ' + branch) # 推送到远程 if push_to_remote: ihelper.execute('git push -u origin ' + branch + ':' + branch) if igit.workspace_is_clean(): #处理master更新检验,防止创建分支后执行master更新检查操作 igit.set_last_sync_master_date(branch) ok(u'创建成功!已进入分支:' + branch) else: raise exception.FlowException(u'创建分支失败')