1. 程式人生 > >repo詳解與如何更改manifest快速獲取和複用AOSP程式碼

repo詳解與如何更改manifest快速獲取和複用AOSP程式碼

源起

現在很多企業的網路一般都比較快, 但是有的企業卻會限速, 如果需要從github和google code上面git clone大的倉庫的話, 那麼需要耗費的時間是很客觀的,  例如從github或者google code, 或者其他託管服務站點獲取Android中需要的多個Kernel倉庫, 一般一個kernel倉庫都有幾GB, 如果是100KB/S的話, 那麼將需要很長的時間.

與此同時, 不同的Android 版本(AOSP)程式碼, 他們一般都會依賴許多相同的元件, 甚至獲取相同的倉庫程式碼, 僅僅只是branch或者tag不同而已, 例如對於Nexus 7 flo平板而言, 不管是AOSP 4.4 Kitkat還是 5.X Lolipop, 都會去下載flo-kernel這個核心, 他們都remote都是一樣的, 唯一不同的是tag使用的不同, 因此如果我們已經獲取過Kitkat的程式碼,那麼就可以複用其中的bare repo, 從而達到快速clone.

要了解如何做, 我們需要對AOSP的程式碼結構非常熟悉, 一般而言, 如果是系統工程師,那麼幾乎對AOSP的每一個目錄都會很熟悉, 對自己需要編譯的target的依賴的每一個repo都幾乎會心中有數(例如external中的哪些, vendor, device都會用到哪些), 這種情況下, 就可以刪除某些倉庫的下載, 從而節省時間.

總結起來, 要節省git clone的時間就是從兩個方面入手:

  • 1. 複用已經clone的bare repo
  • 2. 不要clone不需要的repo

repo分析

在實現前面的兩點之前, 除了對AOSP的編譯, 以及Target的依賴很熟悉外, 我們還需要對google 的 repo工具以及其流程有個基本的熟悉和了解.

repo的執行過程

  1. 解析傳入的args
  2. checkout下來最新的repo
  3. 找到manifest的目錄
  4. 解析manifest.xml
  5. 根據manifest或者其他xml檔案呼叫git clone --bare-repo獲取xml中定義的clone repo
  6. 從.repo/projects中的bare repo根據manifest xml中的projects資訊checkout到當前目錄

具體檢視repo這個python指令碼的原始碼.

下面使用具體例子來講解.

repo init

repo init -u https://github.com/bluez-android/aosp_platform_manifest.git -b lollipop

這個init呼叫傳入的-u這個用於指定需要下載的manifest的倉庫地址: 
def _Checkout(cwd, branch, rev, quiet):
  """Checkout an upstream branch into the repository and track it.
  """
  cmd = [GIT, 'update-ref', 'refs/heads/default', rev]
  if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
    raise CloneFailure()

  _SetConfig(cwd, 'branch.default.remote', 'origin')
  _SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch)

  cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default']
  if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
    raise CloneFailure()

  cmd = [GIT, 'read-tree', '--reset', '-u']
  if not quiet:
    cmd.append('-v')
  cmd.append('HEAD')
  if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
    raise CloneFailure()



例如前面的 init 執行完成後, 我們可以看到在.repo目錄下有一個manifest.git目錄:

$ cd .repo/manifests.git/

$ git remote -v
origin	https://github.com/bluez-android/aosp_platform_manifest.git (fetch)
origin	https://github.com/bluez-android/aosp_platform_manifest.git (push)

注意這個manifest.git屬於bare repo , 然後repo會checkout一份出來manifest working tree到manifest目錄, 且使用的就是前面repo init中的-b指定的branch:
.repo/manifests

$ git status
On branch default
Your branch is up-to-date with 'origin/lollipop'. // branch -b指定後在這裡

然後我們可以看到有一個manifest.xml會指向checkout的working tree中的xml:
cd /Dir/Contain/.repo/../

$ ls -l
total 12
drwxrwxr-x  3 hexiongjun hexiongjun 4096 Feb 15 10:57 manifests // 從下面這個bare repo checkout
drwxrwxr-x 10 hexiongjun hexiongjun 4096 Feb 15 10:54 manifests.git  //bare repo
lrwxrwxrwx  1 hexiongjun hexiongjun   21 Feb 15 10:40 manifest.xml -> manifests/default.xml
drwxrwxr-x  7 hexiongjun hexiongjun 4096 Feb 15 10:40 repo // repo本身的working tree checkout

repo本身的checkout

在repo init執行的時候會到: https://gerrit.googlesource.com/git-repo

checkout最新的repo, checkout下來後放在了.repo/repo目錄

manifest的修改

前面的ls -l命令中列出了manifest.xml指向的是manifests/default.xml, 然後這個xml中會指明各種fetch的url, 版本revision, 以及需要checkout下來的projects, 例如:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>

  <remote  name="aosp"
           fetch=".." />
  <default revision="refs/tags/android-5.0.0_r7"
           remote="aosp"
           sync-j="4" />

  <project path="build" name="platform/build" groups="pdk,tradefed" >
    <copyfile src="core/root.mk" dest="Makefile" />
  </project>
  <project path="abi/cpp" name="platform/abi/cpp" groups="pdk" />
  <project path="art" name="platform/art" groups="pdk" />
