hg常用命令

时间:2022-04-04 05:56:17

关于hg命令选项

如果你是在windows系统下,使用的是图像界面,你很可能不常用它。但是一旦你了解这些命令之后,会觉得很方便。hg有很多命令,这些命令都有一定的选项,在开始的时候,只知道用它,有时候命令选项以”–”开头,有时又以”-”开头。翻阅资料,发现对于命令选项,hg有以下的约定。

  1. 每一个命令选项都有一个长的名称,如hg log 命令会使用 –rev选项;
  2. 大多数选项拥有一个短的名称,如—rev有一个-r的短名;
  3. 长名称以两条横线(–)作为起始,短名起始是一条横线(-)。如—rev、-r;
  4. 无论是长名还是短名,其用途是一致的。如-r和—rev 其后都跟一个变更集合的ID或版本号;
  5. 如果使用的是短名,多个名称可以连在一起运行。如hg log –v –r –p 2可以写作hg log –vpr 2。

关于hg log命令

使用该命令可以了解代码仓库变更的历史,其输出的结果中包含以下几个字段:

hg常用命令

  1. changeset 该字段被一个分号(:)分成两部分,分号的前面是一个数字,其后是一个十六进制的字符串。在查看版本历史的时候,常常会用到前面得数字。这里需要注意的是,该数字所代表的变更集合不是唯一的(比如a,b,c在一个代码仓库中的顺序是0,1,2,在另外一个代码仓库中可能是0,2,1)。真正指向唯一的变更集合的是后面的十六进制的字符串。
  2. user 代表集合的创建者;
  3. date 代表集合创建的时间;
  4. summary 创建者提供的关于该集合的描述文本;
  5. tag 有一些集合会包含一个tag字段,这个特别的字段总是指向代码仓库中最新的版本。

明白以上字段的含义,对于你查看版本历史和提交代码时书写描述性文本很有意义。在后面的章节中,甚至可以根据这些字段改变其输出的格式。

要查看特定的版本,在hg log 后跟上版本号即可,如:

1.//查看特定的版本;
2.hg log -r 2

同时查看几个版本,可以使用如下的命令:

1.//查看版本2,3,4
2.Hg log -r 2:4

如果要查看版本的详细内容,包括文件发生改变的内容,可以添加-p(–patch)命令选项。

1.//查看版本的详细内容
2.hg -log -vpr 1

下图是使用该命令后的输出结果:

hg常用命令

使用hg commit 提交代码的需要注意的问题

第一次使用hg commit命令提交代码时,很可能会出现代码无法提交的问题。这是因为在代码提交时hg会尝试去找到一个有效的用户名。它会按下面的顺序去逐个尝试寻找有效的用户名:

  1. 如果在使用hg conmit提交代码时,使用-u命令选项,并在其后跟上一个用户名(如:dexibe@gmail.com)。此时,该命令将具有最高的优先权;
  2. 如果没有第一步的命令选项,它会查看你是否设置了HGUSER环境变量;
  3. 如果在你的home目录下,你创建了.hgrc文件,并且该文件设置了username,它会启用该用户名;
  4. 到这一步,它会查看你的email环境变量;
  5. 如果以上都没有找到合适的用户信息,hg 将查看你的系统寻找用户名和主机名称,并试图根据这些组件构建有效的用户名,通常情况下用户名是不可用的,只会呈现一段警示语句;

下图是没有设置用户名提交代码时的输出结果:

hg常用命令

拉取和推送代码

拉取代码,使用hg pull即可,有一个hg incoming命令我很少用到,仔细看了看,这个命令还是很管用。hg incoming命令不会真正的拉取代码到本地仓库,它只是告诉你使用hg pull会将哪些变更集合拉至本地仓库。这对于你拉取特定的版本集合很管用。

推送代码,使用hg push即可。在真正推送之前,可以使用hg outgoing查看有哪些改变将会被推送至代码仓库。

在项目推进的过程中,经常会出现两个人共同修改一个文件的情况。这个时候,我们就要进行代码合并。使用hg合并代码非常简单。Hg记录每一次变更集合的父级,如果变更集合一个父级,一个head就是一个没有子级的集合。当多人修改同一个文件时,就会出现不止一个head的情况,此时需要进行代码合并。

