分类: LINUX
2011-09-08 15:58:54
目录
摘要
2011年04月11日 by dangbinghoo
Copyright(c) dangbinghoo All rights reserved
Mercurial(Hg)汞工具是个分布式的版本控制工具,不同于传统广泛使用的svn,cvs,vss这些集中式的 版本控制工具。 先区分下集中式和分布式的版本控制的不同:
集中式
仓库在一个服务器上,所有的更改都要提交到服务器,所以两个人并不能对同一个文件同时做出修改,这样,如果这两人必须等待相应文件是没有被锁定的,对于参与人数较多的较大项目,频繁的修改文件将需要大量的等待时间,很影响开发效率。
分布式
仓库在本地local,并不一定要放到集中的服务器上,对于文件所做的修改每次都是提交文件的修改集到本地仓库,所以服务器不在线并不影响工作。即便服务器丢失了仓库,因为每个本地仓库都有修改集,所以并不会丢失完所有信息。如果多人协作,修改集可以通过推送和拉取动作来在不同开发者的仓库之间同步。因为大部分操作是在本地,所以效率很高,对于多人同时完成一个项目就很适合了.
初始化一个本地仓库很简单,先建立一个目录比如helloprj,然后使用hg init helloprj或者在helloprj 目录下面执行hg init就可以了。这时候hg会自己建立.hg目录,在里面初始化供它记录信息用的数据结构, 实际上hg会追踪你的源码文件,然后你每次的提交它都会保存到.hg里面的相应数据结构中。
$ hg init helloprj $接下来我们建立一个文件,并且在里面做些改动,然后提交
$ touch hello.c $ 编辑 hello.c好了,使用 hg add 将hello.c加入跟踪
$ hg add hello.c adding hello.c如果你是想跟踪整个工程的好多文件 在顶层目录直接执行 hd add就可以了.
这时候我们使用 hg status 命令来查看当前仓库的状态:
$ hg status A hello.c这里看到大写字幕A,表示added,已添加hello.c文件
如果是?那就表示这是新建立的文件,还没有被hg纳入跟踪,那你就需要运行hg add命令了。
好了,我们再做些改动,再运行 hg status
$ hg status M hello.cM表示文件已经修改,所以随时运行hg status命令就可以看到文件的改动情况。
接下来我们需要将我们做的修改提交起来,让hg做好差异化保存
$ hg commit -m "这是第一次提交,刚添加了hello.c文件"然后我们再运行 hg status应该会看到什么也没有输出,这就表示你的仓库是干净的,没有新的改动出现。
刚才我们已经做了一次提交,这时候我们可以使用 hg log来看看
$ hg log可以看到,hg log打印出来了本仓库做的改动记录, 本次修改集 id为 0,因为这是我们第一次修改。 摘要里会显示本次的提交理由,这里我们通常对所作的改动作以解释。
如果对仓库继续做出修改并提交,会出现新的修改集
$ hg log可以看到多了一个 ID是1的修改集 ,这里我们就可以明白,hg 实际上会记录你每次的提交动作(commit),如果你只是对文件做了修改,却没有提交,那么修改集并不会产生。这时候你所的改动并不会被hg保存起来,所以你想悔改那是不可能的了。
注意 | |
---|---|
所以, 你一定要对你感觉正确的修改做出提交动作。 |
克隆一个仓库很简单,使用 hg clone就可以了,克隆操作会建立一个原仓库的副本
$ hg clone helloprj helloprj2 updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved然后使用我们之前的方法对helloprj2做出一些修改并且提交。
然后在helloprj仓库里执行拉取操作:
$ hg pull ../helloprj2由于helloprj2的父仓库就是helloprj,在helloprj没有变动的时候拉取hellprj2只是一些更新的修改集, 并不会产生分支。
这个时候只是拉取了helloprj2的改动到这里,这时候本仓库的文件还没有改变,如果要应用刚才拉取的prj2的 改动就需要运行 hg update命令:
$ hg update然后我们再对helloprj2进行改动,然后试试push操作
$ hg push ../helloprj这时候就可以在 helloprj仓库里执行 hg update来更新刚才推送的修改集。
$ hg update上一节我们只是对一个仓库进行了改动,然后来拉取和推送修改集,这一节我们将对同时对两个仓库都做修改,这就会产生分支,我们看看分支是如何产生的,以及如何合并分支。
在两个仓库里分别对hello.c文件的同一行做改动,然后分别commit,接着我们来在helloprj里面拉取 helloprj2的修改集:
$ hg pull ../helloprj2可以看到heads改变了,这时候我们可以使用 hg heads来查看下:
$ hg heads可以看到 修改集5的父集为3,也就是说顶集改变了,这个时候就是说两个仓库的改动是两个分支了, 需要进行合并(merge)工作:
由于我们修改的是文件的同一行,有冲突发生,命令行运行了diff编辑器让我们手动来解决冲突, 选择你认可的修改,然后保存,
$ hg merge由于我这里是linux系统,使用的gvim编辑器,所以hg调用了gvimdiff工具以进行手动合并。 然后我们看到提示信息 这是一个分支合并,不要忘记提交。
因为解决的分支合并的冲突是自己来修改文件,所以必须要提交了,按之前的方法提交即可。
这时候使用 hg log来查看信息:
$ hg log可以看到分支的明显标志: 父亲 修改集的出现。
注意 | |
---|---|
这里我们修改的是同一个文件的同一行,用过diff的读者应该清楚,diff是足够智能的,如果你只是添加了代码,diff会忽略空行,并且清楚你是添加了代码,而不会把新添加一行也作为冲突,所以如果你在两个分支里所做的改动diff认为不冲突,那么合并就会自动完成,并不会让你手动来编辑. |
运行 hg help 我们可以看到 hg serve命令,hg 具有web服务器的作用,使用 hg serve可以很轻易 的将我们的仓库以网络的形势呈现出来.
运行 hg serve就可以了,如果你需要改动端口号,那么请使用-p参数,默认hg 使用8000端口,
$ hg serve然后使用http://你的ip地址:8000就可以查看了,可以在里面看到分支的图形标示,及每次提交的更改 的diff显示。
$ hg serve -p 8080 127.0.0.1注意 | |
---|---|
hg serve得到的网络地址适合在开发者之间进行快捷的共享和协同开发,如果你是要发布你的版本库,请使用我们架设的代码托管服务器,在服务器上的地址你需要使用的形式,http是不支持push操作的. |
现在我们到仓库2中,并且再对hello.c做出修改,然后提交,接着我们进行网络推送
$ hg push可以看到网络推送是成功的,只是仓库2是分支,直接推送有冲突,默认并不直接覆盖。
不过现在我们应该清楚这个只需要在helloprj端进行pull操作然后merge即可。
到现在我们应该明白,其实hg的操作的确是在本地完成的,网络的仓库操作起来跟本地没什么区别,它只是 个本地外的仓库而已。
现在我们明白了hg的工作机理,实际上hg都是在记录修改集,所以从一个版本到另一个版本,修改集会变动,那么如果我们某次提交是错误的,我想换回到某次修改怎么办呢? hg update 加上-r参数即可,比较如要换到修改集3,那么使用
$ hg update -r 3即可。 这时候我们使用 hg summary可以看到当前的修改集
$ hg summary在经过一段时间的开发之后,我们可能觉得某个修改集是一个值得发布的版本,那么我就可以打上标记 使用 hg tag命令即可:
比如:
$ hg tag -r 0 v0.01
这时候我们 hg log查看:
修改集: 0:bedf4c4d526d以上是hg的基本操作流程,实际上hg的功能还很多,不过本教程只是个简明教程,完成和理解了本教程的内 容后自己查看相应的更具体详细的手册应该是容易的,所以这里推荐几个教程:
Mercurial权威指南(《Mercurial: The Definitive Guide》)
Mercurial Tutorial
Mercurial与TortoiseHg使用入门教程 (windows 用户使用图形界面的请多关注此教程)
hg 带help系统,任何命令都可以使用 hg help