版本控制
版本控制相关
Android repo 魔法
8月31日
Android 为企业提供一个新的市场,无论大企业,小企业都是处于同一个起跑线上。研究 Android 尤其是 Android 系统核心或者是驱动的开发,首先需要做的就是本地克隆建立一套 Android 版本库管理机制。
Android 使用 Git 作为代码管理工具,开发了 Gerrit 进行代码审核以便更好的对代码进行集中式管理,还开发了 Repo 命令行工具,对 Git 部分命令封装,将 百多个 Git 库有效的进行组织。要想克隆和管理这百多个 Git 库,还真不是一件简单的事情。
在研究 Repo 的过程中,发现很多文档在 Google Group 上,非“翻墙”不可看。非法的事情咱不干,直接阅读 repo 的代码吧。
阅读全部内容 »

Repo——另一个Git协同模型
8月31日
Git 的神奇之处在于,你可以用很多不同的方式来使用它,而不像 Subversion,只有集中式一种方式。
最近又发现了一个 Git 新的协同模型 —— Repo,这个协同模型对于一个项目用到了多个Git版本库的协同开发非常有效。
实际上,这是上周在给一个团队做 “Git培训” 时,发现该团队在 Android 开发中,需要使用 Repo 这个工具来维护 Android 代码。于是花了些时间研究,补充了新的一章到讲义中…

Subversion管理后台增加对SVN容灾的支持
8月29日
群英汇Subversion版本控制系统提供的基本服务,实际上已经包含了简单的容灾实现:
- 在本机使用 gistore 进行数据备份
- 在备机上用 git pull 进行每日一次的数据同步
这个方法对于大多数公司,对于非核心数据的容灾备份已经足够,但是对于代码,不同的公司有着不同的敏感度,可能每日一次的备份就不合适了。
最近在给一个客户进行SVN版本控制系统的实施时,就碰到了SVN服务器间建立镜像和实时备份的需要
- 两个异地的开发团队,每个团队工作在不同的本地版本库,可能会参考(读取)异地不同版本库的内容
- 异地团队中间通过无线网桥互联,互联网桥的通讯质量易受到环境、气候的影响
- 如果两个异地的SVN服务器能够互做镜像,可以实现双机热备
- 一个团队可以在本地的主版本库中读写,一旦有数据写入本地版本库,就会同步到无线网桥另外一端的版本库。反之亦然。
- 由于本地还提供无线网桥另外一端版本库的镜像,因此访问远程版本库可以改用本地镜像进行访问,实现本地读取速度。
如果需要写入,配置 SVN反向代理,实现透明的远程写入。
Subversion可以使用 svnsync 这一工具实现版本库的远程镜像,但是如果使用手工配置,对于客户数量众多的版本库,难以维护。加之很多版本库本身很大,从头建立同步可能会非常缓慢。
我们通过在SVN管理后台增加了一对儿插件,实现了对SVN容灾(镜像)的图形化配置界面。
阅读全部内容 »
Gistore 备份回滚改用分支实现
8月21日
Gistore 备份的回滚原来采用的方法是,建立和回滚 Tag(里程碑):
- 当 master 分支的提交(备份)数量达到预设次数(缺省200次),建立一个 Tag,如 gistore/1
- 当名为 gistore/XXX 的 tag 的数量达到一定程度,进行回滚,即:
- gistore/2 -> gistore/1
- gistore/3 -> gistore/2
- …
更改里程碑?!
正在写 Git 培训资料,开始写里程碑时,突然想到 gistore 实现中有更改里程碑的实现,这种实现是不好的:
- 里程碑在创建后,只在第一次同步(PULL)的时候,被获取
- 当里程碑修改后,其它人再执行 PULL 的时候,不会更新!
- Gistore原来的实现,如果发生备份回滚,远程同步的服务器不能获取更新后的Tag。在镜像服务器有失去部分备份历史的危险。
新的备份回滚用分支来实现
分支名称为 gistore/1, gistore/2, …。数字越大的分支保存近期的备份,数字小的保存老的回滚备份。

