はじめに
これは2017/06/03 に作成した過去記事の移植です。
CVSからGitの移行について
CVSリポジトリをGitリポジトリに変換する機会があったので、使用するコマンドなどをまとめます。 ここでは、まずCVSのリポジトリを作成し、それをGitリポジトリに変換し、履歴がどうなっているのかを確認します。
CVSリポジトリの作成
まずは、CVSのリポジトリ用のディレクトリを作成します。
CVSディレクトリ作成
[root@tk2-256-37863 horiba]mkdir cvsroot
[root@tk2-256-37863 horiba]ls
cvsroot
CVSリポジトリの初期化
[root@tk2-256-37863 horiba] cvs -d /home/horiba/cvsroot/ init
treeコマンドでディレクトリを調べると以下のようになるはずです。
[root@tk2-256-37863 horiba] tree
.
-- cvsroot
-- CVSROOT
|-- Emptydir
|-- checkoutlist
|-- checkoutlist,v
|-- commitinfo
|-- commitinfo,v
|-- config
|-- config,v
|-- cvswrappers
|-- cvswrappers,v
|-- editinfo
|-- editinfo,v
|-- history
|-- loginfo
|-- loginfo,v
|-- modules
|-- modules,v
|-- notify
|-- notify,v
|-- rcsinfo
|-- rcsinfo,v
|-- taginfo
|-- taginfo,v
|-- val-tags
|-- verifymsg
-- verifymsg,v
3 directories, 24 files
CVSROOTの環境パス設定
[root@tk2-256-37863 horiba] CVSROOT=/home/horiba/cvsroot; export CVSROOT
[root@tk2-256-37863 horiba] echo $CVSROOT
/home/horiba/cvsroot
CVSリポジトリの作業場所を作成
[root@tk2-256-37863 horiba] mkdir work
[root@tk2-256-37863 horiba] cd work/
[root@tk2-256-37863 work] mkdir project
[root@tk2-256-37863 work] cd project/
[root@tk2-256-37863 project] echo "CVS initalize commit." > init.txt
[root@tk2-256-37863 project] cat init.txt
CVS initalize commit.
CVSリポジトリにインポートする
CVSに projectをインポートします。
書式は以下の通り
cvs import [モジュール名] [ベンダタグ] [リリースタグ]
[root@tk2-256-37863 project] cvs import -m "Project" project horiba project_0_1
N project/init.txt
No conflicts created by this import
CVSに projectをインポートします。
チェックアウトをする
[root@tk2-256-37863 horiba] mkdir checkout_dir ←チェックアウト用のディレクトリを作成
[root@tk2-256-37863 horiba] cd checkout_dir/
[root@tk2-256-37863 checkout_dir] cvs checkout project ← cvsリポジトリ(projectモジュール)をチェックアウトする。
cvs checkout: Updating project
U project/init.txt
[root@tk2-256-37863 checkout_dir] ll ←チェックアウトできたか確認
合計 0
drwxr-xr-x 3 root root 31 6月 3 16:06 project
[root@tk2-256-37863 checkout_dir] cd project/
[root@tk2-256-37863 project] ll
合計 4
drwxr-xr-x 2 root root 48 6月 3 16:06 CVS
-rw-r--r-- 1 root root 22 6月 3 16:03 init.txt
[root@tk2-256-37863 project] cat init.txt ← 中身を確認
CVS initalize commit.
CVSリポジトリに新たにコミットをする
[root@tk2-256-37863 project] echo "Add new line" >> init.txt
[root@tk2-256-37863 project] cat init.txt ←追加されていることを確認
CVS initalize commit.
Add new line
[root@tk2-256-37863 project] cvs diff ←リポジトリとの差分チェック
cvs diff: Diffing .
Index: init.txt
===================================================================
RCS file: /home/horiba/cvsroot/project/init.txt,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 init.txt
1a2
> Add new line ←ここが追加されている
[root@tk2-256-37863 project] cvs commit -m "Add new Line" ←コミットメッセージを添えてコミット
cvs commit: Examining .
Checking in init.txt;
/home/horiba/cvsroot/project/init.txt,v <-- init.txt
new revision: 1.2; previous revision: 1.1
done
CVSリポジトリに新しいファイルを追加する
[root@tk2-256-37863 project] echo "New File" > newfile.txt
[root@tk2-256-37863 project] cvs update
cvs update: Updating .
? newfile.txt ← ?マークがついているため、CVSの追跡対象外ファイル
[root@tk2-256-37863 project] cvs add newfile.txt ←CVSの追跡対象にする
cvs add: scheduling file 'newfile.txt' for addition
cvs add: use 'cvs commit' to add this file permanently
[root@tk2-256-37863 project] cvs commit -m "Add newfile.txt"
cvs commit: Examining .
RCS file: /home/horiba/cvsroot/project/newfile.txt,v
done
Checking in newfile.txt;
/home/horiba/cvsroot/project/newfile.txt,v <-- newfile.txt
initial revision: 1.1
done
[root@tk2-256-37863 project] cvs update
cvs update: Updating .
CVSリポジトリに新しいディレクトリを追加する
ディレクトリはコミットをしなくてもリポジトリに反映される。
[root@tk2-256-37863 project] mkdir src
[root@tk2-256-37863 project] cvs update
cvs update: Updating .
? src
[root@tk2-256-37863 project] cvs add src
Directory /home/horiba/cvsroot/project/src added to the repository
[root@tk2-256-37863 project] cvs update
cvs update: Updating .
cvs update: Updating src
ここまでがCVSの作業です。
テスト用にリポジトリを作成しましたが、実際はもっと巨大なリポジトリになっているはずです。
テスト用にブランチを作成
[root@tk2-256-37863 project] cvs tag -b new_branch ← new_barnchというブランチを作成
cvs tag: Tagging .
T init.txt
T newfile.txt
cvs tag: Tagging src
[root@tk2-256-37863 project] cvs stat init.txt ←現在のブランチを確認
===================================================================
File: init.txt Status: Up-to-date
Working revision: 1.2 Sat Jun 3 07:12:34 2017
Repository revision: 1.2 /home/horiba/cvsroot/project/init.txt,v
Sticky Tag: (none) ← Sticky Tagが(none)なので、現ブランチはtrunk
Sticky Date: (none)
Sticky Options: (none)
[root@tk2-256-37863 project] cvs update -r new_branch ← ブランチを切り替え(new_branch)
cvs update: Updating .
U init.txt
U newfile.txt
cvs update: Updating src
[root@tk2-256-37863 project] cvs stat init.txt
===================================================================
File: init.txt Status: Up-to-date
Working revision: 1.2 Sat Jun 3 07:26:46 2017
Repository revision: 1.2 /home/horiba/cvsroot/project/init.txt,v
Sticky Tag: new_branch (branch: 1.2.2) ← new_branchになっている
Sticky Date: (none)
Sticky Options: (none)
[root@tk2-256-37863 project] echo "new branch" > branch.txt
[root@tk2-256-37863 project] cvs add branch.txt
cvs add: scheduling file 'branch.txt' for addition on branch 'new_branch'
cvs add: use 'cvs commit' to add this file permanently
[root@tk2-256-37863 project] cvs commit -m "Add branch.txt" ←ブランチにコミット
cvs commit: Examining .
cvs commit: Examining src
RCS file: /home/horiba/cvsroot/project/Attic/branch.txt,v
done
Checking in branch.txt;
/home/horiba/cvsroot/project/Attic/branch.txt,v <-- branch.txt
new revision: 1.1.2.1; previous revision: 1.1
done
Gitリポジトリへの移行
cvs2gitのツール準備
https://github.com/mhagger/cvs2svn/releases ここから cvs2svn をダウンロードする
(リンク切れであったため修正した。上記のURLに読み替えて以下を作業すること)
解凍をし、make installを行う。
[root@tk2-256-37863 horiba] wget http://cvs2svn.tigris.org/files/documents/1462/49237/cvs2svn-2.4.0.tar.gz
[root@tk2-256-37863 horiba] tar zxvf cvs2svn-2.4.0.tar.gz
[root@tk2-256-37863 horiba] mv cvs2svn-2.4.0 cvs2git
[root@tk2-256-37863 horiba] cd cvs2git/
データの準備
CVSROOT 以下と移行したいリポジトリのディレクトリ以下をローカルにコピーしてくる
今回は、/home/horibaにimportというディレクトリを用意し、そこにいれる。
- CVSROOT
- インポートしたいプロジェクト
データをインポートさせたい場所に移動
[root@tk2-256-37863 horiba] ll
合計 4
drwxr-xr-x 3 root root 20 6月 3 16:06 checkout_dir
drwxrwxr-x 10 501 501 4096 6月 3 17:04 cvs2git
drwxr-xr-x 4 root root 34 6月 3 16:03 cvsroot
drwxr-xr-x 2 root root 6 6月 3 17:17 import
drwxr-xr-x 3 root root 20 6月 3 16:00 work
[root@tk2-256-37863 horiba] cp cvsroot/CVSROOT/ import/ -R
[root@tk2-256-37863 horiba] cp cvsroot/project/ import/ -R
[root@tk2-256-37863 cvsroot] cd /home/horiba/
データをインポートする
[root@tk2-256-37863 horiba]# cvs2git --blobfile=git-blob.dat --dumpfile=git-dump.dat --username=horiba--encoding=utf-8 --fallback-encoding=utf-8 import/
----- pass 1 (CollectRevsPass) -----
Examining all CVS ',v' files...
import/CVSROOT/checkoutlist,v
import/CVSROOT/commitinfo,v
import/CVSROOT/config,v
import/CVSROOT/cvswrappers,v
import/CVSROOT/editinfo,v
import/CVSROOT/loginfo,v
import/CVSROOT/modules,v
import/CVSROOT/notify,v
import/CVSROOT/rcsinfo,v
import/CVSROOT/taginfo,v
import/CVSROOT/verifymsg,v
import/project/init.txt,v
import/project/newfile.txt,v
import/project/Attic/branch.txt,v
Done
Time for pass1 (CollectRevsPass): 0.024 seconds.
----- pass 2 (CleanMetadataPass) -----
Converting metadata to UTF8...
Done
Time for pass2 (CleanMetadataPass): 0.007 seconds.
----- pass 3 (CollateSymbolsPass) -----
Checking for forced tags with commits...
Done
Time for pass3 (CollateSymbolsPass): 0.007 seconds.
----- pass 4 (FilterSymbolsPass) -----
Filtering out excluded symbols and summarizing items...
Done
Time for pass4 (FilterSymbolsPass): 0.093 seconds.
----- pass 5 (SortRevisionsPass) -----
Sorting CVS revision summaries...
Done
Time for pass5 (SortRevisionsPass): 0.005 seconds.
----- pass 6 (SortSymbolsPass) -----
Sorting CVS symbol summaries...
Done
Time for pass6 (SortSymbolsPass): 0.004 seconds.
----- pass 7 (InitializeChangesetsPass) -----
Creating preliminary commit sets...
Done
Time for pass7 (InitializeChangesetsPass): 0.009 seconds.
----- pass 8 (BreakRevisionChangesetCyclesPass) -----
Breaking revision changeset dependency cycles...
Done
Time for pass8 (BreakRevisionChangesetCyclesPass): 0.009 seconds.
----- pass 9 (RevisionTopologicalSortPass) -----
Generating CVSRevisions in commit order...
Done
Time for pass9 (RevisionTopologicalSortPass): 0.009 seconds.
----- pass 10 (BreakSymbolChangesetCyclesPass) -----
Breaking symbol changeset dependency cycles...
Done
Time for pass10 (BreakSymbolChangesetCyclesPass): 0.007 seconds.
----- pass 11 (BreakAllChangesetCyclesPass) -----
Breaking CVSSymbol dependency loops...
Done
Time for pass11 (BreakAllChangesetCyclesPass): 0.008 seconds.
----- pass 12 (TopologicalSortPass) -----
Generating CVSRevisions in commit order...
Done
Time for pass12 (TopologicalSortPass): 0.007 seconds.
----- pass 13 (CreateRevsPass) -----
Mapping CVS revisions to Subversion commits...
Creating Subversion r1 (Project initialization)
Creating Subversion r2 (commit)
Creating Subversion r3 (commit)
Creating Subversion r4 (copying to tag 'project_0_1')
Creating Subversion r5 (commit)
Creating Subversion r6 (commit)
Creating Subversion r7 (copying to branch 'new_branch')
Creating Subversion r8 (commit)
Done
Time for pass13 (CreateRevsPass): 0.010 seconds.
----- pass 14 (SortSymbolOpeningsClosingsPass) -----
Sorting symbolic name source revisions...
Done
Time for pass14 (SortSymbolOpeningsClosingsPass): 0.005 seconds.
----- pass 15 (IndexSymbolsPass) -----
Determining offsets for all symbolic names...
Done.
Time for pass15 (IndexSymbolsPass): 0.003 seconds.
----- pass 16 (OutputPass) -----
Time for pass16 (OutputPass): 0.007 seconds.
cvs2svn Statistics:
------------------
Total CVS Files: 14
Total CVS Revisions: 15
Total CVS Branches: 2
Total CVS Tags: 1
Total Unique Tags: 1
Total Unique Branches: 1
CVS Repos Size in KB: 12
Total SVN Commits: 8
First Revision Date: Sat Jun 3 15:51:18 2017
Last Revision Date: Sat Jun 3 16:27:39 2017
------------------
Timings (seconds):
------------------
0.024 pass1 CollectRevsPass
0.007 pass2 CleanMetadataPass
0.007 pass3 CollateSymbolsPass
0.093 pass4 FilterSymbolsPass
0.005 pass5 SortRevisionsPass
0.004 pass6 SortSymbolsPass
0.009 pass7 InitializeChangesetsPass
0.009 pass8 BreakRevisionChangesetCyclesPass
0.009 pass9 RevisionTopologicalSortPass
0.007 pass10 BreakSymbolChangesetCyclesPass
0.008 pass11 BreakAllChangesetCyclesPass
0.007 pass12 TopologicalSortPass
0.010 pass13 CreateRevsPass
0.005 pass14 SortSymbolOpeningsClosingsPass
0.003 pass15 IndexSymbolsPass
0.007 pass16 OutputPass
0.213 total
[root@tk2-256-37863 horiba]# ll
合計 20
drwxr-xr-x 3 root root 20 6月 3 16:06 checkout_dir
drwxrwxr-x 10 501 501 4096 6月 3 17:04 cvs2git
drwxr-xr-x 4 root root 34 6月 3 16:03 cvsroot
-rw-r--r-- 1 root root 10158 6月 3 17:22 git-blob.dat
-rw-r--r-- 1 root root 2554 6月 3 17:22 git-dump.dat
drwxr-xr-x 4 root root 34 6月 3 17:20 import
drwxr-xr-x 3 root root 20 6月 3 16:00 work
.datが作成されている
Gitリポジトリへ反映
反映するようのGitリポジトリを作成
[root@tk2-256-37863 horiba] mkdir git_repo
[root@tk2-256-37863 horiba]# cd git_repo/
[root@tk2-256-37863 git_repo]# git init
Initialized empty Git repository in /home/horiba/git_repo/.git/
[root@tk2-256-37863 git_repo]# cat ../git-blob.dat ../git-dump.dat | git fast-import
git-fast-import statistics:
---------------------------------------------------------------------
Alloc d objects: 5000
Total objects: 34 ( 0 duplicates )
blobs : 15 ( 0 duplicates 3 deltas of 13 attempts)
trees : 12 ( 0 duplicates 5 deltas of 12 attempts)
commits: 7 ( 0 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 4 ( 3 loads )
marks: 1073741824 ( 22 unique )
atoms: 16
Memory total: 2344 KiB
pools: 2110 KiB
objects: 234 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 15
pack_report: pack_mmap_calls = 4
pack_report: pack_open_windows = 1 / 1
pack_report: pack_mapped = 7234 / 7234
---------------------------------------------------------------------
Gitリポジトリの反映確認
リポジトリ確認
[root@tk2-256-37863 git_repo] ll
合計 4
drwxr-xr-x 2 root root 4096 6月 3 17:25 CVSROOT
drwxr-xr-x 2 root root 39 6月 3 17:25 project
ログ確認
[root@tk2-256-37863 git_repo]# git log
commit cda9cc6531facb46b873267e9d313d923f1d5bce
Author: horiba <>
Date: Sat Jun 3 07:16:13 2017 +0000
Add newfile.txt
commit 0161fd85c89b575294a48a08e4b9eb96dfe38bf6
Author: horiba <>
Date: Sat Jun 3 07:13:00 2017 +0000
Add new Line
commit b67ce725fa1ad57d24cc99d19bf4a91d504c76d3
Author: horiba <>
Date: Sat Jun 3 07:03:28 2017 +0000
Project
commit 9069a0b5297af1a034086dd2d6b210f622ab74fd
Author: horiba <>
Date: Sat Jun 3 06:51:18 2017 +0000
initial checkin
ブランチ確認
[root@tk2-256-37863 git_repo]# git branch -a
* master
new_branch
[root@tk2-256-37863 git_repo]#
チェックアウト時のログ確認
[root@tk2-256-37863 git_repo]# git checkout new_branch
Switched to branch 'new_branch'
[root@tk2-256-37863 git_repo]# git log
commit f5fd22bedc9541926bf5e672331c69d4cffff819
Author: horiba <>
Date: Sat Jun 3 07:27:39 2017 +0000
Add branch.txt
commit 49710aa5e3f06f97bfe6b70f571471c4faca8b40
Author: horiba--encoding=utf-8 <>
Date: Sat Jun 3 07:16:14 2017 +0000
This commit was manufactured by cvs2svn to create branch 'new_branch'.
Sprout from master 2017-06-03 07:16:13 UTC horiba 'Add newfile.txt'
Delete:
CVSROOT/checkoutlist
CVSROOT/commitinfo
CVSROOT/config
CVSROOT/cvswrappers
CVSROOT/editinfo
CVSROOT/loginfo
CVSROOT/modules
CVSROOT/notify
CVSROOT/rcsinfo
CVSROOT/taginfo
CVSROOT/verifymsg
commit cda9cc6531facb46b873267e9d313d923f1d5bce
Author: horiba <>
Date: Sat Jun 3 07:16:13 2017 +0000
Add newfile.txt
commit 0161fd85c89b575294a48a08e4b9eb96dfe38bf6
Author: horiba <>
Date: Sat Jun 3 07:13:00 2017 +0000
Add new Line
commit b67ce725fa1ad57d24cc99d19bf4a91d504c76d3
Author: horiba <>
Date: Sat Jun 3 07:03:28 2017 +0000
Project
commit 9069a0b5297af1a034086dd2d6b210f622ab74fd
Author: horiba <>
Date: Sat Jun 3 06:51:18 2017 +0000
initial checkin
CVSROOTは、masterブランチに存在しているが、不要なので下記コマンドで削除しておく。
[root@tk2-256-37863 git_repo]# rm -fR CVSROOT/
あとは、Gitリポジトリを好きに、リモートに登録して、ブランチを全てプッシュしてあげれば良い。
移行について
CVSはファイル単位での履歴管理なので、どこでバグったかがわかりにくい。
また、修正差分がわかりにくい。
その点Gitはコミット単位での履歴管理なので、修正ファイルが一緒に差分として出せたりするので、とても便利。
Gitは積極的に使うべきであろう。ある程度の操作も覚えるべきだと思う。