版本管理 RCS之命令基礎篇
RCS作為非常古老的版本工具,遠遠在SVN和已經退役的CVS之前。它的古老程度應該比Web開發的ASP前代的CGI還要久遠。但是作為非常簡單的文本格式的版本管理工具,它使用時間跨度之久令人驚奇。如果想對版本管理實現方式進行深入研究的話,RCS提供了一種最為簡單的方式,,v文件是RCS的全部,以文本形式存放,簡單易讀,對於想深入了解版本管理或者想開發類似工具的開發者來說,絕對是可以借鑒的。
安裝
比如像centos等,新的centos7之前應該都是被缺省安裝的。如果沒有的話,yum install rcs即可。230k左右的package,可以完成很多的功能。
===================================================================================================================================================
Package Arch Version Repository Size
===================================================================================================================================================
Installing:
rcs x86_64 5.9.0-5.el7 base 230 k
Transaction Summary
===================================================================================================================================================
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
版本確認
[root@host31 ~]# rcs --version
rcs (GNU RCS) 5.9.0
Copyright (C) 2010-2013 Thien-Thi Nguyen
Copyright (C) 1990 -1995 Paul Eggert
Copyright (C) 1982,1988,1989 Walter F. Tichy, Purdue CS
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[root@host31 ~]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
checkin命令:ci
準備
[root@host31 ~]# mkdir -p /local/testrcs
[root@host31 ~]# cd /local/testrcs
[root@host31 testrcs]# mkdir RCS
[root@host31 testrcs]# echo "#include <stdio.h>" >hello.h
- 1
- 2
- 3
- 4
checkin命令:ci
[root@host31 testrcs]# ci hello.h
RCS/hello.h,v <-- hello.h
enter description, terminated with single ‘.‘ or end of file:
NOTE: This is NOT the log message!
>> initial version
>> .
initial revision: 1.1
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
checkin後的確認,發現文件不見了,只有RCS下生成的,v文件了
[root@host31 testrcs]# ll
total 0
drwxr-xr-x. 2 root root 22 Aug 15 21:48 RCS
[root@host31 testrcs]# ll RCS
total 4
-r--r--r--. 1 root root 213 Aug 15 21:48 hello.h,v
[root@host31 testrcs]# cat RCS/hello.h,v
head 1.1;
access;
symbols;
locks; strict;
comment @ * @;
1.1
date 2016.08.15.17.47.54; author root; state Exp;
branches;
next ;
desc
@initial version
@
1.1
log
@Initial revision
@
text
@#include <stdio.h>
@
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
再看hello.h,v文件你會清晰地發現版本管理中需要考慮的東西內容,branch/lock/log/tag/操作等,你在SVN中能做到的事情RCS同樣可以做到,只不過有時需要再封裝一層。在沒有SVN和git甚至沒有CVS的時代我們就曾經通過自己封裝RCS做到多項目同時開發,branch/tag/自動merge無所不能,工具本身沒有所謂那個更好,對我們來說只是方便和合適最為重要。
checkout命令:co
[root@host31 testrcs]# ll
total 0
drwxr-xr-x. 2 root root 22 Aug 15 21:48 RCS
[root@host31 testrcs]# co hello.h
RCS/hello.h,v --> hello.h
revision 1.1
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
修正差分確認:rcsdiff
準備:事前lock住要修正的文件。
[root@host31 testrcs]# co -l hello.h
RCS/hello.h,v --> hello.h
revision 1.1 (locked)
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
在hello.h中增加一行
[root@host31 testrcs]# cat hello.h
#include <stdio.h>
#include <string.h>
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
checkin之前確認差分
[root@host31 testrcs]# rcsdiff hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 1.1
diff -r1.1 hello.h
1a2
> #include <string.h>
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
checkin, 在1.1的版本之上生成1.2,ci -u即可保證本地文件在checkin之後不被刪除。
[root@host31 testrcs]# ci -u hello.h
RCS/hello.h,v <-- hello.h
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single ‘.‘ or end of file:
>> add string.h
>> .
done
[root@host31 testrcs]# ll
total 4
-r--r--r--. 1 root root 39 Aug 15 22:00 hello.h
drwxr-xr-x. 2 root root 22 Aug 15 22:03 RCS
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
也可以使用如下的方式進行確認
[root@host31 testrcs]# rcsdiff -r1.1 -r1.2 hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -r1.1 -r1.2
1a2
> #include <string.h>
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
創建branch
[root@host31 testrcs]# ci -r2.0 -f -m "initial" hello.h
RCS/initial,v <-- initial
ci: initial: No such file or directory
RCS/hello.h,v <-- hello.h
new revision: 2.0; previous revision: 1.2
done
[root@host31 testrcs]#
[root@host31 testrcs]# co -l hello.h
RCS/hello.h,v --> hello.h
revision 2.0 (locked)
done
[root@host31 testrcs]#
[root@host31 testrcs]# rcsdiff hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 2.0
diff -r2.0 hello.h
2a3
> #include "test.h"
[root@host31 testrcs]#
[root@host31 testrcs]# ci -u hello.h
RCS/hello.h,v <-- hello.h
new revision: 2.1; previous revision: 2.0
enter log message, terminated with single ‘.‘ or end of file:
>> modify for 2.0
>> .
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
在2.1的版本上繼續lock,修改,checkin,發現只能繼續生成2.2的版本
[root@host31 testrcs]# co -l -r2.1 hello.h
RCS/hello.h,v --> hello.h
revision 2.1 (locked)
done
[root@host31 testrcs]# vi hello.h
[root@host31 testrcs]# rcsdiff hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 2.1
diff -r2.1 hello.h
3a4
> #include "test2.1.h"
[root@host31 testrcs]# ci -u -m "add test2.1.h" hello.h
RCS/add test2.1.h,v <-- add test2.1.h
ci: add test2.1.h: No such file or directory
RCS/hello.h,v <-- hello.h
new revision: 2.2; previous revision: 2.1
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
如果我們現在對舊的版本1.1進行lock,然後修正,然後checkin會發生什麽呢
[root@host31 testrcs]# co -l -r1.1 hello.h
RCS/hello.h,v --> hello.h
revision 1.1 (locked)
done
[root@host31 testrcs]# vi hello.h
[root@host31 testrcs]# rcsdiff hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 2.2
diff -r2.2 hello.h
2,4c2
< #include <string.h>
< #include "test.h"
< #include "test2.1.h"
---
> #include "test1.1.h"
[root@host31 testrcs]# ci -u -m "add test1.1.h" hello.h
RCS/add test1.1.h,v <-- add test1.1.h
ci: add test1.1.h: No such file or directory
RCS/hello.h,v <-- hello.h
new revision: 1.1.1.1; previous revision: 1.1
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
1.0/2.0進行大的Trunk管理,在其下生成的1.1 2.1等進行lock,進一步生成第一層的Branch,這是個4位的版本號,1.1.1.1, 第四位是文件自身的版本號,第三位第一層Branch號,第一位和第二位結合起來為發生branch的位置。能不能生成2層的branch呢,答案是肯定的,如果項目有奇葩的需求的話,你可以繼續往下生成branch。現在你的版本號是1.1.1.1.1.1了,夠不夠長。
[root@host31 testrcs]# co -l -r1.1.1.1 hello.h
RCS/hello.h,v --> hello.h
revision 1.1.1.1 (locked)
done
[root@host31 testrcs]# vi hello.h
[root@host31 testrcs]# rcsdiff hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 2.2
diff -r2.2 hello.h
2,4c2,3
< #include <string.h>
< #include "test.h"
< #include "test2.1.h"
---
> #include "test1.1.h"
> #include "test1.1.1.1.h"
[root@host31 testrcs]#
[root@host31 testrcs]# ci -u -m "add test1.1.1.1.h" hello.h
RCS/add test1.1.1.1.h,v <-- add test1.1.1.1.h
ci: add test1.1.1.1.h: No such file or directory
RCS/hello.h,v <-- hello.h
new revision: 1.1.1.2; previous revision: 1.1.1.1
done
[root@host31 testrcs]#
[root@host31 testrcs]# co -l -r1.1.1.1 hello.h
RCS/hello.h,v --> hello.h
revision 1.1.1.1 (locked)
done
[root@host31 testrcs]# vi hello.h
[root@host31 testrcs]# rcsdiff hello.h
===================================================================
RCS file: RCS/hello.h,v
retrieving revision 2.2
diff -r2.2 hello.h
2,4c2,3
< #include <string.h>
< #include "test.h"
< #include "test2.1.h"
---
> #include "test1.1.h"
> #include "test1.1.1.1.branch.h"
[root@host31 testrcs]# ci -u -m "1.1.1.1 branch" hello.h
RCS/1.1.1.1 branch,v <-- 1.1.1.1 branch
ci: 1.1.1.1 branch: No such file or directory
RCS/hello.h,v <-- hello.h
new revision: 1.1.1.1.1.1; previous revision: 1.1.1.1
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
rlog確認詳細信息
[root@host31 testrcs]# rlog hello.h
RCS file: RCS/hello.h,v
Working file: hello.h
head: 2.2
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 8; selected revisions: 8
description:
initial version
----------------------------
revision 2.2
date: 2016/08/15 22:13:25; author: root; state: Exp; lines: +1 -0
*** empty log message ***
----------------------------
revision 2.1
date: 2016/08/15 22:10:19; author: root; state: Exp; lines: +1 -0
modify for 2.0
----------------------------
revision 2.0
date: 2016/08/15 22:07:41; author: root; state: Exp; lines: +0 -0
*** empty log message ***
----------------------------
revision 1.2
date: 2016/08/15 22:03:45; author: root; state: Exp; lines: +1 -0
add string.h
----------------------------
revision 1.1
date: 2016/08/15 21:47:54; author: root; state: Exp;
branches: 1.1.1;
Initial revision
----------------------------
revision 1.1.1.2
date: 2016/08/15 22:31:13; author: root; state: Exp; lines: +1 -0
*** empty log message ***
----------------------------
revision 1.1.1.1
date: 2016/08/15 22:15:10; author: root; state: Exp; lines: +1 -0
branches: 1.1.1.1.1;
*** empty log message ***
----------------------------
revision 1.1.1.1.1.1
date: 2016/08/15 22:32:27; author: root; state: Exp; lines: +1 -0
*** empty log message ***
=============================================================================
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
rlog -h 則可以單獨列出symbolicnames等信息
[root@host31 testrcs]# rlog -h hello.h
RCS file: RCS/hello.h,v
Working file: hello.h
head: 2.2
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 8
=============================================================================
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
修改註釋 rcs -m
修正前rlog信息
revision 1.1
date: 2016/08/15 21:47:54; author: root; state: Exp;
branches: 1.1.1;
Initial revision
- 1
- 2
- 3
- 4
[root@host31 testrcs]# rcs -m1.1:"initial version" hello.h
RCS file: RCS/hello.h,v
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
修正後rlog信息
revision 1.1
date: 2016/08/15 21:47:54; author: root; state: Exp;
branches: 1.1.1;
initial version
- 1
- 2
- 3
- 4
註意:-m和版本之間不能有空格等細小的事項
管理symbolic names: rcs -n
為什麽要用symbolic names,很簡單,作tag。使用方便的管理工具的時候你可能不會意識到版本管理工具替你做了什麽,但是用RCS,需要一個文件一個文件的設定上tag,無論什麽樣的版本管理工具,他們都應該是類似,有一種特定的方法將某一時間斷面的所有文件進行整體管理。現代的版本管理工具不會讓你如此麻煩,但同時也拿去了我們了解其實際運作的機會。
[root@host31 testrcs]# rcs -nNewBranch:1.1.1.1.1.1 hello.h
RCS file: RCS/hello.h,v
done
[root@host31 testrcs]# rlog -h hello.h
RCS file: RCS/hello.h,v
Working file: hello.h
head: 2.2
branch:
locks: strict
access list:
symbolic names:
NewBranch: 1.1.1.1.1.1
keyword substitution: kv
total revisions: 8
=============================================================================
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
刪除symbolic names
[root@host31 testrcs]# rcs -nNewBranch hello.h
RCS file: RCS/hello.h,v
done
[root@host31 testrcs]# rcs -h hello.h
rcs: unknown option: -h
[root@host31 testrcs]# rlog -h hello.h
RCS file: RCS/hello.h,v
Working file: hello.h
head: 2.2
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 8
=============================================================================
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
註意事項:-nname:rev 的版本如果不存在的時候會出錯,註意空格
刪除版本 rcs -o
刪除1.1.1.1.1.1這個很鬧心的版本
[root@host31 testrcs]# rcs -o1.1.1.1.1.1 hello.h
RCS file: RCS/hello.h,v
deleting revision 1.1.1.1.1.1
done
[root@host31 testrcs]#
- 1
- 2
- 3
- 4
- 5
除了指定版本刪除,還有可以指定from和to的一定範圍的刪除方式
方式 | 詳細說明 |
---|---|
rev1:rev2 | 從rev1刪到rev2 |
rev1: | 刪除rev1開始的分支所有版本 |
:rev2 | 刪除到rev2的所有版本 |
此操作無比兇險,執行之前務必保存好,v文件以便恢復
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow
版本管理 RCS之命令基礎篇