目录
对于每种流行的操作系统,都有已经构建的二进制软件包。这让在你的计算机上开始使用 Mercurial 变得很容易。
The best version of Mercurial for Windows is TortoiseHg, which can be found at http://tortoisehg.org. This package has no external dependencies; it “just works”. It provides both command line and graphical user interfaces.
Lee Cantey 为 Mac OS X 在 http://mercurial.berkwood.com 发布了 Mercurial 安装程序。
由于每种 Linux 发行版都有自己的包管理工具,开发策略和进度,从而很难给出安装 Mercurial 二进制包的全面说明。你安装的 Mercurial 版本,在很大程度上依赖于你所使用的发行版的 Mercurial 维护者的活跃程度。
为了让事情简单,我会致力于说明在最流行的 Linux 发行版中,从命令行安装 Mercurial
的方法。这些发行版都提供了图形界面的包管理器,让你通过点击鼠标安装 Mercurial;寻找的包名称是
mercurial
。
位于 http://www.sunfreeware.com 的 SunFreeWare 提供了 Mercurial 的二进制安装包。
首先,我们使用 hg version 命令检查 Mercurial 是否已经正确安装。它打印出来的实际版本信息并不重要;我们只关心它是否能够运行,打印出信息。
$
hg version
Mercurial Distributed SCM (version 1.6.4) Copyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Mercurial 内置了帮助系统。当你不记得如何执行一个命令时,它会给你重要的帮助。如果你完全没有头绪,那就直接运行 hg help;它会给出命令的简短列表,还描述了每个命令的作用。如果你需要具体命令的帮助(下述),它会给出更详细的信息。
$
hg help init
hg init [-e CMD] [--remotecmd CMD] [DEST] create a new repository in the given directory Initialize a new repository in the given directory. If the given directory does not exist, it will be created. If no directory is given, the current directory is used. It is possible to specify an "ssh://" URL as the destination. See "hg help urls" for more information. Returns 0 on success. options: -e --ssh CMD specify ssh command to use --remotecmd CMD specify hg command to run on the remote side use "hg -v help init" to show global options
要获得更多的详细信息(通常不需要),可以执行 hg help -v
。选项 -v
是 --verbose
的短格式,告诉 Mercurial 要打印通常不需要的更多信息。
在Mercurial中,所有的操作都在版本库中进行。项目的版本库包括了属于该项目的所有文件和这些文件的历史记录。
版本库没有什么神秘的地方;仅仅是你系统中的一个目录树,Mercurial会将它们特殊处理。你可以在任何喜欢的时候使用命令行或者文件浏览器删除版本库或者给它改名。
拷贝版本库有点特殊。虽然你可以使用文件拷贝命令来复制一般版本库,最好还是用Mercurial内置的命令。这个命令叫做 hg clone,因为它创建了一个原来版本库的拷贝。
$
hg clone http://hg.serpentine.com/tutorial/hello
destination directory: hello requesting all changes adding changesets adding manifests adding file changes added 5 changesets with 5 changes to 2 files updating to branch default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
如上所示,使用hg clone的好处在于它能够让你通过网络克隆版本库。另外一个好处你它会记得这个版本库是从哪里克隆的,稍后会看到,当我们想从其他的版本库获取新的变更的时候这点这会非常有用。
如果我们克隆成功,我们会得到一个本地目录,叫做 hello
。这个目录会包括一些文件。
$
ls -l
total 0 drwxr-xr-x 3 oracle dba 120 Mar 17 03:00 hello$
ls hello
Makefile hello.c
这个版本库中的文件和我们刚才克隆的版本库中的文件相同的内容和版本历史
每个Mercurial版本库都是完整的,自包含的,独立的。它包含了项目文件的一份私有拷贝和全部历史。我们刚才已经提到,克隆的版本库会记住它克隆的那个版本库的地址,但是Mercurial不会和那个或者其他任何一个版本库通信,除非你给它命令。
对于一个新的,我们不熟悉的版本库,我们想做的第一件事就是了解它的历史。命令hg log可以让我们浏览版本库中的历史变更。
$
hg log
changeset: 4:2278160e78d4 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:16:53 2008 +0200 summary: Trim comments. changeset: 3:0272e0d5a517 user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 summary: Get make to generate the final binary from a .o file. changeset: 2:fef857204a0c user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 summary: Introduce a typo into hello.c. changeset: 1:82e55d328c8c user: mpm@selenic.com date: Fri Aug 26 01:21:28 2005 -0700 summary: Create a makefile changeset: 0:0a04b987be5a user: mpm@selenic.com date: Fri Aug 26 01:20:50 2005 -0700 summary: Create a standard "hello, world" program
缺省情况下,这个命令对项目中记录的每个变更都输出一段简介,在Mercurial的术语中,我们将这些记录的事件成为变更集,因为每个记录都可能包括几个文件的变更。
缺省情况下,hg log的输出仅仅是个摘要,没有更详细的信息。
图 2.1 “版本库 hello
的历史图”以图形化方式显示了版本库hello
的历史,这样很容易看出历史的“流向”。在本章和下面的章节中,我们会多次使用这个图。
英语是一种非常随便的语言,计算机史上也向来以混乱的术语为荣(如能用四个词为什么要用一个呢?),就版本控制而言,有很多词和短语有相同的意思。如果你和别人讨论Mercurial版本库的历史,你会发现“变更集”这个词常常被简化成“变更”或者(写的时候)“cset”,有时候变更集也指一个“版本”或者“rev”。
实际上,用哪个词来描述“变更集”的概念并不重要,重要的是如何用标识符来标识“一个特定的变更集”。回忆一下hg
log命令的输出,changeset
字段里用一个数字和一个十六进制字符串来标识一个变更集。
这个区别很重要。如果你通过邮件和别人讨论“版本33”,很有可能他们的版本33和你的不一样。原因在于版本号依赖于相应变更进入版本库的顺序。,不能保证同一个变更在不同的版本库中会有相同的次序。有可能三个变更a,b,c
在一个版本库中的次序是0,1,2
,而在另外一个版本库中则变成0,2,1
Mercurial使用版本号纯粹是为了有些命令的方便,如果你要和别人讨论变更集,或者由于某些原因为一个变更集做记录(如在bug报告中),请使用十六进制标识符。
如果只想用hg log查看一个版本的日志使用-r
(或者--rev
)选项。版本号和十六进制标识符都可以来指定版本,可以一次指定任意多个版本。
$
hg log -r 3
changeset: 3:0272e0d5a517 user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 summary: Get make to generate the final binary from a .o file.$
hg log -r 0272e0d5a517
changeset: 3:0272e0d5a517 user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 summary: Get make to generate the final binary from a .o file.$
hg log -r 1 -r 4
changeset: 1:82e55d328c8c user: mpm@selenic.com date: Fri Aug 26 01:21:28 2005 -0700 summary: Create a makefile changeset: 4:2278160e78d4 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:16:53 2008 +0200 summary: Trim comments.
如果你想显示几个版本历史,但是不想一个一个的列出来,可以使用
范围标记;它会显示包括abc
和def
,以及它们之间的所有版本的版本历史。
$
hg log -r 2:4
changeset: 2:fef857204a0c user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 summary: Introduce a typo into hello.c. changeset: 3:0272e0d5a517 user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 summary: Get make to generate the final binary from a .o file. changeset: 4:2278160e78d4 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:16:53 2008 +0200 summary: Trim comments.
Mercurial还可以指定版本的输出顺序,如hg log -r 2:4输出2,3,4。而hg log -r 4:2则输出4,3,2。
当你知道你在找那个版本的时候,hg
log输出的摘要是非常有用的,但有时候你不知道要找哪个版本,你想看到变更的完整描述,或者修改过的文件的列表,hg log命令的-v
(--verbose
)选项会给出更详细的信息。
$
hg log -v -r 3
changeset: 3:0272e0d5a517 user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:08:02 2008 +0200 files: Makefile description: Get make to generate the final binary from a .o file.
如果你想同时看到变更的描述和内容,增加-p
(--patch
)选项。这会将变更的内容以unified
diff的格式显示(如果你不知道unified diff,请参考第 12.4 节 “理解补丁”。
$
hg log -v -p -r 2
changeset: 2:fef857204a0c user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 files: hello.c description: Introduce a typo into hello.c. diff -r 82e55d328c8c -r fef857204a0c hello.c --- a/hello.c Fri Aug 26 01:21:28 2005 -0700 +++ b/hello.c Sat Aug 16 22:05:04 2008 +0200 @@ -11,6 +11,6 @@ int main(int argc, char **argv) { - printf("hello, world!\n"); + printf("hello, world!\"); return 0; }
我们休息一下,先不讨论Mercurial命令了,而是来看看它们工作的模式;这对以后的学习会非常有帮助。
Mercurial处理传递给它的命令选项的方法简单一致。它遵从现代Linux和Unix对选项的处理习惯。
Long options start with two dashes (e.g. --rev
), while short options start with one
(e.g. -r
).
Option naming and usage is consistent across commands. For example, every
command that lets you specify a changeset ID or revision number accepts both
-r
and --rev
arguments.
如果使用短选项,你可以把它们放在一起以减少输入。例如,命令hg log -v -p -r 2 可以写成 hg log -vpr2。
在本书的例子中,我通常使用短选项,很少用长选项。这仅仅是我个人的习惯,你不一定要这样。
Most commands that print output of some kind will print more output when
passed a -v
(or --verbose
) option, and less when passed
-q
(or --quiet
).
现在我们已经对查看Mercurial的版本历史有了一些了解,现在我们开始做些修改并且检查这些修改。
The first thing we'll do is isolate our experiment in a repository of its own. We use the hg clone command, but we don't need to clone a copy of the remote repository. Since we already have a copy of it locally, we can just clone that instead. This is much faster than cloning over the network, and cloning a local repository uses less disk space in most cases, too[1].
$
cd ..
$
hg clone hello my-hello
updating to branch default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved$
cd my-hello
说句题外话,保留远程版本库的一份“原始”拷贝是一个很好的习惯,这样你就可以为每个任务都创建临时的克隆作为沙盒。直到认务完成并且你准备好提交到版本库, 每个任务都和其他的独立,这样你可以并行工作。因为本地的克隆很方便,在任何时候克隆和销毁一个版本库都只有很小的开销。
在我们的my-hello
版本库中,有一个叫hello.c
的文件,它包含了经典的“hello,
world”程序。
$
cat hello.c
/* * Placed in the public domain by Bryan O'Sullivan. This program is * not covered by patents in the United States or other countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("hello, world!\"); return 0; }
# ... edit edit edit ...$
cat hello.c
/* * Placed in the public domain by Bryan O'Sullivan. This program is * not covered by patents in the United States or other countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("hello, world!\"); printf("hello again!\n"); return 0; }
Mercurial的hg status命令能告诉我们它对版本库中的文件有多少了解。
$
ls
Makefile hello.c$
hg status
M hello.c
hg
status命令对有些文件没有输出信息,但是对文件hello.c
,有一行以“M
”为开头的输出。除非你明确告诉它,命令hg status不会输出那些没有修改的文件的信息。
“M
”表明Mercurial已经发现我们修改了hello.c
。我们不需要在改文件之前,或者在修改完之后通知Mercurial;它自己能处理。
知道文件hello.c
被修改了很有用,但有时候我们想知道做了什么样的修改。这时,我们应该使用
hg diff命令。
$
hg diff
diff -r 2278160e78d4 hello.c --- a/hello.c Sat Aug 16 22:16:53 2008 +0200 +++ b/hello.c Thu Mar 17 03:00:28 2011 +0000 @@ -8,5 +8,6 @@ int main(int argc, char **argv) { printf("hello, world!\"); + printf("hello again!\n"); return 0; }
![]() |
理解补丁 |
---|---|
如果你不知道如何理解以上信息,请参考第 12.4 节 “理解补丁”。 |
我们可以修改文件,创建并测试我们的修改,使用命令hg status和hg diff复审修改,直到我们对修改满意,同时也达到了一个自然的停止点,然后用一个新的变更集记录我们的工作。
我们用命令hg commit创建新的变更集;我们通常把这个称为“做一次提交”或者“提交”。
当你准备第一次运行hg commit命令时,不一定会成功。对于你提交的每个变更,Mercurial都会记录你的名字和邮件地址,这样你和其他人以后就能分开是谁做的哪个变更。Mercurial会自动尝试找出一个有意义的用户名来提交。它会依次尝试以下方法:
如果你在主目录创建了名字为.hgrc
的文件,其中包括username
条目,那就用它。如果想知道这个文件的格式,请参考下面的第 2.7.1.1 节 “创建 Mercurial 的配置文件”。
Mercurial会查询你的系统,找出主机名和你的用户名,然后用他们创建一个用户名。这样的用户名不怎么有用,所以在只能这样生成用户名的时候,它会打印出一条告警信息。
如果所有的这些机制都失败了,Mercurial会执行失败退出,打印出一条错误信息这种情况下,只有你设定了用户名之后才能提交。
当你需要覆盖Mercurial缺省的用户时,可以考虑HGUSER
环境变量和hg commit命令的-u
选项。正常使用的情况下,最简单实用的方法就是创建.hgrc
文件来设定用户名;步骤如下。
设定用户名的时候,使用你最喜欢的编辑器在你的主目录创建一个名为.hgrc
的文件。Mercurial将会从这个文件中查找你的个人配置信息。你的.hgrc
开始的时候应该是这样子。
![]() |
Windows上的“主目录” |
---|---|
英文版的Windows的主目录通常是
|
# This is a Mercurial configuration file. [ui] username = Firstname Lastname <email.address@example.net>
配置文件中“[ui]
”这行标识着一个字段的开始,“username
=
...
”这行的意思是在ui
字段中设定项username
的值。当出现一个新的字段或者到达文件结尾的时候,当前的字段才结束。
我们提交一个变更的时候,Mercurial会打开一个编辑器,让我们输入一些信息来描述这个变更集做的更改。这就是提交日志。它会告诉读者我们改了什么以及修改的原因,我们提交之后,命令hg log会输出这些信息。
$
hg commit
hg
commit命令打开的编辑器包括一两个空行,接着是以“HG:
”开始的行。
This is where I type my commit comment. HG: Enter commit message. Lines beginning with 'HG:' are removed. HG: -- HG: user: Bryan O'Sullivan <bos@serpentine.com> HG: branch 'default' HG: changed hello.c
Mercurial会忽略以“HG:
”为开始的行;它仅仅用来告诉我们这个变更集中包括哪些文件。修改或者删除这行没有任何影响。
因为hg log命令在缺省情况下仅会输出提交日志的第一行,所以日志第一行最好是单独的一行。下面是一个日志的实例,它没有遵守这个规则,因此摘要可读性很差。
changeset: 73:584af0e231be user: Censored Person <censored.person@example.org> date: Tue Sep 26 21:37:07 2006 -0700 summary: include buildmeister/commondefs. Add exports.
至于日志的其他部分的内容,没有严格的规定。Mercurial并不解释或者关心日志的内容,虽然你的项目可能有某种格式的规定。
我个人喜欢简短,而又信息量大的日志,它能告诉我一些我不能通过快速浏览hg log --patch的输出而得到的信息。
如果我们运行hg commit命令的时候没有指定文件,它会提交我们做的所有修改,与hg status和hg diff这两个命令的输出一样。
提交完成后,我们就可以用hg tip命令显示刚刚创建的变更集。这个命令和hg log的输出一样,但是只显示版本库中最新的版本。
$
hg tip -vp
changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 files: hello.c description: Added an extra line of output diff -r 2278160e78d4 -r 2e443ac19c36 hello.c --- a/hello.c Sat Aug 16 22:16:53 2008 +0200 +++ b/hello.c Thu Mar 17 03:00:29 2011 +0000 @@ -8,5 +8,6 @@ int main(int argc, char **argv) { printf("hello, world!\"); + printf("hello again!\n"); return 0; }
我们通常把版本库中最新的版本称为tip版本或者简称为tip。
顺便提一下,hg tip命令可以接受很多和hg log命令一样的选项。如-v
选项的意思是“详细的”。-p
的意思是“输出补丁”。使用-p
输出补丁也是我们前面提到的一致性的另外一个例子。
前面我们曾经提到Mercurial的版本库是自包含的。这意味着我们刚才创建的变更集仅仅存在于我们的my-hello
版本库中。下面我们会看到几种将变更传播到其他版本库的方法。
首先,我们克隆原始版本的hello
版本库,它不包含我们刚刚提交的变更。我们将这个临时版本库称为hello
。
$
cd ..
$
hg clone hello hello-pull
updating to branch default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
我们用hg pull命令将变更从my-hello
拖到hello-pull
。然而,不管三七二十一将不了解的变更拖进版本库也实在是冒险。Mercurial提供了hg incoming命令,它会告诉我们hg
pull将会把哪些变更拖进版本库,但不会真正的执行。
$
cd hello-pull
$
hg incoming ../my-hello
comparing with ../my-hello searching for changes changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 summary: Added an extra line of output
运行hg pull命令将变更拖进版本库非常简单,你可以指定从那个版本库拖变更。
$
hg tip
changeset: 4:2278160e78d4 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:16:53 2008 +0200 summary: Trim comments.$
hg pull ../my-hello
pulling from ../my-hello searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy)$
hg tip
changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 summary: Added an extra line of output
从前后的hg tip的输出可以看出,我们成功将变更拖进了我们的版本库。然而,Mercurial将拖变更和更新当前工作目录分成两个操作。在看到在当前目录中我们刚拖进的变更之前,还有一步要完成。
现在我们已经对版本库和它的工作目录之间的关系有了粗略的了解。我们在第 2.8.1 节 “从其它版本库取得变更”一节运行的hg pull命令会将变更拖进版本库,但是如果我们检查一下的话,就会发现工作目录并没有变化。这是因为hg pull命令并不会影响工作目录。实际上,我们需要hg update命令来完成这个工作。
$
grep printf hello.c
printf("hello, world!\");$
hg update tip
1 files updated, 0 files merged, 0 files removed, 0 files unresolved$
grep printf hello.c
printf("hello, world!\"); printf("hello again!\n");
hg pull命令并不会自动更新工作目录,这看起来有点奇怪。但实际上这样做是有原因的:你可以用hg update来更新工作目录,切换到版本库中的任意一个版本。假设你将工作目录切换到一个老的版本—假如说是为了追踪一个bug—然后运行了hg pull命令。它自动将工作目录更新到新版本,这可能并不是你想要的结果。
因为拖然后更新是个非常常用的操作顺序,Mercurial允许你将这两个操作组合在一起,只要给hg
pull命令加上-u
选项就可以了。
如果回顾第 2.8.1 节 “从其它版本库取得变更”一节,我们运行hg
pull而又没有加上-u
选项时,你可能会发现它输出了一条很有用的提示,我们还需要执行一个操作,才能更新工作目录。
如果想知道工作目录的版本,可以使用hg parents命令。
$
hg parents
changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 summary: Added an extra line of output
如果回顾图 2.1 “版本库 hello
的历史图”一节,你会看到箭头连着每个变更集。箭头离开的节点是父版本,箭头指向的是子版本。工作目录的父版本也是一样的方式;它是工作目录包含的变更集。
如果需要将工作目录切换到一个特定版本,给hg update命令加上版本号或者变更集标识符就可以了。
$
hg update 2
2 files updated, 0 files merged, 0 files removed, 0 files unresolved$
hg parents
changeset: 2:fef857204a0c user: Bryan O'Sullivan <bos@serpentine.com> date: Sat Aug 16 22:05:04 2008 +0200 summary: Introduce a typo into hello.c.$
hg update
2 files updated, 0 files merged, 0 files removed, 0 files unresolved$
hg parents
changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 summary: Added an extra line of output
我们可以将变更从当前所在的版本库推到其他的版本库。与上面的hgpull例子一样,我们可以创建一个临时的版本库存放我们的变更。
$
cd ..
$
hg clone hello hello-push
updating to branch default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
hg outgoing命令可以告诉我们那些变更将会被推到另外一个版本库。
$
cd my-hello
$
hg outgoing ../hello-push
comparing with ../hello-push searching for changes changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 summary: Added an extra line of output
$
hg push ../hello-push
pushing to ../hello-push searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files
与hg pull一样,在变更推送之后,hg push命令并不会更新版本库的工作目录,与hg
pull命令不同,hg
push并不提供-u
选项来更新其他版本库的工作目录。这一不对称是有目的的:我们推送的版本库可能是一个远端的服务器,并且很多人共享使用它。如果在其他人正在工作的时候,我们更新了工作目录,那么他们的工作很可能被破坏。
如果我们向一个已经包含了这些变更的版本库推送或者拉这些变更会发生什么事情呢?,什么也不会发生。
$
hg push ../hello-push
pushing to ../hello-push searching for changes no changes found
在我们克隆版本库的时候,Mercurial会在新的版本库的.hg/hgrc
文件中记录下版本库的位置,如果我们对hg
pull没有指定来源,或者对于hg push
没有指定目标,那么这些命令就会使用缺省位置。hg incoming和hg
outgoing命令也是如此。
如果你用文本编辑器打开版本库的.hg/hgrc
文件,你会看到如下内容。
[paths] default = http://www.selenic.com/repo/hg
有可能—并且常常很有用—hg push和hg
outgoing的缺省位置与hg pull和hg
incoming的位置不同。我们可以给.hg/hgrc
文件的[paths]
节加上default-push
条目,如下所示。
[paths] default = http://www.selenic.com/repo/hg default-push = http://hg.example.com/hg
前面几节我们介绍的命令不仅可以用于本地版本库,还可以用于网络;只要传递的参数从本地路径变成URL就可以了。
$
hg outgoing http://hg.serpentine.com/tutorial/hello
comparing with http://hg.serpentine.com/tutorial/hello searching for changes changeset: 5:2e443ac19c36 tag: tip user: Bryan O'Sullivan <bos@serpentine.com> date: Thu Mar 17 03:00:29 2011 +0000 summary: Added an extra line of output
在本例中,我们可以看到准备向远程版本库推送的变更,但是该版本库并不允许匿名用户推送。
$
hg push http://hg.serpentine.com/tutorial/hello
pushing to http://hg.serpentine.com/tutorial/hello searching for changes remote: ssl required
开始一个新项目和使用一个已有项目一样简单。hg init命令可以创建一个新的,空的Mercurial版本库。
$
hg init myproject
在当前目录创建一个名为myproject
的版本库就是这么简单。
$
ls -l
total 8 -rw-r--r-- 1 oracle dba 47 Mar 17 02:59 goodbye.c -rw-r--r-- 1 oracle dba 45 Mar 17 02:59 hello.c drwxr-xr-x 3 oracle dba 72 Mar 17 02:59 myproject
我们认为myproject
是一个Mercurial版本库,
因为它包含了.hg
目录。
$
ls -al myproject
total 0 drwxr-xr-x 3 oracle dba 72 Mar 17 02:59 . drwx------ 3 oracle dba 184 Mar 17 02:59 .. drwxr-xr-x 3 oracle dba 128 Mar 17 02:59 .hg
如果想将一些已有的文件加入版本库,我们可以将它们拷贝到目录下,然后执行hg add命令,告诉Mercurial开始管理它们。
$
cd myproject
$
cp ../hello.c .
$
cp ../goodbye.c .
$
hg add
adding goodbye.c adding hello.c$
hg status
A goodbye.c A hello.c
$
hg commit -m 'Initial commit'
只需要几分钟就可以在一个新的项目上使用Mercurial,这时它的魅力之一。现在版本控制做起来非常方便,我们可以在很小的不需要复杂工具的项目上使用它。
[1] 如果版本库的源和目标都在同一个文件系统上,将会节省很多空间。这种情况下,Mercurial会使用硬链接的方式来共享内部元数据,并使用写时拷贝的机制。如果你不明白这句话的意思,没有关系:所有的事情都是自动和透明的,你不需要知道它们。