图解 hg 命令

2013-11-13 00:00:00 by 【6yang】, 713 visits, 收藏 | 返回
 

用了3年的hg,突然要切换到git,最近两天被git折磨的吐血,可是擦擦干净还得干活不是~
趁着对hg的了解还新鲜,总结下来,过几天git熟了再来个对比说明哈~~

hg和svn最大的区别就是remote repo和working copy之间多了个local repo,还有就是强大的Queue功能。经验之谈就是,一定要发挥queue的强大优势,否则hg就白用了!

这里列了一下常用的hg命令,最后还总结了几个常用的场景。

图解 hg 命令 - 晶晶 - 晒太阳的地方
自己画的图图,有点丑。供快速参考。更详细说明如下:
 

基本命令

hg help [command]  //eg: hg help qnew

hg st // 查看working copy与local repository之间的的所有更改

hg diff // 查看working copy与local repository之间的的所有更改的详细内容

hg in // 查看remote repository 上可更新的changeset

hg out // 查看local repository上 可push的changeset

hg ci -m "comment" // 提交本地修改到local repository,ci = commit

hg update // 应用local repository的更新到本地

hg heads // 查看head的数量,如果多于一个则需要merge

hg merge // merge多个heads

hg push // 提交本地更新到remote repository

hg log -l 5 // 查看最新的5个changeset

hg revert . // 最常用的revert命令,"."表示当前repository中的所有修改。如果只想revert某个文件,把"."换成文件路径即可。删除 working copy中所有修改。revert之后,会在被revert文件旁边创建备份文件,后缀名是.orig,所以可以放心大胆的revert,不用害怕修改找 不回来。

hg revert -r 12345 --all // revert版本12345之后所有的修改,注:版本12345本身的修改不会被revert

hg strip 12345 // 从local repo及working copy上删掉12345及之后所有的版本,hg in又能看见remote repo上12345之后的修改

队列命令(Queue)

hg qnew "comment" patch_name.diff // 创建一个patch。创建patch之后,就千万不要再执行hg ci -m "" 命令,血泪的教训啊!!

hg qref // 把当前working copy里的修改更新到最新的patch里

hg qref not_existing_file_name // 把最新的queue里的内容置换回working copy里,即hg st可见。此命令之后,最新的queue还存在,只是里面不包含没有任何更改了。

hg qpop // 把最上面的的patch移出队列

hg qpush // 应用一个patch

hg qremove patch_name //删除一个patch,只有被pop出来的patch才能被删除

hg qser // 查看所有已有的patch

hg qapp // 查看所有被应用的patch

hg qfinish -a // finish 之后的patch才能被提交

hg qimport "C: est.diff" // 导入指定patch文件,之后需要执行qpush才能把新导入的queue应用上

hg qimport -r 12345 // 把已经finish的changeset再变回queue,-r后的参数为changeset的版本号

其他命令

hg purge // 删除所有新增的文件

hg pull --rebase // 非常常用而且重要的命令!本地有q的时候使用,从center repository上得到最新更新,并在更新的代码上应用本地的queues。如果有queue的情况下,忘了使用--rebase,而是执行了hg pull -u,解决办法见下面场景5。

 

扩展(Extension)

如果使用上面命令的时候hg说没有这些命令,那么就要加一些extension。

常用的extensiongs, 包括q, purge, pull rebase等, 修改.hg文件夹中的hgrc文件,如下:

[paths]
default = [repository path]

[extensions]
hgext.mq=
hgext.purge=
rebase=

一些可能的场景

场景0:使用hg管理代码的基本步骤

1, 假设我们现在本地没有任何修改(即hg st,hg out都没有内容)
2, 修改代码,阶段性完成一部分功能。这时使用hg st可以看到修改了哪些文件,hg diff看详细修改内容。
3, 如果有需要增加或删除的文件(执行hg st,看到的前面带?或!的文件),执行hg addrem进行添加删除
4, 创建queue: hg qnew -m "task A"  A.diff。这样就保证这些修改被保存起来,之后的修改如果需要revert,也不会影响已经进入queue的这部分。这步之后hg st里应当没有任何内容了,可以使用hg qser和hg qdiff来查看修改。
5, 继续做后面的功能
6, 如果开发不顺利,需要重写5中的部分,就使用下面命令revert所有5的修改:“hg revert .”。
7, 如果第5步开发顺利,想把5中的修改添加到4中创建的queue里:hg qref。
8, 如果第5步开发顺利,想把5中的修改添加到一个新的queue里:hg qnew -m "task B"  B.diff。
9, 更新remote的修改:hg pull --rebase,如果有冲突,hg会自动弹出merge窗口
10, 如果还需要继续修改,回到第5步。
11, 提交修改:hg qfinish -a,之后hg push,完成。回到第1步。

场景1: 把机器A上的修改转移到机器B上

1, 在A上: hg qnew -m "blah..." q.diff
2, 打开文件夹:[项目目录]/.hg/patches,把 q.diff 拷贝到B机器,例如,放到c盘根目录下
3, 在B上,hg qimport C:q.diff
4, hg qpush。
5, 回到A上,弹出q.diff:hg qpop
6, 把A上的这个queue删除:hg qremove q.diff。
完成~

场景2: 后做的修改要先提交

这种情况经常发生,比如正在做一个功能A,尚未完成,突然要先修一个bug B。

1,修复B之前,先把功能A的修改queue起来: hg qnew -m "comment" a.diff
2,把A的代码弹出队列:hg qpop
3,修改B
4,提交B:hg qnew -m "fix bug B" b.diff; hg pull --reb; hg qfinish -a; hg push;
5,把A的修改应用回来:hg qpush
完成~ 可以继续开发功能A了

场景3:在Local Repo和Remote Repo之间再搭一个hg server
这种情况发生在一个小组内部互相之间需要频繁提交,却不适合直接提交到remote repo的情况。
1,在某台电脑上(如A上),复制一份代码。
2,修改.hg文件夹中的hgrc文件,根据自己的需要修改提交权限,例如:


[web]
allow_push = *
push_ssl = false

3,在新创建的代码库上,运行如下命令: hg serve -p 2222 -d (-p后面是端口号,-d表示后台运行)
4,把其他电脑的hg的remote repo都指向电脑A: 修改.hg文件夹中的hgrc文件,把repo地址指向电脑A的地址,端口如上面-p所设
5,server搭建完成,其他电脑的提交会提交到电脑A上,在A上的操作如下
6,A更新其他电脑的修改:hg update
7,A更新remote repo的修改: hg fetch
8,A提交到remote repo:hg push

场景4:创建及合并分支

场景:需要创建一个分支,来满足trunk上可以继续开发新功能,branch上要进行bugfix。branch上的修改要经常更新到trunk上。

1, 创建分支,我常用的方法是到remote server上复制一个trunk repository文件夹。假设这个文件夹叫branch,在这个文件夹下执行 “hg serve -p [port] -d” 命令,这样在开发机上就可以使用 hg clone 命令checkout代码了。
2,在branch上进行修改。
3,如果要把 branch的修改更新到trunk上:在开发机trunk文件夹下,执行 hg pull http://[branch-address]:[port]。中间如果有冲突,hg会自动提示merge。之后使用hg st命令能看到merge的修改。再用hg ci + hg push命令提交就可以了。

场景5:在已经创建了queue的情况下,又执行了hg pull -u命令
前面说过,在执行过qnew之后,一定要使用hg pull --rebase命令,不能使用-u。否则会出现这种情况下
执行hg st会显示有修改。这些都是pull下来的内容。
执行hg qpop会显示有本地更新,无法qpop。
执行hg revert会显示有未提交的merge。
好像陷入了一个死循环。
这时候如果希望删掉本地修改,重新执行hg pull --rebase命令,可以这样做:
1,hg log -l 5 // 看最近的5个changesets,不够的话就多看几个。找到你要回滚到的version号,比如1111。
2,hg strip [version number] -f // 删掉version number之后的changesets,可以重新执行hg pull --rebase了。
分享到:
share

    图片原图

    loading

    loading