Mercurial 工作流
使用Mercurial,您可以使用多种不同的工作流。此页面显示其中几种常用工作流及其用例。它旨在使版本跟踪的初学者能够轻松地入门并逐渐深入。它没有解释所使用的概念,因为已经有许多其他很好的这方面的资源。
还提供了向个相关的学习链接:
- 快速入门 - 简单尝试。
- Mercurial教程 - 更详尽的教程。
- 理解Mercurial - Mercurial背后的概念。
- Mercurial扩展 - 增强Mercurial功能
- Mercurial权威指南(英文) - Mercurial的详细描述和内部原理,关于Mercurial设计的深入文章。
注意:
本指南不需要任何先前的版本控制系统知识(尽管SVN用户可能会很熟悉)。基于命令行更方便学习,因为我们将使用命令行客户端。基本工作流
我们从简单工作流开始逐渐过渡到更复杂的工作流。由浅入深。
日志保持
用例
第一个工作流是最简单的:使用Mercurial 查看变更记录。
此工作流程只需要安装Mercurial并对某些文件有写入访问权限。它是复杂工作流的基础。
工作流
准备Mercurial
作为第一步,应该先设置Mercurial中你的用户名。为此,使用文本编辑器打开文件〜/ .hgrc(或Windows主目录中的mercurial.ini),并将你的用户名添加ui部分:
[UI] username = Mr. Johnson <johnson@smith.com>
初始化项目
现在添加一个项目:
$ hg init project
添加文件并跟踪
输入项目文件夹(例如:project),创建一些文件,然后添加并提交。
$ cd project $ echo 'print("Hello")' > hello.py $ hg add $ hg commit (默认编辑器被打开, 输入提交消息, 保存并关闭。)output of hg add: adding hello.py display of hg commit (with your message): Initial commit. HG: Enter commit message. Lines beginning with 'HG:' are removed. HG: Leave message empty to abort commit. HG: -- HG: user: Mr. Johnson <johnson@smith.com> HG: branch 'default' HG: added hello.py
注意:
要避免切换到编辑器,还可以在命令行中直接输入提交消息:$ hg commit -m "[MESSAGE]"
然后,可以使用hg log查看初始历史记录:
$ hg logoutput of hg log: changeset: 0:a5ecbf5799c8 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:00:00 2011 +0100 summary: Initial commit.
注意:
默认情况下,Log仅显示提交消息的第一行。要显示完整的消息,请使用$ hg log -v
注意:
你还可以先进入项目目录,并在那里初始化版本库。$ cd project $ hg init
此外,你可以只添加特定文件而不是目录中的所有文件。Mercurial将只跟踪这些文件,不会知道其他文件。以下告诉mercurial跟踪名称以“file0”开头的所有文件以及file10,file11和file12。
$ hg add file0 * file10 file11 file12
保存更改
首先做一些改变:
$ echo 'print("Hello World")' > hello.py
查看哪些文件已更改,哪些文件已添加或删除,哪些文件尚未被跟踪
$ hg statusoutput of hg status: M hello.py
查看变更
$ hg diffoutput of hg diff: diff --git a/hello.py b/hello.py --- a/hello.py +++ b/hello.py @@ -1,1 +1,1 @@ -print("Hello") +print("Hello World")
提交更改
$ hg commit
现在弹出一个编辑器,并要求输入提交消息。保存并关闭编辑器后,Mercurial会保存更改。
display of hg commit (with your message): Say Hello World, not just Hello. HG: Enter commit message. Lines beginning with 'HG:' are removed. HG: Leave message empty to abort commit. HG: -- HG: user: Mr. Johnson <johnson@smith.com> HG: branch 'default' HG: changed hello.py历史现在看起来像这样:
output of hg log: changeset: 1:487d7a20ccbc user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:11:00 2011 +0100 summary: Say Hello World, not just Hello. changeset: 0:a5ecbf5799c8 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:00:00 2011 +0100 summary: Initial commit.注意:
您还可以通过hg commit -m 'MESSAGE' 直接提供提交消息。复制和移动文件
复制或移动文件时,应告诉Mercurial进行复制或移动,以便跟踪文件之间的关系。
记得在移动或复制后提交。从基本命令中,用commit创建一个新的修订版
$ hg cp hello.py copy $ hg mv hello.py target $ hg diff#查看更改 $ hg commit (输入提交消息)
现在你有两个文件,“copy”和“target”,Mercurial知道它们是如何相关的。
output of hg diff (before the commit): diff --git a/hello.py b/copy rename from hello.py rename to copy diff --git a/hello.py b/target copy from hello.py copy to target注意:
如果您忘记进行显式复制或移动,您仍然可以通过hg addremove --similarity 100告诉Mercurial检测更改。可以使用hg help addremove了解详细信息。查看历史记录
$ hg log
这将打印一个变更列表及其日期,提交者用户名及其提交消息。
output of hg log: changeset: 2:70eb0ca9d264 tag: tip user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:20:00 2011 +0100 summary: Copy and move. changeset: 1:487d7a20ccbc user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:11:00 2011 +0100 summary: Say Hello World, not just Hello. changeset: 0:a5ecbf5799c8 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:00:00 2011 +0100 summary: Initial commit.要查看某个修订版,可以使用-r开关(--revision)。要查看显示修订版的差异,还有-p开关( - 补丁)
$ hg log -p -r 3
独立开发者与非线性历史记录
用例
第二个工作流仍然非常简单:假设你是一个独立开发者,并且您希望使用Mercurial来跟踪更变并优化您的工作流。
它的工作方式与日志保持工作流类似,不同之处在于您可以回溯到之前的更改并从那里继续工作。
要开始一个新项目,需要初始化版本库,添加文件并在完成部分工作时提交。
你也可以随时检查历史记录,回顾工作过程。
工作流程
记录日志的基础知识
初始化您的项目,添加文件,查看更改并提交它们。
$ hg init project $ cd project $(添加文件) $ hg add#告诉 Mercurial跟踪所有文件 $(做一些改变) $ hg diff#查看更改 $ hg commit#提交变更 $ hg cp#复制文件或文件夹 $ hg mv#移动文件或文件夹 $ hg log#查看历史记录
查看早期的修订版
与日志保持工作流不同,您有时需要返回历史记录并直接在那里进行一些更改,例如因为早期的更改引入了一个错误,并且您希望在发生错误的地方修复它。
要查看以前版本的代码,可以使用update。我们假设要查看修订版1。
$ hg update 1
现在代码回到修订版1,第二次提交(Mercurial从0开始计数)。要检查是否有该修订版本,可以使用identify -n。
$ hg identify -noutput of hg identify -n: 1 output of ls: hello.py
注意:
不带选项的identify为你提供唯一修订ID的简短形式。该ID是Mercurial内部使用的ID。如果您告诉某人您更新的版本,您应该使用该ID,因为其他人的数字可能不同。 如果您想了解背后的原理,请阅读理解Mercurial。当你处于最新版本时,hg identify n将返回“-1”。要更新到最新版本,可以使用“tip”作为修订名称。
$ hg update tip
注意:
如果有命令显示建议,最好的选择遵循这个建议。注意:
hg update,你也可以使用缩写hg up。类似地,您可以将hg commit 缩写为hg ci。注意:
要获得文件的最初状态,只需通过hg update null 更新为“null” 。这是在添加任何文件之前的修订版。注意:
如果hg identify 的输出以“+”结尾,则您的版本库具有未提交的更改。修复早期版本中的错误
当你在某些早期版本中发现错误时,你有两个选择:可以在当前代码中修复它,或者返回历史记录并将代码准确地恢复到提交前的位置,从而创建更清晰的历史记录。
更清析的方式是,首先更新到旧版本,修复错误并提交。然后合并此修订,再提交合并。你不用担心:mercurial的合并是快速而无害的,就像你马上就会看到的那样。
我们假设该错误是在修订版1中引入的。
$ hg update 1 $ echo 'print(“Hello Mercurial”)'> hello.py $ hg commitoutput of hg commit (after entering the message): created new head
注意:
“created new head”意味着现在还有一个修订版,它没有子版本。head与项目当前状态并存。在传播之前将它们合并在一起是很好的风格。现在修复过的文件已存储在历史记录中。我们只需要将其与当前版本的代码合并即可。
$ hg mergeoutput of hg merge (here): merging hello.py and copy to copy merging hello.py and target to target
如果存在冲突,请使用hg resolve - 这也是发生冲突时必须要做的事情。
首先列出有冲突的文件
$ hg resolve --list
然后一个一个地解决它们。resolve再次尝试合并
$ hg resolve conflicting_file (必要时手工修理)
注意:
有关解决冲突的更多详细信息,请参阅Mercurial教程: 解决冲突部分。将已修复的文件标记为已解决
$ hg resolve --mark conflicting_file
解决所有冲突后立即提交合并。即便没有冲突时,也要提交!
$ hg commit
此时,修复过的文件将与所有其他的工作合并,你可以继续编码。此外,历史记录清楚地显示了修复错误的位置,因此您始终可以检查错误的位置。
output of hg log (after the final commit): changeset: 4:3b06bba7c1a9 tag: tip parent: 3:7ff5cd572d80 parent: 2:70eb0ca9d264 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 20:11:00 2011 +0100 summary: merge greeting and copy+move. changeset: 3:7ff5cd572d80 parent: 1:487d7a20ccbc user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 20:00:00 2011 +0100 summary: Greet Mercurial changeset: 2:70eb0ca9d264 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:20:00 2011 +0100 summary: Copy and move. changeset: 1:487d7a20ccbc user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:11:00 2011 +0100 summary: Say Hello World, not just Hello. changeset: 0:a5ecbf5799c8 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 11:00:00 2011 +0100 summary: Initial commit.注意:
大多数合并都会成功。当合并冲突时,你只需要解决冲突(resolve)。因此,现在你可以通过提交早期的变更集,并将更改合并到当前代码中来初始化版本库,保存更改,更新以前的更改并在非线性历史记录中进行开发。
注意:
如果修复了早期版本中的错误,并且某些更高版本复制或移动了该文件,则修复将在合并时传播到目标文件。这是你应该总是使用hg cp和hg mv的主要原因。分离功能
用例
有时您将并行开发多个功能。如果要避免混合不完整的代码版本,可以创建本地版本库的克隆,并在其自己的代码目录中开发每个功能。
完成功能后,将其拉回主目录并合并更改。
工作流
在不同的副本中工作
首先创建一份功能副本, 并进行一些更改
$ hg clone project feature1 $ cd feature1 $ hg update 3 $ echo'print("Hello feature1")'> hello.py $ hg commit -m "Greet feature1"
现在检查从feature1 pull时会发生什么,就像在提交之前可以使用diff一样。用于拉动的相应命令是incoming
$ cd ../project $ hg incoming ../feature1output of hg incoming ../feature1: comparing with ../feature1 searching for changes changeset: 5:3eb7b39fcf57 tag: tip parent: 3:7ff5cd572d80 user: Arne Babenhauserheide <bab@draketo.de> date: Sun Nov 20 20:11:11 2011 +0100 summary: Greet feature1
注意:
如果你想看到的差异,你可以使用hg incoming --patch就像你可以用hg log --patch对资源库中的变化。如果你想要这些更改,可以拉取到项目中
$ hg pull ../feature1
现在,项目中已经有feature1的历史记录,但工作目录中还不可见。因为它只存储在项目的“.hg”目录中。
output of hg pull: pulling from ../feature1 searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge)注意:
从现在开始,我们所说的"版本库"是指项目中的.hg目录。如果你没有对项目进行任何更改,那么当你使用feature1时,你可以更新到最新(hg update tip),如果你还需要做一些其他更改。需要先合并。
将feature1合并到项目代码中
$ hg merge
如果存在冲突,请使用hg resolve - 必须先解决冲突。之后,你必须明确的提交,来完成合并
$ hg commit (输入提交消息,例如“merged feature1”)output of hg log -r -1:-3 (the last 3 changesets): changeset: 6:e8a33691171a tag: tip parent: 4:3b06bba7c1a9 parent: 5:3eb7b39fcf57 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 20:20:00 2011 +0100 summary: merged feature1 changeset: 5:3eb7b39fcf57 parent: 3:7ff5cd572d80 user: Arne Babenhauserheide <bab@draketo.de> date: Sun Nov 20 20:11:11 2011 +0100 summary: Greet feature1 changeset: 4:3b06bba7c1a9 parent: 3:7ff5cd572d80 parent: 2:70eb0ca9d264 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 20:11:00 2011 +0100 summary: merge greeting and copy+move.
注意:
Mercurial提供了有效的方式指定修订版。请使用hg help revsets 查看详情。你可以创建任意数量的克隆,还可以是在U盘中。你还可以使用它们在家中和工作中,或在桌面和笔记本电脑之间同步文件。
注意:
在没有冲突的情况下,也必须在合并后提交,因为合并会创建新的历史记录,并且你可能希望将特定的消息附加到合并(例如“merge feature1”)。注意:
如果您需要空文件夹,请在这些文件夹中创建一个占位文件并添加该文件到版本库。回滚错误
现在你可以并行开发不同的功能,但不时会有一个错误的提交隐藏起来。当然,你可以回到过去一个版本并合并排除错误,将所有错误都排除在合并版本之外。但是,如果你在执行另一次commit或pull之前意识到错误,则有一种更简单的方法:rollback。
回滚意味着撤消上次操作,这会给历史记录添加一些内容。
想象一下,你刚刚意识到你做了一个错误的提交 - 例如你没有在提交消息中看到拼写错误。要修复它你会使用
$ hg rollbackoutput of hg rollback: repository tip rolled back to revision 5 (undo commit) working directory now based on revisions 4 and 5
然后重做提交
$ hg commit -m "Merged Feature 1"output of hg log -r -1:-2 (after rollback and commit): changeset: 6:3f549b33c7ef tag: tip parent: 4:3b06bba7c1a9 parent: 5:3eb7b39fcf57 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 20:20:11 2011 +1100 summary: Merged Feature 1 changeset: 5:3eb7b39fcf57 parent: 3:7ff5cd572d80 user: Arne Babenhauserheide <bab@draketo.de> date: Sun Nov 20 20:11:11 2011 +0100 summary: Greet feature1
如果你可以使用shell的命令历史记录并且通过commit -m “message”添加了上一条消息,那么以下提交只意味着两次单击箭头键“up”并单击“enter”。
虽然它会更改您的历史记录,但回滚不会更改您的文件。它只会撤消您历史记录的最后一次添加。
但请注意,回滚本身无法撤消。如果你回滚然后忘记提交。您必须创建一个新的提交。
注意:
可以回滚,因为Mercurial在记录更改时使用事务,您可以使用事务记录来撤消上一个事务。这意味着如果您还没有提交任何新内容,也可以使用rollback撤消上次拉取。分享变更
用例
现在我们更进一步:假设你不再是一个人独立开发,你希望与他人分享你的变更并包含其它人的变更。
对此的基本要求是你必须能够看到其他人的变更。
Mercurial允许你通过包含一个简单的Web服务器来轻松实现,你可以从中拉取变更,就像从本地克隆中提取变更一样。
注意:
不过,还有其他一些方法可以分享变更。除了使用内置Web服务器,你也可以通过电子邮件发送或设置更改的共享资源库,到了那里推送你的变更,而不是拉动它们。我们稍后会介绍其中一个。工作流程
使用内置的网络服务器
这是快速共享变更的最简单方法。
首先,想要分享其变更的人创建了Web服务器
$ hg serve
现在所有其他人都可以将他们的浏览器指向他在端口8000的IP地址(例如192.168.178.100)。然后他们将在那里查看他的所有历史记录,并可以决定是否要拉取他的更改。
$ firefox http://192.168.178.100:8000
如果他们决定包含更改,则只需从上面的URL中拉取
$ hg pull http://192.168.178.100:8000
此时,你可以像从本地版本库中取出一样工作。所有数据现在都在你的各个版本库中,你可以合并更改并使用它们,而无需与服务器版本库建立任何连接。
通过电子邮件发送更改
通常,你无法直接访问其他人的版本库。可能你还希望保密你的更改并更喜欢用内部电子邮件(如果你需要其他保护,你也可以加密电子邮件,例如使用GnuPG)。
在这种情况下,您可以轻松地将更改导出为补丁并通过电子邮件发送。
通过电子邮件发送它们的另一个原因可能是,当其他开发人员习惯于阅读电子邮件中的差异时,你需要手动审查更改。
通过Mercurial,通过电子邮件发送更改非常简单。您只需导出(export)变更并在电子邮件中附加(或复制粘贴)。然后你的同事可以导入(import)。
首先检查要导出的变更
$ cd project $ hg log
我们假设你要导出变更集3和4
$ hg export 3> change3.diff $ hg export 4> change4.diff
现在将它们附加到电子邮件中,你的同事可以在两个差异上运行import以获取完整变更,包括你的用户信息。
要小心,他们首先clone他们的版本库以将integration目录作为沙箱
$ hg clone project integration $ cd ingteration $ hg import change3.diff $ hg import change4.diff
OK。他们现在可以克隆你的变更并测试。如果他们接受了,他们会将变更拉取到主版本库中
$ cd ../project $ hg pull ../integration
注意:
patchbomb扩展可以自动发送电子邮件,但这个工作流中并不是必须的。注意:
您还可以发送捆绑包,这些捆绑包是您实际历史记录的片段。只需通过创建它们$ hg bundle --base FIRST_REVISION_TO_BUNDLE changes.bundle其他人可以通过简单地拉动它们来获取变更,就好像是实际的版本库一样
$ hg pull path / to / changes.bundle
使用共享版本库
当你还不是普通开发团队的成员时,通过电子邮件发送更改可能是最简单的方法,但它会产生额外的工作:你必须打包(bundle)变更,发送邮件,然后手动导入(import)捆绑包。幸运的是,有一种更简单的方法可以很好地运行:共享推送版本库。
到目前为止,我们通过电子邮件或拉取(pull)传输所有变更。现在我们使用另一种选择:推送(push)。顾名思义,这与拉取相反:您将变更推送(push)到另一个版本库。
但要使用它,我们首先需要有可以推动的目标。
为了安全,默认情况下,hg serve不允许推送。你可以设置为允许推送,但是当你居住在不同的时区时,这不是好的解决方案,因此我们将采用另一种方法:使用线上服务器或BitBucket等服务上使用共享版本库。这样做会有更高的起始成本,需要更长的时间来解释,但这是值得花费的努力。
如果要使用线上服务器,可以在那里使用服务并允许推送。 还有一些其他很好的方法可以推送到Mercurial版本库, 包括通过SSH进行简单访问。
否则,您首先需要设置BitBucket帐户。只需在BitBucket注册。 注册(sign up)(并登录(login))后,将鼠标悬停在“版本库(Repository)”上。单击打开对话框底部的项目,显示“新建”。
输入名字和描述。如果你不相公开版本库,请选择“私有(Private)”
$ firefox http://bitbucket.org
现在你的版本库已创建,你将看到有关推送(push)它的说明。为此,您将使用类似于以下命令(仅使用不同的URL):
$ hg push https://bitbucket.org/ArneBab/hello/
(将URL替换为您创建的版本库的URL。如果你的用户名是“Foo”,并且您的版本库名为“bar”,则URL将为https://bitbucket.org/Foo/bar/)
Mercurial将询问你在BitBucket用户名和密码,然后推送(push)你的代码。
”小明,你的代码已经在线。“
要查看推送时会得到什么,您可以使用传出(outgoing)。它与本地版本库的工作方式与共享版本库相同,因此您可以使用本地版本库进行测试:
$ hg outgoing ../feature1output of hg outgoing ../feature1 (our feature seperation repo): comparing with ../feature1 searching for changes changeset: 6:3f549b33c7ef tag: tip parent: 4:3b06bba7c1a9 parent: 5:3eb7b39fcf57 user: Mr. Johnson <johnson@smith.com> date: Sun Nov 20 20:20:11 2011 +1100 summary: Merged Feature 1
注意:
你也可以使用SSH推送到BitBucket。现在是时候告诉所有同事注册BitBucket了。
之后,你可以单击版本库的“管理员(Admin)”选项卡,并在“权限(Permission):编辑人员(Writers)”下的右侧添加同事的用户名。现在允许他们将代码推送(push)到版本库。
(如果您选择将版本库设为私有,则还需要将它们添加到“权限(Permission):读者(Readers)”中)
如果你们其中一个人现在想要发布变更,他只需将它们推送(push)到版本库,其他所有人都可以通过拉取(pull)来获取它们。
发布的变更
$ hg push https://bitbucket.org/ArneBab/hello/
将其他变更拉入本地版本库
$ hg pull https://bitbucket.org/ArneBab/hello/
开发人员也可以只是克隆(clone)这个版本库,就像你们其中一个人正在使用hg服务一样
$ hg clone https://bitbucket.org/ArneBab/hello/ hello
该本地版本库将自动配置到远程库的关联,因此新贡献者只需使用hg push和hg pull而无需URL。
注意:
为了使这个工作流程更具可伸缩性,你们每个人都可以拥有自己的BitBucket版本库,只需从其他版本库中拉取(pull)即可。通过这种方式,可以轻松地建立工作流,其中有的人负责集成,最后将检查的代码推送(push)到共享拉版本库,其他所有人都可以从中获取。注意:
可以通过SSH或共享目录将此工作流用于共享服务器而不是BitBucket。使用Mercurial的SSH URL的示例是ssh://user@example.com/path/to/repo。使用共享目录时,只需按下共享目录中的版本库位于本地驱动器上即可。摘要
现在让我们退后一步,看看我们在哪里。
使用你已经知道的命令,稍微阅读一下hg help
。你几乎可以完全掌控你的源代码历史记录了。
意味着你现在可以使用更复杂的工作流。
其次它让你更专注于你的任务,而不是专注于你的工具。它可以帮助您专注于编码本身。
如果你还记得命令的含义,你可以做的简短摘要和检查。
创建一个项目
$ hg init project $ cd项目 $(添加一些文件) $ hg add $ hg commit (输入提交消息)
非线性历史记录开发
$(做一些改变) $ hg commit (输入提交消息) $ hg update 0 $(做一些改变) $ hg commit (输入提交消息) $ hg merge $(可选hg解析) $ hg commit (输入提交消息)
使用功能副本
$ cd .. $ hg clone project feature1 $ cd feature1 $(做一些改变) $ hg commit (输入提交消息) $ cd ../project $ hg pull ../feature1
通过集成的Web服务器共享版本库
$ hg serve & $ cd .. $ hg clone http://127.0.0.1:8000 project-clone
导出对文件的变更
$ cd project-clone $(做一些改变) $ hg commit (输入提交消息) $ hg export tip> ../changes.diff
从文件导入更改
$ cd ../project $ hg import ../changes.diff
从服务器版本库中拉取(pull)变更
$ cd ../feature1 $ hg pull http://127.0.0.1:8000
在BitBucket上使用共享版本库
$(设置bitbucket repo) $ hg push https://bitbucket.org/USER/REPO (在提示中输入名称和密码) $ hg pull https://bitbucket.org/USER/REPO
让我们继续实现有用的功能和更高级的工作流程。
高级工作流
退出不良修订版
用例
当你经常从其他人那里提取代码时,您可能会忽略一些不好的变更。一旦其他人从你那里获得了这一改更,你几乎没有机会彻底摆脱。
为解决任何真正分布式系统中的基本问题,Mercurial为您提供了退出(backout)命令,告诉Mercurial 创建一个可以撤销的不良提交。这样你就不必摆脱坏代码历史记录,但是你可以从新版本中删除。
注意:
基本命令不会重写历史记录。如果你想这样做,你需要激活mercurial附带的一些扩展。之后会讲到。工作流
让我们假设不好的变更是版本3,并且版本库中已经有一个更新版本。要删除不良代码,您只需退出(backout)即可。这生成一个新的变更,扭转了不良变更。退出后,您可以将新更改合并到当前代码中。
$ hg backout 3 $ hg merge (可能解决冲突) $ hg commit (输入提交消息。例如:"merged backout")
OK,你扭转了不良变更。但历史记录依然有记录(遵循“非必要,不重写历史”的原则),但它不再影响未来的代码。
协作功能开发
现在可以共享变更并在必要时撤消它们,继续深入,使用Mercurial进行协调开发。
第一部分是一种简单的方式,可以一起开发功能,而无需每个开发人员跟踪多个功能副本。
用例
如果要将开发拆分为多个功能,则需要跟踪谁在哪个功能上工作以及在哪里获得哪些更改。
Mercurial通过提供命名分支可轻松实现。它们是主版本库的一部分,因此可供所有相关人员使用。同时,在某个分支上提交的更改不会与默认分支中的更改混合在一起,因此功能将保持独立,直到它们合并到默认分支中。
注意:
克隆版本库总是首先将您置于默认分支。工作流程
当团队中的某个人想要开始编写某个功能而不会打扰其他功能时,他可以创建一个命名分支并在那里提交。当其他人想要加入时,他只是更新分支并提交。功能完成后,有人会将指定分支合并到默认分支中。
注意:
命名分支信息将永久存储在历史记录中,因此您始终可以查看添加了哪些更改的功能。如果您只想将临时分支作为历史记录上的短期标记,则可以使用“书签”。只需用hg bookmark 替换hg branch 并添加参数 -B bookmark_name 到hg push和hg pull。在命名分支中工作
创建分支
$ hg branch feature1 (做一些改变) $ hg commit (写提交消息)
更新到分支并在其中工作
$ hg update feature1 (做一些改变) $ hg commit (写提交消息)
现在,您可以提交(commit),拉取(pull),推送(push)和合并(merge)(以及其他任何内容),就像在单独的版本库中工作一样。如果命名分支的历史是线性的并且你调用“hg merge”,Mercurial会要求明确的提供修订版,因为工作的分支没有任何要合并的内容。
合并分支
完成该功能后,将分支合并回默认分支。
$ hg update default $ hg merge feature1 $ hg commit (写提交消息)
使用hg branches查看活动分支。要将分支标记为非活动状态,例如因为您已完成功能的实现,可以将其关闭。已关闭的分支隐藏在hg branches和hg heads。
$ hg update feature1 $ hg commit --close-branch -m "finished feature1"
这样现在可以轻松地将功能分开。
标记修订版
用例
现在你可以更轻松地编写单独的功能,因此你可能希望将某些修订版标记为适合使用(或类似)。例如你可能希望标记版本,或者只是将修订标记为已审核。
对于这个Mercurial提供的标签功能。标签为修订版添加名称,并且是历史记录的一部分。您可以在提交后的几年内标记更改。标签包含添加时的信息,标签可以像任何其他提交的更改一样被拉取,推送和合并。
注意:
标签不能包含char“:”,因为该char用于指定多个修订版 - 请参阅“hg help revisions”。注意:
要安全地标记修订版,您可以使用gpg扩展对标记进行签名。工作流程
我们假设你想将版本3命名为“v0.1”。
添加标签
$ hg tag -r 3 v0.1
查看所有标签
$ hg tags
当你查看日志时,您现在会在变更集3中看到有标签的行。如果有人想要更新到标签的修订版,他可以使用您的标记名称
$ hg update v0.1
现在他将处于标记版本,可以从那里开始工作。
删除历史记录
用例
有时你将在版本库中进行更改,而你实际上你并不需要对其进行更改。
有许多高级选项可以删除它们,其中大多数都使用了很棒的扩展(Mercurial Queues是最常用的扩展),但在这个基本指南中,我们只用我们已经学过的命令来解决问题。但是我们会使用一个选项来克隆我们还不需要的东西。
当您需要删除隐藏在许多新变更下的变更时,此工作流程会变得不方便。如果你足够早地发现它们,你可以毫不费力地摆脱不良的修订版。
工作流程
假设您想要删除修订版2,最高版本为3。
第一步是使用“--rev”选项进行克隆(clone):创建一个仅包含指定修订版本更改的克隆。由于您希望保留修订版1,因此你只用克隆修订版1
$ hg clone -r 1 project stripped
现在,你可以从原始库中导出(export)变更集3 ,然后导入(import)到当前被剥离的项目中
$ cd project $ hg export 3> ../changes.diff $ cd ../stripped $ hg import ../changes.diff
如果无法应用部分更改,你将在* .rej文件中看到该部分。如果你有* .rej文件,则必须手动包含或放弃更改
$ cat * .rej (手动应用更改) $ hg commit (写提交消息)
hg export还包括提交消息,日期,提交者和类似的元数据,到此就算完成了。
注意:
删除历史记录将会改变修订版ID,再次拉取(pull)仍然会拉取到被删除的版本。这就是为什么重写历史只能是尚未公布的版本。摘要
因此,现在您可以私下使用Mercurial,并以多种方式分享你的更改。
此外,你可以通过在版本库中创建一个可以撤销原始更改的更改,或者通过真正重写历史记录来删除不良更改,因此看起来似乎从未发生过更改。
您可以使用命名分支将单个版本库中的功能工作分开,并将标记添加到修订版本,这些修订版本是其他人的可见标记,可用于更新到标记的修订版本。
有了这个,我们可以得出我们的实用指南。