如果一个文件同时被几个人修改,hg pull命令会告知你”heads”的情况。此时如果使用hg update命令,会出现以下的提示语:abort: crosses branches (use ‘hg merge’ or ‘hg update -C’)

如果要强制更新,可以使用hg update –C。要查看heads可以使用hg heads命令,该命令会告知你head的情况,使用hg merge就会完成两个head之间的代码合并。此时使用hg parents命令会看到父级的情况。在完成代码合并之后,一定不要忘记使用hg commit命令提交更改的代码。

大多数情况下,代码合并都很简单。但是,如果多个人修改文件的同一个地方,情况就有所不同了。除非修改的内容一样,否则会导致冲突发生。Hg不能很好的处理这些冲突,但是它能运行外部程序来处理这些冲突,如kdiff3。这种合并就是所谓的“三路合并”(three-way merge)。此时,窗口会被分成三部分:

  1. 左边是文件的的基础版本;
  2. 中间是你自己的版本,文件包括被修改的内容;
  3. 右侧是你将要与之合并的版本。

你可以在三个窗口之间来回切换,修改文件的冲突部分,将其更改为我们需要的部分。一旦完成文件合并,一定要记住提交合并之后的代码。Hg本身不能处理有冲突的变更集合,它会在存在冲突文件上留下一个标记,告知用户该文件存在冲突。

仔细回忆一下,从代码仓库中拉取代码(hg pull)后,更新(hg update)本地仓库,进行代码合并(hg merge),提交(hg commit)合并的代码。在hg中有一个命令可以完成前三步操作,它就是fetch。要启用它,只需在.hgrc中的[extensions] 设置fetch = 即可,这是个标准的扩展,hg知道在何处去查找这个扩展,使用hg help extensions命令,你可以看到关于fetch的描述: pull ,update and merge one command。启用成功之后,使用hg fetch试试。

前面的两节简要地记录了使用hg命令的一些注意事项,并提到了文件merge的一些知识,这一节将回顾使用hg来添加、删除、复制文件的一些操作。

一、如何让HG跟踪你的文件

hg不会自动的管理你仓库中文件,hg status命令会告诉你那些它不知道的文件,它会在这些文件的前面打上一个“?”号。假如在你的仓库中有一个myfile.txt的文件,执行hg status你会看到:

hg常用命令

在myfile.txt前面,我们会看到一个“?”号。如要让hg管理该文件,执行如下命令:

1.hg add myfile.txt

此时运行hg st,你会看到:

hg常用命令

文件myfile.txt前面的“?”号变成了“A”。执行hg commit命令之后,myfile.txt就不会再出现在hg status的输出结果之中。hg status命令的输出结果中仅包含删除的(removed)、被修改的(modified)、重命名的(renamed)文件。添加一个文件,hg什么也不会做,它只是在执行下一次提交(hg commit)之前对该文件“拍一张快照”。

在将文件添加到代码仓库中,需注意一下几点:

  1. 如果使用hg add后跟的是一个目录,该命令会将该目录下的所有文件添加到仓库之中,包括子目录中的文件。假如有一个目录b,其下有一个文件some.txt和d目录,d目录之下有一个文件c.txt。运行hg add b,你会看到:

    hg常用命令

  2. hg并不追踪文件夹信息,而是追踪文件的路径。在创建一个文件之前,首先创建文件所在的路径。删除一个文件后,它会删除文件所在路径的所有空的文件夹。一般情况下,很少用到空文件夹。如果在你的代码仓库中需要空文件夹,可以通过hg add来添加一个隐藏的文件。在linux系统中,任何以“.”开头的文件都被视作隐藏文件。除此之外,你可以在需要它之前通过自动化执行脚本方式创建空文件夹。

二、如何停止文件跟踪

如果你决定不让代码仓库跟踪你的文件,使用hg remove命令即可。文件删除之后,运行hg status后的输出结果中,被删除的文件之前会打上“R”标识符。假如我移除我仓库中的myfile.txt文件,你会看到:

hg常用命令

