接下来按照http://mercurial.selenic.com/wiki/ChineseTutorial中文教程中的情况来介绍检查仓库历史来说明一下很重要的改变集的思想,这也是和SVN的区别,对于改变集提交与其他用户的仓库冲突时怎么处理是我现在最理解不清楚的地方。但是了解Mercurial管理机制后就迎刃而解了。
这里还是不要破坏原版来翻译成中文,只通过对官方的Understanding Mercurial做些标识来简单的了解HG的操作原理:
http://mercurial.selenic.com/wiki/UnderstandingMercurial 此为官方原文,这里已经做了粘贴。
我们都习惯拿到工具先上手用用,这就必须在较早的提到HG的一些良好的习惯,这里先提到一个HG的良好使用习惯,是从svn转变需要注意的
在 Mercurial 开发实践中一个好的做法是把每个变更隔离在各自的仓库里。这样可以避免把不相关的代码混杂起来, 并且便于一个接一个的测试每一部分工作。我们现在就开始采用这一模式。
给新的 仓库 命名了一个描述性 的名字,基本上是说明这个仓库的目的。 在Mercurial里面给一个仓库创建[克隆]很方便,我们会很快的积攒起很多稍微不同的仓库。如果我们不给他们描述性的命名, 很快就会没法分辨它们。
Understanding Mercurial
Mercurial's decentralized development model can be confusing to new users. This page attempts to illustrate some of the basic concepts. See the Tutorialfor step-by-step instructions.
目录
- What's in a repository
- Committing changes
- Revisions, changesets, heads, and tip
- Cloning, making changes, merging, pulling and updating
- A decentralized system
- What Mercurial can't do
1. What's in a repository
Mercurial repositories contain a working directory coupled with a store: (此处为一个仓库中的情况,rev标识了revision,也是改变集,下一节着重深入介绍改变集)
(此处唯一要说的是rev3存在的情况下working directory可以指向rev2,HG还支持这样一种与之类似的两个commit之前的操作流程:
在一个文件上做了修改,还没有提交,但这时候需要回溯到修改前的版本,取消修改,可以使用revert命令。此时仍然可以再次改变到修改版本,HG为我们保存了修改的副本)
The store contains the complete history of the project. Unlike traditional SCMs, where there's only one central copy of this history, every working directory is paired with a private copy of the history. This allows development to go on in parallel.
The working directory contains a copy of the project's files at a given point in time (eg rev 2), ready for editing. Because tags and ignored files are revision-controlled, they are also included.
2. Committing changes
When you commit, the state of the working directory relative to its parents is recorded as a new changeset (also called a new "revision"):
Note here that revision 4 is a branch of revision 2, which was the revision in the working directory. Now revision 4 is the working directory's parent.
3. Revisions, changesets, heads, and tip
Mercurial groups related changes to multiple files into single atomic changesets, which are revisions of the whole project. These each get a sequentialrevision number. Because Mercurial allows distributed parallel development, these revision numbers may disagree between users. So Mercurial also assigns each revision a global changeset ID. Changeset IDs are 40-digit hexadecimal numbers, but they can be abbreviated to any unambiguous prefix, like "e38487".(此处是非常重要的,使用changeset ID来区分部署在所有用户机器上的不同仓库的修改,也是刚才提到的冲突解决的问题最关键的地方。下面还有例子会提到这种多用户的pull和push问题)
Branches and merges in the revision history can occur at any point. Each unmerged branch creates a new head of the revision history. Here, revisions 5 and 6 are heads. Mercurial considers revision 6 to be the tip of the repository, the head with the highest revision number. Revision 4 is a merge changeset, as it has two parent changesets (revisions 2 and 3).
4. Cloning, making changes, merging, pulling and updating
Let's start with a user Alice, who has a repository that looks like:
Bob clones this repo, and ends up with a complete, independent, local copy of Alice's store and a clean checkout of the tipmost revision d in his working directory:
Bob can now work independently of Alice. He then commits two changes e and f:
Alice then makes her own change g in parallel, which causes her repository store to diverge from Bob's, thus creating a branch:
Bob then pulls Alice's repo to synchronize. This copies all of Alice's changes into Bob's repository store (here, it's just a single change g). Note that Bob's working directory is not changed by the pull:
Because Alice's g is the newest head in Bob's repository, it's now the tip.
Bob then does a merge, which combines the last change he was working on (f) with the tip in his repository. Now, his working directory has two parent revisions (f and g):
(例子到这个地方已经说明了merge的关键实现方式,先将不同的版本存放在本地,将tip设给pull进来的最新的修改版本并由两个父类,后面会提到如果改变集有两个父类就是merge的情况,这里可以根据working dir有两个父节点发现需要merge的情况,之后可以在本地解决冲突,对于设置了公用服务器,同步到服务器的情况可以通过多次的操作可以完成版本控制。)
After examining the result of the merge in his working directory and making sure the merge is perfect, Bob commits the result and ends up with a new merge changeset h in his store:
Now if Alice pulls from Bob, she will get Bob's changes e, f, and h into her store:
Note that Alice's working directory was not changed by the pull. She has to do an update to synchronize her working directory to the merge changset h. This changes the parent changeset of her working directory to changeset h and updates the files in her working directory to revision h.
Now Alice and Bob are fully synchronized again.
5. A decentralized system(这里说明了central的情况,即提到的有服务器的情况,这部分非HG关注的,但是利用HG已有的机制很容易实现这种常用的工作形式,同时满足了解决了工作中提交代码申请的问题。普通的融合可以再两个人,多个人之间完成,只需要最终提交到中心测试过的模块的时候才需要审核)
Mercurial is a completely decentralized system, and thus has no internal notion of a central repository. Thus users are free to define their own topologies for sharing changes (see CommunicatingChanges):
Unlike a centralized version control system in which experimentation can be disastrous, with a DVCS like Mercurial, you just clone and experiment. If you like the results, push them back, otherwise wipe the cloned repository and try something else.
6. What Mercurial can't do(这里提到了HG不能做到的事情,也值得注意,更名明白HG的初衷,才能更好的使用)
Many SVN/CVS users expect to host related projects together in one repository. This is really not what Mercurial was made for, so you should try a different way of working. In particular, this means that you cannot check out only one directory of a repository.
If you absolutely need to host multiple projects in a kind of meta-repository though, you could try the Subrepositories feature that was introduced with Mercurial 1.3 or the older ForestExtension.
For a hands-on introduction to using Mercurial, see the Tutorial.