有日子没更新了...Project类的实现略复杂和庞大因此看了好久,先整体总结一下。
1.概述
我们已经清楚repo借助xml的管理来实现批量git仓的操作,而这些操作又是通过封装git基础命令及底层命令来实现的,那么支撑这些git基础命令和底层命令封装实现的就是Project类,repo所有的子命令最终都会或多或少的调用Project类中的方法。
我们首先需要了解Project类的基本属性,然后按服务的不同子命令分别分析对应方法。
2.数据结构
project.py中定义了多个类,其中最重要的有三个:RepoHook、Project和MetaProject。
2.1 class RepoHook
(用于定义和调用xml中配置的repohook仓内hook,注意不是为各个gir仓配置来自repo/hooks目录的hook,此功能参考Project类的_InitHooks方法)
def __init__(self, hook_type,hooks_project, topdir,abort_if_user_denies=False)
def Run(self, user_allows_all_hooks, **kwargs)
def _ExecuteHook(self, **kwargs)
2.2 class Project
def __init__(self,manifest,name,remote,gitdir,worktree,relpath,revisionExpr,revisionId)
构造器方法中可以看到gitdir、worktree、work_git、bare_git、relpath等路径信息相关参数。
def IsRebaseInProgress(self) def IsDirty(self, consider_untracked=True)
常用的判断方法,例如判断worktree是否处于rebase中,worktree是否被修改(包括缓存区)等
def CurrentBranch(self) def GetRemote(self, name) def GetBranches(self)
常用的信息获取方法,例如获取当前分支、获取所有本地分支等
2.2.1 对应repo status子命令的方法
def HasChanges(self)
def PrintWorkTreeStatus(self, output_redir=None)
def PrintWorkTreeDiff(self)
2.2.2 对应repo upload子命令的方法
def GetUploadableBranches(self, selected_branch=None) def GetUploadableBranch(self, branch_name)
def UploadForReview(self, branch=None,people=([],[]),auto_topic=False)
def UploadNoReview(self, opt, branch=None)
2.2.3 对应repo sync子命令的方法
def Sync_NetworkHalf(self, quiet=False, is_new=None)
Sync_NetworkHalf方法完成Sync过程的前半段(网络交互和检查部分),它调用了_InitGitDir / _InitRemote / _ApplyCloneBundle / _RemoteFetch / _InitMRef 等方法完成下载git仓的网络相关准备工作,同时调用GetRevisionId方法来检查要下载的revisionid是否存在。
def Sync_LocalHalf(self, syncbuf)
Sync_LocalHalf方法完成Sync过程的后半段(本地操作部分),它除了调用_InitWorkTree和_Checkout方法完成本地工作空间的处理外,还执行了非常多的检查动作以应对本地工作空间中各类异常情况,例如:IsRebaseInProgress方法检查是否在rebase过程中,_revlist方法对比远端revision与本地HEAD来得知是否需要更新或丢弃本地提交,以及_revlist方法对比本地是否存在与中心库差异的提交等。
def DownloadPatchSet(self, change_id, patch_id)
2.2.4 对应branch管理(repo start等子命令)的方法
def StartBranch(self, name)
def CheckoutBranch(self, name)
def AbandonBranch(self, name)
2.2.5 对应git命令的方法
def _RemoteFetch(self, name=None, tag=None,initial=False,quiet=False,alt_dir=None)
def _FetchBundle(self, srcUrl, tmpPath, dstPath, quiet)
def _Checkout(self, rev, quiet=False)
def _ResetHard(self, rev, quiet=True)
def _Rebase(self, upstream, onto = None)
def _FastForward(self, head)
def _InitGitDir(self)
def _InitHooks(self)
def _InitRemote(self)
def _InitWorkTree(self)
def _revlist(self, *args, **kw)
2.2.6 class _GitGetByExec
Project类中还定义了一个比较重要的类_GitGetByExec,它用于生成work_git和bare_git对象以执行一些git底层命令。
def __init__(self, project, bare)
def LsOthers(self)
def DiffZ(self, name, *args)
def GetHead(self)
def SetHead(self, ref, message=None)
def DetachHead(self, new, message=None)
def UpdateRef(self, name, new, old=None,message=None,detach=False)
def rev_list(self, *args, **kw)
3.主体思路
按照git底层命令、git基础命令、repo子命令三个层级分别定义方法,并逐层调用。
4.算法