使用hg remove删除一个文件后,hg将停止追踪该文件的任何改变。即使你重新创建一个与之同名的文件, hg也会无动于衷。假设你重新创建一个与之同名的文件,运行hg add命令让hg跟踪它。hg会认为新添加的文件与先前的同名文件毫无关联。

删除一个文件并不会对该文件的历史带来任何影响。它仅仅从当前工作目录中移除文件的当前版本,并在下一次代码提交的时候让hg停止对该文件的追踪。

如果你不是使用hg remove来删除一个文件,hg会认为文件丢失。它会在丢失的文件之前打上“!”标识符。假设我手动删除工作目录下的myfile.txt,然后运行hg status命令,你会看到如下结果:

hg常用命令

假设你的本意是将该文件删除,你可以在任何时候运行hg remove –after命令来真正的删除该文件。紧跟上面的例子,执行该命令会看到如下结果:

hg常用命令

可以看到,myfile.txt前面打上了“R”标识符。

如果意外的删除了丢失的文件,可以使用hg revert命令将其恢复。还是紧跟上面的例子,运行该命令,你会看到:

hg常用命令

你可能认为文件添加和删除操作相当繁琐。令人兴奋的是,hg有一些快捷方式可以一次完成文件的添加和删除文件操作。

  1. 使用hg addremove命令;
  2. 在提交代码时使用-A参数,即hg commint -A -m “提交代码”。

三、复制文件

hg提供了hg copy命令来复制一个文件。用该命令来复制文件,hg会记住新的的文件是源文件的副本。在你合并代码的时候,它会对其作特殊的处理。下图是使用hg copy复制文件后的截图:

hg常用命令

从图中可以看到,hg status -C 可以看到myfile-copy.txt是从myfile.txt复制而来。复制的文件在代码合并的时候会发生什么呢?以下是在在两个工作目录中复制文件,并在一个仓库中修改文件时的截图。

hg常用命令

查看myfile-copy.txt,你会看到,对myfile.txt所作的修改同步到了myfile-copy.txt。这看上去有些怪异,但是其结果却相当尽如人意。可以想见,如果hg不将其同步到文件副本,那么该副本就会保持原来的版本不变。当然,你也可以手动去修改副本文件。这里需要注意的是,这种信息直播仅发生在以下几种情况:

  1. 代码合并的时;
  2. 你的代码仓库中还没有该文件的副本时。

如果说这种文件复制所导致的信息直播并不是你所需要的结果,你可以使用系统正常的文件复制操作。比如使用unix中的cp命令,然后用hg add命令将其添加至代码仓库。

如果你修改一个文件,但是在没有提交代码的情况下复制该文件,那么在该副本文件中仍将包含文件被修改的部分。

hg copy命令与unix系统中的cp命令极其相似,只需要提供两个或三个以上的参数即可,最后的一个参数被视作目的地,其它都被视作复制源。这种操作包括以下几种情况:

  1. 目的地不存在,源文件为单个文件,将创建同名的新文件;如:
    1.hg copy a k//目录k不存在,重建k目录,并将a复制到k文件夹之下
  2. 目的地是一个目录,将源文件复制到该目录之下;如:
    1.hg copy a b d// 将a 和b 复制到d目录之下
  3. 复制源跟目的地都是目录,则将复制源复制到目标文件夹之下,并在目标文件夹之下根据复制源目录的名称重建目录,且保持复制源的目录树结构;如:
    1.hg copy z d //假设z的目录树结构为z/a/c,复制到目录d后,d的目录树结构为d/z/a/c
  4. 复制源是一个目录,目的地不存在,则创建新的目录,并将复制源下的目录树复制到新的目录之下;如:
    1.hg copy z e//假设z的目录结构为z/a/c,复制完成后e的目录结构为e/a/c

与hg remove命令一样,如果你手动复制一个文件,并让hg能跟踪此文件,可以使用hg copy –after [源文件] [目标文件],如:

1.cp  a b
2.hg copy --after a b

四、文件重命名

与文件复制操作相比,文件重命名操作更为常见。在hg代码管理中,文件重命名操作在本质上等同于文件复制操作。因此,理解了文件的复制操作,文件重命名操作就不是太难。

使用hg rename进行重命名操作时,hg先对文件进行复制操作,然后删除该文件,并标注该文件已经删除。如:

hg常用命令

从图中可以看到,重命名的newfile.txt前面打上了“A”标识符,源文件myfile.txt前面打上了“R”标识符。运行hg status -C你会看到如下的结果:

hg常用命令

同样,如果你手动重命名一个文件,你也可以使用–after选项来让hg追踪你重命名的文件。在 unix系统中,可以使用hg mv命令来重命名一个文件。以下是在windows系统中操作的截图:

hg常用命令

既然重命名操作与复制操作相似,那么在代码合并时对被重命名文件所作的操作将会同步至被重命名后的文件。比如,当你对一个文件进行修改,而你的同伴对该文件进行了重命名操作。在代码合并的时候,你所做的修改将被同步到被重命名的文件之中。

对文件进行重命名操作时,会遇到以下两种情况:

  1. 同一个文件被重命名为不同的名称。在这种情况下,进行代码合并的时候,hg会发出警告,提示用户该文件存在不同的文件名,让用户去决定选择哪一个文件名;
  2. 不同的文件被命名为相同的文件名。在这种情况下,hg会按正常合并程序来合并代码,让用户去选择合适的方案
  3. 在你的代码仓库中的有一个目录文件,它的名称与另外一个代码仓库中的文件名相同。这种情况下进行代码合并时,合并将会终止,这是Mercurial 遗留下来的一个bug。详情可以查看http://mercurial.selenic.com/bts/issue29。

五、如何处理较为复杂的代码合并

一般来说,合并代码是一件很简单的事情。不过有些时候代码合并也不是那么顺利。假如一个项目中有一个较大的文件同时被几个人编辑,冲突就很容易出现,运行hg heads命令就会看到两个或多个head的情况,此时就需要分别与每一个head进行合并,并提交代码,直至看到一个head为止。如果代码合并没有完成,hg将会阻止代码提交。

如果合并代码后提交代码失败,可以使用hg resolve命令。进行代码合并后,如果 hg发现文件为unresolved 状态,则认为代码合并失败。hg resolve –list或hg resolve -l会输出每一个合并文件的状态,如果文件前面有一个标识符“U”,则认为合并不成功,提交代码就会失败。对于hg resolve,有以下几个常见的选项:

  1. –all或-a,尝试去合并所有unresolved 状态的文件;
  2. –mark或-m,直接将文件修改为resolved 状态;
  3. –unmask或-u,直接将文件修改为unresolved 状态。

六、关于hg diff

hg diff有一个选项–Git或者-g,该选项我们很少用到。假如你修改了一个文件的权限,运行hg status会看到文件被修改,而运行hg diff将看不到任何输出结果。如果在hg diff后跟上-g选项,你将会看到文件的实际状态。在unix系统下运行以下代码,看看输出结果。

1.chmod +x a
2.hg diff -g

七、后话

版本控制系统通常用来管理文本文件,一些集中式版本控制系统也能处理二进制文件。集中式版本控制系统提供一种锁定机制来编辑文件,这会很好的处理文件冲突的发生。假如一个项目中有多个人频繁的修改一些二进制文件,那么hg或其它的分布式管理系统也许就不是最好的工具。

在修改文件时,hg仅仅存贮文件当前版本与上一个版本间的差异。如果对文件做一次小小的改动导致文件的逻辑发生了巨大的改变,hg就不能很有效的存储这些差异,并直接影响到存储的空间和clone代码所花费的时间。因此,对于以下的两种情形应慎之又慎:

  1. 较大而且不能压缩的文件;
  2. 文件频繁编辑导致版本间产生巨大差异。

hg维护着克隆的所有历史,任何人的代码仓库都可以作为备份源。当然,可以在远程服务器上构建一个小小的脚本来定时备份代码仓库。如果只是作传统的备份,运行hg clone -U myrepo myrepo.bak即可,这里的选项-U会在clone完成后不对工作目录进行更新操作,详情可以参看hg help clone。