.............
  <include name="bluez-android.xml" />

</manifest>


裡面的remote就是git remote獲取得到的remote name, fetch指定的是從哪裡checkout projects, 隨後指定了revision, 以及sync的並心數.

接下來是projects的list, path指定checkout下來後放到哪裡, 例如下面這行:

  <project path="device/htc/flounder-kernel" name="device/htc/flounder-kernel" groups="device,flounder" clone-depth="1" />
指定了從fetch/name這個位置clone, 因為repo本身會將所有的projects放到.repo/projects目錄下面, 這個存放的位置就是由後面的groups來指定的, 例如上面的flounder-kernel的repo 本地bare repo位於:

.repo/projects/device/flounder-kernel.git

而這個repository的objects則位於:

.repo/project-objects/aosp_device_asus_flo-kernel.git/

這個objects目錄大小為:

$ du -sh ../../project-objects/aosp_device_asus_flo-kernel.git/
1.2G	../../project-objects/aosp_device_asus_flo-kernel.git/


然後repo在為每一個project建立了bare repository之後, 會從本地使用git clone一份出來, 且版本為前面指定的revision.

最後xml還可以使用include來包含, 實現"過載"

瞭解了repo的工作過程後,我們就可以想辦法來重用以前的bare repository了, 也知道如何不去clone和建立不需要的project的bare repository.

如何重用已有的bare repo倉庫來加快clone

假設我們已經有了一個AOSP 4.4 Kitkat的flo-kernel的bare repository了, 而AOSP 5.1 Lollipop也需要fetch 這個project,那麼我們就可以按照下面這個方式來做.

1. 拷貝project objects到對應目錄

2. 拷貝projects下的對應目錄到新的需要checkout的目錄, 例如從AOSP4到5

然後直接repo sync, sync完成後, 我們可以看到對應的branch被重新checkout下來了:

$ git branch  -a
  remotes/github/kitkat
  remotes/github/lollipop
  remotes/m/kitkat -> github/kitkat
  remotes/m/lollipop -> github/lollipop
可以看到既有kitkat也有lollipop, 這個和我們期望的一致:
  <project path="device/asus/flo-kernel" name="aosp_device_asus_flo-kernel" groups="device,flo" revision="lollipop" remote="github" />

這個xml中的project還指定了路徑, 我們到裡面確定一下:
 cd ../device/asus/flo-kernel/

$ git branch  -a
* (no branch)
  remotes/github/kitkat
  remotes/github/lollipop
  remotes/m/kitkat -> github/kitkat
  remotes/m/lollipop -> github/lollipop

然後我們使用gitk看看, 可以確定是我們需要的branch中:

刪除不需要的程式碼倉庫

例如我們使用的Nexus 7 flo來做開發, 並不需要Nexus 9等其他的核心, 那麼可以直接在xml中註釋掉其他的, repo就不會去下載了:


如果後來又需要checkout這些倉庫,那麼取消註釋, 然後重新repo sync即可.

也可以使用remove-project指定, 如同上圖中的前面幾行.

其他的例如drawn, MIPS等一些用不到的倉庫也可以刪除掉.

相關推薦

repo如何更改manifest快速獲取AOSP程式碼

源起 現在很多企業的網路一般都比較快, 但是有的企業卻會限速, 如果需要從github和google code上面git clone大的倉庫的話, 那麼需要耗費的時間是很客觀的,  例如從github或者google code, 或者其他託管服務站點獲取Android中需要

Go語言I/O多路netpoller模型

> 轉載請宣告出處哦~,本篇文章釋出於luozhiyun的部落格:https://www.luozhiyun.com > > 本文使用的go的原始碼15.7 可以從 Go 原始碼目錄結構和對應程式碼檔案瞭解 Go 在不同平臺下的網路 I/O 模式的實現。比如,在 Linux 系統下基於 epoll,free

併發系列(九)-----AQS共享模式的資源獲取釋放

一 簡介     到目前為止已經知道了AQS中同步佇列的基本的工作原理可以總結為維護同步佇列,獲取資源和改變執行緒狀態。上一篇文章中主要總結了獨佔模式下的資源獲取。這篇主要總結一下AQS中的共享模式。    共享模式從字面上理解就是,這個資源可以被

併發系列(八)-----AQS獨佔模式資源的獲取釋放

一 簡介 上一篇總結了AQS的整體架構,以及它的組成,和它們之間的關係。AQS主要的三部分分別是volatile修飾的變數、同步佇列和等待佇列其中,同步佇列在上篇總結中已經介紹過了,不知道的話可以點這裡AQS的框架組成以及同步佇列原始碼解析。這一片文章主要總結獨佔模式下資源的獲取。 二

python子進程模塊subprocess應用實例 之三

app 命令執行 windows rom not tput 一個 網絡 shell命令 二、應用實例解析 2.1 subprocess模塊的使用 1. subprocess.call >>> subprocess.call(["ls", "-l"]) 0

#20 ifconfig、route、netstat、ip、ss命令修改主機名網卡配置文件

ifconfig、route、netstat、ip、ss命令詳解與修改主機名與網卡配置文件 網絡的結構: 硬件:計算機、互聯設備、網絡設備 軟件:操作系統、協議、應用程序、數據庫 網絡的功能: 資源共享:目的 數據通信:手段 網絡通信模型 ISO/OSI: 應用層

centos/linux alternativesupdate-alternatives軟件版本切換

等等 ava 包括 blank 多個 config etc 兩種模式 版權 update-alternatives是linux系統中專門維護系統命令鏈接符的工具,通過它可以很方便的設置系統默認使用哪個命令、哪個軟件版本,比如,我們在系統中同時安裝了open jdk和

iptablesCentos7 關閉防火墻

tex new color sta pos firewalld 如果 火墻 blog http://www.cnblogs.com/metoy/p/4320813.html CentOS 7.0默認使用的是firewall作為防火墻,使用iptables必須重新設

#26 Linux kernel(內核)uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法

linux kernel(內核)詳解與uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法Linux kernel: 內核設計流派: 單內核設計,但是充分借鑒了微內核體系設計的優點,為內核引入了模塊化機制,內核高度模塊化; 內核被模塊化之

Linux下的監控器之一Ganglia部署

集群 服務器 監控器 Ganglia基礎詳解Ganglia介紹 Ganglia是一個跨平臺可擴展的,高性能計算系統下的分布式監控系統,如集群和網格。它是基於分層設計,它使用廣泛的技術,如XML數據代表,便攜數據傳輸,RRDtool用於數據存儲和可視化。它利用精心設計的數據結構和算法實現每節點間並發

px em rem的區別

聲明 -c -s 項目 屏幕分辨率 div 推薦 項目開發 pre 在前端項目開發中,px,em,以及rem都是頁面布局常用的單位,雖然它們是長度單位,但是所含的意義不一樣。通過復習和查閱,總結了以下知識。 px像素(Pixel)     定義:相對長度單位

[js高手之路] dom常用節點屬性兼容性應用

asc 子元素 種類型 process 變色 tex 如果 結構 節點和 一、每個DOM節點都有一個nodeType屬性,表示節點類型, NodeType一共有12種類型,我們可以通過遍歷內置的Node構造函數獲取 1 window.onload =

[crash防護] KVO crash

eval nat new mat not 自身 init 步驟 Coding 一、KVO介紹 KVO(Key-Value Observing),鍵值監聽。它提供一種機制:指定的被觀察者的屬性被改變後,KVO就會通知觀察者,觀察者可以做出響應。   KVO作用:利

Gradle命令導入第三方包

cst x86 簽名 更新 清除 容易 onu nali nag Android Studio + Gradle的組合用起來非常方便,很多第三方開源項目也早都遷移到了Studio,為此今天就來介紹下查看、編譯並導入第三方開源項目的方法。 Sublime + Termina

Linux centos關機重啟命令實戰

包含 動作 /var/ proc 電源 sign 沒有 時間 數據丟失 Linux centos重啟命令:   1、reboot   2、shutdown -r now 立刻重啟(root用戶使用)   3、shutdown -r 10 過10分鐘自動重啟(root用戶使

【基於初學者的SSH】struts2 值棧的struts2標簽庫+ognl表達式

radi ring etl action 值棧 多選 https submit 技術分享 一:什麽是值棧:struts2裏面本身提供的一種存儲機制,類似於域對象,值棧,可以存值和取值  特點:先進後出,最上面的元素叫做棧頂,也叫壓棧。  <s:debug><

Vue入門系列(五)Vue實例生命周期

auto res context mode parent all from bool silent 【入門系列】 【本文轉自】   http://www.cnblogs.com/fly_dragon Vue的實例是Vue框架的入口,其實也就是前端的ViewM

Dockerfile中的COPYADD指令比較

copy和add指令詳解與比較Dockerfile中的COPY指令和ADD指令都可以將主機上的資源復制或加入到容器鏡像中,都是在構建鏡像的過程中完成的。COPY指令和ADD指令的唯一區別在於是否支持從遠程URL獲取資源。COPY指令只能從執行docker build所在的主機上讀取資源並復制到鏡像中。而ADD

log4j.properties配置實例

尺寸 bject debug deb .com 大數 配置日誌 應用程序 登錄 最近使用log4j寫log時候發現網上的寫的都是千篇一律,寫的好的嘛不全,寫的全一點的嘛沒有一點格式,看著累。這裏把網上收集到的整理了一下,並且全部都在機器上測試成功了。這麽好的文

CentOS DNS服務基於bind的智能DNS

cfa oba 主從 err 正向解析 程序 管理員 hint 查詢方式 Linux中通常使用bind來實現DNS服務器的架設 安裝bind 安裝DNS服務軟件Bind和相應工具包 #yum install bind bind-utils -y #service named