爱上Git——《Git培训讲义》摘录
8月17日
群英汇的开源版本控制系统服务和咨询主要是基于Subversion,群英汇的开源项目管理系统平台主要集成的也是Subversion。但是我们公司(群英汇)内部的开发一直在使用Git,所以实际上,我们在Git上也有着丰富的使用和管理经验。
最近一个客户选择了我们提供Git的培训和部署服务,于是从上周开始着手准备《Git培训讲义》。
这个客户是有着实际的需求,才不得不从 Subversion 迁移到 Git,虽然只是公司的部分项目组。
《Git培训讲义》中开头有一章,我给它命名为“爱上Git”,抓眼球是其次,主要是先让用户能够立刻“爱上Git”。
阅读全部内容 »
如何同步 Gistore 的备份数据?
8月14日
Gistore 在公司内部以及部分客户推广一段时间来看,还是很满意的,但是如何实施双机备份或者管理员远程克隆是一个问题。
- 每个需要同步 gistore 备份库的用户都需要建立单独的系统帐号?
- 或者引入复杂的 Git 库管理工具?
最新的解决方案非常的简单,只引入了一个系统帐号 gistore,使用该帐号进行备份库的克隆操作:
- 将同步者的公钥上传。可以使用下面的命令(需要开启 gistore 的口令认证)
$ ssh-copy-id -i id_rsa gistore@<REMOTE.SERVER>
- 使用 git 命令执行克隆操作。
例如下面的命令克隆 /etc/gistore/tasks/system 指向的 gistore 备份库$ git clone gistore@<REMOTE.SERVER>:system
那么是如何实现的呢?
- 使用了群英汇改进的 gitosis 提供 git 库访问控制服务
- 利用了改进后的 map 指令,将访问的 git 库的地址映射到对应的 gistore 备份库
例如访问 system,实际访问的是 /etc/gistore/tasts/system/repo.git 指定的代码库。相关的 map 指令:map readonly * = (.*):\1/repo
- 不对单个公钥连接进行身份识别,而是所有的登录用户都使用唯一帐号。这样简化了授权模型,降低了配置难度
实际上是在 /etc/ssh/sshd_config 中增加了如下设置:# ossxp gistore backup account settings: Match user gistore ForceCommand gitosis-serve gistore X11Forwarding no AllowTcpForwarding no AllowAgentForwarding no PubkeyAuthentication yes #PasswordAuthentication no - 以上的操作,都在安装群英汇 gistore 软件包的时候自动配置,无须人工介入。
pySvnManager 0.5 升级指引
8月9日
对于不能提供 SSH 远程登录服务器的用户,可以参照本文进行 pySvnManager 的升级。关于 pySvnManager 的新功能,参照:《pySvnManager新功能:LDAP用户同步》
升级的步骤简单的说就是:备份 -> 软件升级 -> 重启服务
阅读全部内容 »

