Yuan Yijun (bbbush) wrote,
Yuan Yijun
bbbush

模块化

Git 的问题是不允许 partial 的 checkout。它的一个 commit 一定是整个树,它记录了整体的状态变化。很有道理,如果一个项目是有机的整体,那么的确密不可分。可是如果这个项目不是如此,又该怎么用 Git 维护呢?

例如我们的项目包括 A~Z 共 26 个模块,其中 A~G 是核心的七个模块,H~N 是另外七个核心的模块,用 A~N 这几个模块拼成一个产品,用 A~Z 拼成另几个产品,后来又有一个新的模块 A',用 A'~N 又可以拼成一个产品——而且是同时开发的。

我猜想,可以为每个产品建立 Git 仓库,其中模块 X 只在其中一个仓库中开发,而在其他仓库中只是简单的,定期或按需同步。

这是比较奇怪的地方。一方面,一个拥有这么多模块的项目,模块之间一定要相对独立。另一方面,Git 在提醒并强化这种意识:这些模块并不是没来由地凑在一起,确实是密不可分的。如何表达“其中某些模块的关系更紧密一些”呢?



BTW, 经过了两周小规模的 Git 应用,也就是为每个模块准备一个 Git 仓库,现在有些烦了:我们有五个模块要维护,两个人,两个版本,就是 20 个工作目录,还不算有多少个分支在里头。规模小的好处是速度快,尤其是像我们只能在 win32 上工作的时候。但是仓库太多,维护不容易,再者体现不出原子性:简直没法想每次要跑三个目录去 checkout 到某个分支,再做事情。现在我打算用一个很大的 Git 仓库(A~Z)。慢是会慢点啦。

我们的代码,single snapshot 是 13k files, 250M,压缩后(7z)是 35M,两个不同的 snapshot 导入同一个 Git 仓库,repack 之后只有 60M,在本地切换(checkout)和通过网上邻居,在同一子网的另一台机器上 checkout,都需要 2.5Min,算是不错的速度。另外还有些统计。git status 基本上没法用 (10s),git diff 也只适合对某个目录来做 (10s),比起小规模时,爽快感还是下降不少。不知道 Hg 怎么样?

历史数据,听说 VSS 数据库达到了 5G,当然包括非常多的项目,不止我们,而且还有很长的历史(中间因为数据库 corrupt 还截去了一大半的历史)。本以为 Git 不可能处理这么大的仓库的,后来从 OOo 网站上看到,OOo 的代码有 50G,导入 Git 也没什么问题,然则他们现在仍在用 CVS。从 CVS/VSS 这些不带原子性的仓库,导入到 Git 仓库的时候,一般都是怎么做的?

从 VSS 到 Git 时因为要 trim blanks, dos2unix, etc. 需要很长时间,所以不可能每个 commit 都导入吧。不管历史,为了 branch 和 merge/rebase,从现在做起。

记: http://www.selenic.com/mercurial/wiki/index.cgi/GenericConversion


This describes the basic steps needed to do history conversion from arbitrary formats, as implemented in Mercurial's convert-repo script:

    * Group changes into changesets
          o This step is difficult for systems that don't have atomic commits. See cvsps for an example of how this can be done with CVS. 
    * Associate a unique identifier with each changeset
    * Generate the revision graph by finding the parent changesets of each changeset
    * Generate a topologically sorted list of changesets such that parents precede their children
    * For each changeset:
          o Extract or generate a changeset description, user name, and date
          o Extract a copy of each file changed in the changeset
          o Use the Mercurial rawcommit interface to explicitly commit the changeset
          o Save a correspondence map between source changeset IDs and Mercurial changeset IDs so that the process can be
                + interrupted and resumed 
    * Convert tags
          o Generate a list of tags and their corresponding source changeset IDs
          o Use the correspondence map to convert tags to Mercurial IDs
          o Write a .hgtags file
          o Commit .hgtags file 




----


Git 的 submodule 有个强制的要求是 submodule 必须是在不同的目录中,另一个强制的要求是如果修改了 submodule,必须先 publish submodule changes,然后再更新 super。

如果对付不了 Git 的 submodule 和换行符的问题,那就没法再用它了。Git 的 crlf 设置大概可以是 binary,不做任何转换?in gitattributes(5), * crlf="0"