hg常用命令的更多相关文章

  1. Android学习第一天-adb常用命令

    平时开发android应用 的时候,我们都会用到包含在Android SDK中一系列的工具,或许我们通过Eclipse去调用,又或许,我们自己通过打开终端进行手动输入并且执行,下面我们来一起学习下这些 ...

  2. redis数据类型及常用命令介绍(图文实例)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhgAAAFLCAYAAACUdvXUAAAgAElEQVR4nO3da1da58L2fT5KfPvc96 ...

  3. adb常用命令及简介

    平时开发android应用 的时候,我们都会用到包含在Android SDK中一系列的工具,或许我们通过Eclipse去调用,又或许,我们自己通过打开终端进行手动输入并且执行,下面我们来一起学习下这些 ...

  4. adb常用命令-android学习第一天

    转载出处:http://www.cnblogs.com/xiaoxuetu/ 转载来源:https://www.cnblogs.com/xiaoxuetu/p/3411214.html 平时开发and ...

  5. Linux 常用命令(持续补充)

    常用命令: command &:将进程放在后台执行 ctrl + z:暂停当前进程 并放入后台 jobs:查看当前后台任务 bg( %id):将任务转为后台执行 fg( %id):将任务调回前 ...

  6. LVM基本介绍与常用命令

    一.LVM介绍LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制LVM - 优点:LVM通常用于装备大量磁盘的系统,但它同样适 ...

  7. Linux学习笔记(一):常用命令

    经过统计Linux中能够识别的命令超过3000种,当然常用的命令就远远没有这么多了,按照我的习惯,我把已经学过的Linux常用命令做了以下几个方面的分割: 1.文件处理命令 2.文件搜索命令 3.帮助 ...

  8. git常用命令(持续更新中)

    git常用命令(持续更新中) 本地仓库操作git int                                 初始化本地仓库git add .                       ...

  9. 【原】npm 常用命令详解

    今年上半年在学习gulp的使用,对npm的掌握是必不可少的,经常到npm官网查询文档让我感到不爽,还不如整理了一些常用的命令到自己博客上,于是根据自己的理解简单翻译过来,终于有点输出,想学习npm这块 ...

随机推荐

  1. 多线程基础(六)GCD基础

    更多值得学习的GCD知识,可以学习: Grand Central Dispatch (GCD) Reference GCDObjC 1.GCD的基本概念     什么是GCD 全称是Grand Cen ...

  2. [BS-14] 打印NSArray和NSDictionary的3种方法

    打印NSArray和NSDictionary的3种方法 NSArray *arr = @[@"奔驰",@"宝马",@"路虎",@" ...

  3. Actioncontext之类的map嵌套,取值

    假设图中最顶端的map设为Actioncontext的map,这种情况,用<s:property value=""/>或者EL表达式取值,可以用#key1.key2.k ...

  4. iOS中UIKit——UIDataDetectors&lpar;数据检测器&rpar;它将电话、邮件、网址等变为链接

    1.它用于UITextView和UIWebView,属性名为:dataDetetorTypes 2.此属性可以设定使符合电话.邮件.网址.符合格式的日期等文字变为链接文字. 3.电话号码点击后拨出电话 ...

  5. WP8教程

    http://www.maiziedu.com/courses-list?technology_category=6

  6. Core Data 教学

    看了一篇国外的文章,关于iOS9的Core Data教学,在这里做了一下总结 Core Data 教学 示例开源地址:LastDayCoreData 在这篇文章中我们将学习Core Data的系列教程 ...

  7. PythonStudy——Python字典底层实现原理 The underlying implementation principle of Python dictionary

    在Python中,字典是通过散列表或说哈希表实现的.字典也被称为关联数组,还称为哈希数组等.也就是说,字典也是一个数组,但数组的索引是键经过哈希函数处理后得到的散列值.哈希函数的目的是使键均匀地分布在 ...

  8. 736&period; Parse Lisp Expression

    You are given a string expression representing a Lisp-like expression to return the integer value of ...

  9. POST提交表单时EnType设置问题

    POST提交表单时EnType设置问题 首先知道enctype这个属性管理的是表单的MIME编码.共有三个值可选: 1.application/x-www-form-urlencoded 2.mult ...

  10. springMVC拦截css与js等资源文件的解决

    写了一个demo的ssm,使用jetty容器跑的,但是在页面的时候总是发现访问资源出现404. 换了多种写法不见效. 偶然发现日志中请求被springMVC拦截了,气死我了. 解决方式: Spring ...