【20180617】python--repo:project類學習
有日子沒更新了...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.演算法