(22:17:51) bbbush@MSN:
你来不来我们公司,这里瞎忙,贼能瞎忙。
(22:18:07) Trent Zhou:
忙啥呢?
(22:19:09) bbbush@MSN:
我们用 VSS 管理代码,所有人都没有自己的分支,代码直接扔进去,于是我这周花了三天来 build ,结果都没法用。正经的 build manager 又不给做 tar ball
(22:19:51) bbbush@MSN:
VSS 又经常性的突然变得很慢,等取代码,等编译,等执行出错。我就瞎忙
(22:20:10) Trent Zhou:
果然瞎忙
(22:20:54) bbbush@MSN:
你们用的是什么来着?记得问过你
(22:21:02) Trent Zhou:
clearcase
(22:21:39) Trent Zhou:
每个人都用自己的branch,并遵循一定的流程把代码merge到main branch上
(22:22:32) Trent Zhou:
倒不大会出现代码冲突、编译不过的现象
(22:23:09) bbbush@MSN:
建立 branch 很简单吧?
(22:23:37) Trent Zhou:
很简单啊
(22:23:43) Trent Zhou:
cleartool mkbrtype branch_name
(22:23:49) bbbush@MSN:
能不能把你们的流程文档给我一份。我们也要用 clearcase 了,没接触过。BTW, 我们公司很多摩托过来的人似的。
(22:24:04) Trent Zhou:
有这种事??
(22:24:20) bbbush@MSN:
是美国那边的,两三个吧
(22:24:46) Trent Zhou:
moto没有统一的流程。一个产品开始的时候,会有专门的人制定这个产品所需要得流程
(22:24:48) bbbush@MSN:
两三个,因为巧合,所以觉得有些多。是老员工了。
(22:25:07) bbbush@MSN:
可是提交代码的 merge 过程呢,总是有个 common sense 吧
(22:26:46) Trent Zhou:
因为开发只有 一个main branch,开发的代码最终都是merge到main branch上面
(22:27:36) Trent Zhou:
但是merge之前,开发者必须先执行upmerge,也就是把main/LATEST上面的代码弄到自己的branch上面,编译测试通过才允许回main
(22:28:22) Trent Zhou:
而且代码必须经过review才能允许回main
(22:28:46) Trent Zhou:
所以不存在冲突的现象
(22:30:40) bbbush@MSN:
upmerge 对应 git rebase。看了很久的 git 了,现在还一头雾水。git 那个东西用得越多,越觉得细节里有魔鬼,流程上也说不清。现在是 text/binary 搞不定。
(22:32:01) Trent Zhou:
ub isPrint { my $c = shift; return $c =~ /\P{IsC}/ } Sample session: isPrint('a') 1 isPrint(chr(22)) isPrint(" ") 1 isPrint("\n") You can get fancier, and more perlish too: sub isPrintAll { my @letters = split(//, shift); return 0+(grep /1/, map {isPrint($_) ? 1 : 0} @letters) == 0+@letters; }
(22:33:24) bbbush@MSN:
自己的分支可以 apply 到多个 main branch 上吧,假如有多个 product/version 的话?
(22:33:50) Trent Zhou:
clearcase有一个概念,叫做branch type
(22:34:13) Trent Zhou:
就比方说,你要做一件事,可能需要修改10个文件
(22:34:32) Trent Zhou:
就可以先创建一个branch type,比方叫 my_br_type
(22:34:54) Trent Zhou:
然后再使用这个my_br_type为每一个文件创建branch
(22:35:19) Trent Zhou:
cleartool mkbrtype my_br_type cleartool mkbranch my_br_type file1 cleartool mkbranch my_br_type file2 ....
(22:35:25) bbbush@MSN:
每一个?那总共会有多少 branch 啊
(22:35:47) Trent Zhou:
对啊,一个branch type,每个文件上面都有branch
(22:36:08) Trent Zhou:
在clearcase里面,代码不是直接存在于文件系统种的
(22:36:15) Trent Zhou:
而是有一个数据库
(22:36:30) bbbush@MSN:
也就是 branch 是指每个文件有很多个版本?
(22:36:38) Trent Zhou:
nod
(22:36:55) Trent Zhou:
但是这个数据库可以通过一个特殊的文件系统给mount过来
(22:37:35) Trent Zhou:
为了把数据库映射成文件系统的模样,用户必须有一个view,每个view上面必须有config spec
(22:38:05) Trent Zhou:
config spec就类似于sources.list,上面写了哪一个文件使用哪个branch来取
(22:40:25) bbbush@MSN:
意思是两个文件各自的 branch 是无关的,如果 branch type 无关的话?然后可以用 config.spec 把无关的东西硬拉到一起? config spec 的版本呢?这里 branch type 好像和 CVS 的 branch 概念倒是一致的,而 branch 又是更细粒度的控制了,需要改 config spec 的时候多吗?
(22:41:20) Trent Zhou:
需要修改config spec的时候很多啊
(22:41:36) Trent Zhou:
但是一般做某一个工作的时候不需要改的
(22:42:23) Trent Zhou:
一般的config spec大概是这个样子: element * CHECKEDOUT element * .../my_br_type/LATEST element * PROJECT_BASELINE_LABEL element * /main/LATEST
(22:44:09) bbbush@MSN:
意思是,一个 branch type 总是作用于模块的,在 config spec 里包含了一个 branch type 时,总是包含这个 branch type 的所有文件,从而就是引用了整个模块?
(22:44:17) bbbush@MSN:
优先级是前面的最高?
(22:44:25) Trent Zhou:
nod
(22:44:34) bbbush@MSN:
LATEST 是什么?BASELINE_LABEL 呢?
(22:45:31) Trent Zhou:
LATEST指使用这个branch上面的最后一个版本。一个文件的某个branch上面可以有好多个版本的,你可以随时checkin,每次checkin都会涨一个版
(22:46:42) Trent Zhou:
当你有了一堆文件,在某一个时刻能够编译,这个时候你认为应该出一个release了,可以把所有文件的这个版本打上一个label
(22:46:56) Trent Zhou:
BASELINE_LABEL就是干这个用的
(22:47:32) Trent Zhou:
config spec里面也可以写 element file1.txt /main/my_br_type/2 这样的语句
(22:47:57) Trent Zhou:
意思是对于file1.txt,取/main/my_br_type上面的版本2
(22:50:04) bbbush@MSN:
看起来还挺好懂。thanks.
(22:50:20) Trent Zhou:
很直观
(22:50:22) bbbush@MSN:
config spec 的版本呢?
(22:50:32) Trent Zhou:
config spec没有版本
(22:50:39) Trent Zhou:
就是一个普通文件
(22:50:48) Trent Zhou:
所以说和sources.list很像嘛
(22:51:43) bbbush@MSN:
和别人的 branch 共享同样的 database 么? config spec 里可以指明别人的 branch?
(22:51:58) Trent Zhou:
可以阿
(22:52:06) bbbush@MSN:
万一大家用的 branch type 冲突了怎么办?
(22:52:27) Trent Zhou:
不可能有两个branch type同名的
(22:52:39) Trent Zhou:
因为操作的是同一个数据库啊
(22:52:46) bbbush@MSN:
比如我 test1, test2, test3... 人家也想用 test1, test2, test3... 可是我已经用掉了
(22:53:41) bbbush@MSN:
这个 clearcase 的观念和 CVS/git 真是不一样
(22:53:57) Trent Zhou:
git是分布式的典型
(22:54:10) Trent Zhou:
但是clearcase就是典型的集中管理
(22:54:45) bbbush@MSN:
你们对 branch type 的命名有规矩的吧,比如每个人有固定的 id prefix 之类?
(22:55:06) bbbush@MSN:
branch type 和 branch 在什么时候删掉?
(22:55:38) Trent Zhou:
是啊,这就是configuration manager做的事情了。每个开始的时候,会有专门的人制定规则,告诉开发人员必须用什么规则命名branch type
(22:55:44) Trent Zhou:
不会删掉
(22:56:02) Trent Zhou:
只要创建了,就在
(22:56:10) Trent Zhou:
当然可以手工删除
(22:56:27) Trent Zhou:
cleartool rmbranch file1@@/main/my_br_type
(22:56:46) Trent Zhou:
cleartool rmtype -rmall brtype:my_br_type
(22:57:35) bbbush@MSN:
所有的项目都扔到一个 clear case 数据库里?按什么收费的?项目有多大规模?用一个 config spec 产生 local tree 速度快不快?
(22:57:52) bbbush@MSN:
:D 赶得早不如赶得巧,问上了
(22:58:10) Trent Zhou:
一个数据库
(22:58:50) Trent Zhou:
按什么收费倒不清楚,估计每年要给ibm钞票吧
(22:59:03) Trent Zhou:
可以肯定这个数居库狂大
(22:59:04) bbbush@MSN:
@@
(23:00:17) Trent Zhou:
@@用来指定文件的版本
(23:02:08) bbbush@MSN:
:D ft
(23:12:08) bbbush@MSN:
睡了?bye bye,今天学到不少 :)
(23:13:12) Trent Zhou:
没睡呢
(23:13:23) Trent Zhou:
网上有很多clearcase的资料的
(23:13:33) Trent Zhou:
不爽的是它太复杂了
(23:13:39) Trent Zhou:
自己的电脑上玩不起来
(23:14:20) bbbush@MSN:
有那么复杂吗……
(23:14:30) bbbush@MSN:
用起来简单?
(23:15:15) Trent Zhou:
是啊,用起来简单而已
(23:15:34) Trent Zhou:
deploy很麻烦
(23:15:44) Trent Zhou:
要专人来做的
(23:16:59) bbbush@MSN:
怪不得 IBM ……


Tags: 工作
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments