一份源码 要让团队里的人能够轻松地拉取。
以下是我的搭建过程。
1.关于源码及相关编译环境参考我之前的一篇博文https://blog.csdn.net/qq_28449863/article/details/79978937
2.简单做个描述
所有电脑都处在局域网下。
一台服务器(UbuntuServer),有几个用户(开发者),另外有一台电脑来管理服务器上的代码(就叫管理员吧)
要做到开发者都能从服务器那拉取代码和更新代码。()
3.先搭好git+repo的简单服务器
具体参考https://blog.csdn.net/qq_28449863/article/details/79992191
4.在此之前请确保上述要求都能满足
最头痛的一步
接下来的就是怎么把Android的源码弄上去了,我这里是谷歌的Android-7.0.0.0-r32版本的源码。弄下来,以为把所有的源码全丢在一个文件下就行了,所以一开始就在管理员那把所有源码都丢进相当于apps的目录下,然后整个push到服务器。然而事情并不简单,当开发人员拉取代码时很多文件夹里面什么都没有。显然这样是不可取。repo是管理多个git的,源码里面本身就有一些git,并不是纯净的目录,所以在管理员push的时候,有些东西并不能push上去。即使是干净的源码,加之这个源码的量很大几十个G,每次push和pull的时候都把整个都这样操作很不方便,也失去了使用repo的意义,那跟单独使用git没区别。用repo就是为了管理多个git。
明白了这个就好多了,然后就是来处理这个源码了。分几个步骤。
1.清理源码使之成为纯净的目录(无特别说明都在源码的根目录下执行命令)
copy一份源码的default.xml 在源码的.repo/manifests/目录下,然后删除整个.repo 文件夹
rm -rf .repo
在删除整个目录中所有“.git”“.gitignore”文件
find . -name ".git" | xargs rm -rf
find . -name ".gitignore" | xargs rm -rf
执行完这些源代码就是干净的了,没git,没gitignore。
原default.xml(以Android8的一个版本为例,android7的跟它差不多一个样):
对其加以修改,我把那个name属性中的"platform/"路径去掉了(其实做不做这一步应该没关系),这个name对应的就是远程仓库的地址,即服务器上/home/git/repositories/下的仓库位置(只要一致就可以了)。不过替换也挺方便的。这样name跟path路径一致了。path代表本地同步时的本地路径。修改参考:https://blog.csdn.net/doubleface999/article/details/55798741
另外还需要修改下默认远程仓库的地址。根据你自己的来(一般替换为你服务器的ip地址即可)
将其保存为default.xml(以后会用的这个xml文件,很重要)
2.在gitosis系统中添加仓库组(这是能够在管理员那关联远程仓库并push上去的前提)
把修改后的default.xml和python脚本文件拷贝到管理员的gitosis-admin目录下,赋予脚本执行权限
脚本文件:gitosis.py
#!/usr/bin/python3
#把出现的git加入到gitosis系统中
import os
import sys
if len(sys.argv) == 1:
print('错误!请传入 xml 文件')
elif len(sys.argv) == 2:
print('错误!请传入 conf文件)
elif len(sys.argv) > 3:
print('错误!传入参数太多')
else:
print('传入的文件是 %s,%s' % (sys.argv[1],sys.argv[2]))
#newfilestr = ''
with open(sys.argv[1], 'r') as fin:
while True:
linestr = fin.readline()
if linestr == '': #表示文件结束
break
#print(linestr)
#下面开始对本行内容分析
if (('name=' in linestr) or ('name =' in linestr)) and (('project' in linestr) or ('path' in linestr)): #本行内容含有name信息
#print(linestr)
#下面分析本行内容,并提取name
charistr1 = 'name="'
charistr2 = '"'
gitprojstr = linestr[linestr.index(charistr1)+len(charistr1) : linestr.index(charistr1)+len(charistr1)+ linestr[linestr.index(charistr1)+len(charistr1):].index(charistr2)]
gitdir=os.path.split(gitprojstr)[0]
gitname=os.path.split(gitprojstr)[1]
print(gitdir)
print(gitname)
with open(sys.argv[2], 'a') as fout:
fout.write(' '+gitname)
修改前:
使用python脚本:
./gitosis.py default.xml gitosis.conf
修改后(脚本执行完,请手动修改一下gitosis.conf ,脚本添加的目录是另起一行添加的,务必把其改成以下形式,其中writeable 有多个路径<以空格隔开的>,每个路径代表一个.git目录,即在服务器上/home/git/repositories/下的仓库位置)
然后删掉之前添加的default.xml和gitosis.py
再add commit提交到远程,git push,更新gitosis配置。
3.初始化源码,并与远程仓库关联,提交后push。
把修改后的default.xml和脚本文件getnames_and_init_push_git_proj.py复制到之前处理过的干净源码目录下,并赋予脚本执行权限
getnames_and_init_push_git_proj.py内容如下:
#!/usr/bin/python3
import os
import sys
remote = '[email protected]:'#注意更改远程仓库地址
if len(sys.argv) == 1:
print('错误!请传入 xml 文件')
elif len(sys.argv) > 2:
print('错误!传入参数太多')
else:
print('传入的文件是 %s' % sys.argv[1])
with open(sys.argv[1], 'r') as fin:
while True:
linestr = fin.readline()
if linestr == '': #表示文件结束
break
#print(linestr)
#下面开始对本行内容分析
if (('name=' in linestr) or ('name =' in linestr)) and (('project' in linestr) or ('path' in linestr)):
#本行内容含有name信息
#print(linestr)
#先无条件提取name路径
charistr1 = 'name="'
charistr2 = '"'
namestr = linestr[linestr.index(charistr1)+len(charistr1) : linestr.index(charistr1)+len(charistr1)+ linestr[linestr.index(charistr1)+len(charistr1):].index(charistr2)]
if 'path=' in linestr: #如果path存在则用path的路径作为本地路径
charistr1 = 'path="'
charistr2 = '"'
pathstr = linestr[linestr.index(charistr1)+len(charistr1) : linestr.index(charistr1)+len(charistr1)+ linestr[linestr.index(charistr1)+len(charistr1):].index(charistr2)]
else: #如果path不存在,则认为path路径(本地路径)就是name路径
pathstr = namestr
print('name="%s", path="%s"' % (namestr, pathstr))
#下面开始初始化并提交git工程
localpath = sys.path[0] + '/' + pathstr # git工程的本地绝对路径
#remotepath = remote + '/' + namestr # git工程远程相对路径
remotepath = remote + namestr+'.git' # git工程远程相对路径,注意要与gitosis.conf 配置的路径一致
print(remotepath)
#判断本地目录是否为空,为空的话则新建一个文件,空目录会导致git提交失败
if not os.listdir(localpath): # 本地目录为空
#cmd = 'touch %s/._USELESSFILE_' % (localpath)
cmd = 'touch %s/.gitignore' % (localpath)
print(cmd)
os.system(cmd)
cmd = 'cd %s && rm -rf .git && git init && git remote add origin %s && git add . -f && git commit -m "init" &&git push -u origin master && cd %s' % (localpath, remotepath, sys.path[0])
print(cmd)
os.system(cmd)
执行脚本文件:./getnames_and_init_push_git_proj.py default.xml
等待。。。(此时就会在相应的目录下初始git,提交,关联指定的远程仓库,push上去)
直至命令执行完毕。
4.更新manifest.git(用于控制repo init时拉取哪些git)
将更新后的default.xml 复制到管理员的manifest目录下提交到远程服务器,更新manifest.git。
5.用户测试
现在关于安卓源码的repo服务器的就搭好了。
gitosis系统中的其他用户就可以拉取代码,这目录会就有真东西了,不像之前什么都没有。
先安装repo工具:
mkdir ~/bin
PATH=~/bin:$PATH
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
chmod a+x ~/bin/repo
修改repo文件内容中的 export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
mkdir adnroid7 && cd android7
repo init -u git://192.168.1.107/manifest.git -m default.xml
repo sync
repo init 中的 -m是指定相应的配置文件,根据这个配置文件来拉代码,默认为default.xml。所以上述-m也可以略去。当你的配置文件名不是default.xml时就需要加上这个 -m参数了
关于脚本的参考:http://nicekwell.net/blog/20171112/ba-yi-you-de-repogong-cheng-ti-jiao-dao-fu-wu-qi.html
注:当repositories目录下需存在多个项目时,且项目之间有重名的git,会产生重叠冲突。此时可通过在repositories目录下新建对应的项目来存储相应的git项。如:yota项目
在初始化和提交脚本中修改远程根地址为:remote = '[email protected]:yota/'
default.xml 修改
fetch用这种绝对地址比较稳妥。