pySvnManager 新功能:LDAP用户同步
8月8日
pySvnManager 升级到 0.5 版本,引入了数据库支持,数据库主要用于保存和 LDAP 用户帐号同步的用户帐号信息。
数据库采用 sqlite 数据库(如果需要也可以使用其它类型数据库),无须手动创建数据库,在 pySvnManager 运行时,会根据需要自动创建数据库。
在没有使用 LDAP 用户信息之前,pySvnManager 是读取 SVN 授权文件,从该授权文件中获取用户名单并显示。
可以看出这种实现的问题是:
- 在权限检查的用户列表中,只能看到用户登录ID,而看不到用户 ID 对应的用户名
- 显示的用户帐号很少(只有在 SVN 授权文件中引用的用户帐号才能显示)
- 为新用户授权,如果用户不在授权文件中,需要手工输入用户名,容易出错。
pySvnManager 0.5 增加了内置数据库和LDAP用户同步功能之后,再看 pySvnManager 中显示的用户列表:
你会发现新版本的用户列表(已经完成和LDAP同步):
- 除了显示用户ID外,还显示用户名
- 显示的用户多了很多,除了在 SVN 授权文件中引用到的用户外,LDAP 中授权的 SVN 用户也显示出来了
- 在为新用户授权时,不必手工输入用户,只需要进行一次 LDAP 用户同步,用户帐号信息自动显示出来。
那么如何进行LADP 同步呢?
我们把 LDAP 用户同步的按钮放在“角色管理”界面,只要点击其中的“和LDAP用户同步”图标按钮,自动完成同步。
其它改进还包括:更好的 IE6 支持,UI 的重新设计等等。我们会陆续协助客户完成软件升级。
用户手册也已经更新,参见: 《pySvnManager 用户手册》
关于如何升级到新版本的 pySvnManager,参照《pySvnManager 0.5 升级指引》
解决 gistore 备份数据中的 git 库(submodule)的备份
8月3日
昨天在从客户现场回公司的路上,想明白了 Gistore 备份出现的 AM 标识的备份数据就是含有变更的子模组。
之前 Gistore 不能解决的一个备份问题是,当备份的数据中包含 git 库,备份数据将不会保存在 gistore 版本库中,而是以 submodule 方式加入备份库。实际的效果是,数据没有备份下来。例如:
- 安装了 etckeeper,用于维护 /etc 下配置文件的变更。实际上 /etc 目录本身已经是一个 git 库了
如果在 gistore 任务建立前,/etc 目录已经 git 化,则不能有效的对 /etc 进行备份 - 某个备份数据的目录,被人为的 git 化。这可能是在 hacking 时遗留的 git 库
我在改动服务器的某些数据(如界面模板等),经常将目录 git 化,然后再修改/比较/提交
如果不能有效的对 git化的备份目录进行备份,肯定会收到惩罚。
在最早的实现中,只是在备份之后的后处理(post_check)查找以 git 子模组方式添加的目录,并打出相应的警告信息。如何能够自动进行处理,一直排在工作队列中,昨天晚上开始了修改。
检查子模组
首先要找出哪些目录是以子模组方式添加的。最开始想到了从状态中找出 AM 标识的子模组,进行修改,但是存在问题:1. 添加没有变更的git化的目录,不会显示为 AM(添加且含修改),而显示为 A(添加)。2. 不能有效的发现 gistore 版本库中已经提交数据中以 git 子模组方式添加的目录。
于是采用分析 git submodules status 命令的输出,确定子模组。不过这个命令需要多次迭代执行(遇到无 .submodules匹配报错退出),才能找到所有的子模组。
重新以普通目录和文件方式添加子模组
首先删除已经提交的按照子模组方式保存的目录,重新添加不能直接添加子模组目录,否则仍会按照子模组方式添加。采用的方法是:
- 删除已经按照子模组方式添加的目录
git –git-dir=repo.git rm –cached sub/module … - 在子模组目录下创建一个临时文件,并添加该临时文件
git –git-dir=repo.git –work-tree=run-time add sub/module/<TMPFILE> - 对子模组目录执行添加操作
git –git-dir=repo.git –work-tree=run-time add sub/module - 别忘了删除临时文件
git –git-dir=repo.git –work-tree=run-time rm sub/module/<TMPFILE> - 迭代执行,直到没有子模组发现为止
Gistore 版本升级为 0.2.3,在服务器上重新安装和执行,将原来子模组方式添加的目录重新纳入备份中,放心了。
Gistore 应用:备份博客数据
- 我们在公司服务器上创建了一个名为 wordpress 的任务,备份 wordpress 数据库导出文件,wordpress 配置文件,wordpress 插件目录,wordpress 上传图片及附件。
- 将 wordpress 任务的 git 库,加入 git 服务器中,并设置权限
- 每个有权限的公司员工,都可以使用 git 命令克隆/同步公司服务器上的 wordpress 版本库,将博客数据保存下来
Gistore(基于 git 的数据备份软件)升级至 0.2.x
7月29日
在 10年1月份的一篇 Gistore 发布声明的博客中 ,我介绍了我们自己开发的一个用户数据备份的小工具 Gistore。
是什么原因让我们开发备份工具呢?这是因为:
- 我们公司的数据备份的需要
- 客户数据备份需要更好用的软件
- rdiff-backup 和 flexbackup 的备份方案不够好
实际上 rdiff-backup 用做数据备份,已经足够好了,你可以从我们公司的维基中看到 rdiff-backup 的使用方法:
但是 rdiff-backup 的解决方案的问题是:
- 命令难记,包括我自己在数据恢复的时候还要一遍一遍的查阅文档
- 之所以命令难记,实际上是因为备份工具本身的使用率很低,只有在灾难恢复时候会用到,所以命令不熟悉是一定的。
- 数据的异地镜像比较复杂,需要引入其它工具
为什么不用 Git 开发一款工具呢?
- Git 的命令天天在用,实在是太熟悉了
- Git 的数据同步太方便了,在同步过程能够实时查看进度
此次 Gistore 升级,解决了半年多的使用过程中积累问题,并且增加了易用性。





最新评论