1. 程式人生 > >【20180617】python--repo:project類學習

【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.演算法