svnとgitのコマンド比較
配属された研究室あるいは職場などで共同作業をする時に、svnやgitなどのバージョン管理システム(Version Control System:VCS)を使う機会が多くなると思います。
最近では、Googleをはじめ多くの企業が大規模プロジェクトでgitによるVCSを採用しており、svnからgitに移行する人が多くなっているとの事でした。それで、コマンドの対応表なんかあったら便利だろうと思ってブログを書いていたのですが、自分が作ろうとしている内容と似たようなサイトをいくつか散見してしまい、急に面倒くさくなって更新が遅れてました(汗)。新規性を発揮するのって難しいものですね、研究でもブログでも…
それでも今回は、一応、自分なりにsvnとgitについてまとめてみることにしました。
ここで最初に断っておきますが、分散管理型VCS(後述)には他にmercurialやbazzarなどがあります。しかし、世の中のシェアを見てみると、どうやら
git > mercurial > bazzar
のようなので今回はgitだけを中央管理型VCS(後述)であるsvnの比較対象として扱うことにしました。
VCSでは、「バージョン」やら「リポジトリ」やら難しい単語が出てきますが、ちゃんと使えるようになると非常に便利な機能だと思うので、ぜひこの機会に使い方を覚えてしまいましょう!
(あと、結構あやふやなので間違ってる可能性もあります。指摘して頂ければ修正致します。)
■語句の説明
まず、今回よく出てくる語句について簡単に説明しておきます。
■svnとgitの比較
そもそもsvnとgitの違いは何なのかというと、svnは中央管理型、gitは分散管理型のバージョン管理システムであるということで、svnは中央のリポジトリに対してコミットを行っていくのに対して、gitは各ユーザが持つローカルのリポジトリに対してコミットを行います。
gitでは、ローカルのリポジトリの内容を中央のリポジトリに反映したり、他のユーザが持つリポジトリを取得したり反映したりできるので、あらゆる環境で分散して管理できます。ローカルにリポジトリがあるので、ノートPCを持ってどこでも開発することができますし、コミットしてもローカルリポジトリに反映されるだけなので、気軽に何度でもコミットできるのも便利です。そして、本当に必要な変更だけをマスターリポジトリに反映させて履歴に残すことができるのです。
しかし、gitはsvnに比べて自分が管理者になる必要がある分だけ覚えなければならない事も多く、コマンドも多くて複雑です。
このため、初心者にとって敷居が高いように感じられますが、svnに慣れていればそんなに難しいことはないと思います。
ここで、細かい操作方法の説明に入る前にsvnとgitの違いについて簡単に箇条書きにしてみました。
以下のsvnとgitの各番号はそれぞれ対応関係にあるものとします。
git
■svnとgitの操作方法
以下では、特定のタスクを行うコマンドを左側にsvn、右側にgitで示すことにしました。これらのコマンドはほぼ同じ動作をするものです。
また、説明を簡略化するために、以下のように文字を定義しておきました。
- DIL:作成するディレクトリ
- FILE:作成するファイル
- HOST:ホスト名
- PORT:ポート番号
- REPO:リポジトリを作成するディレクトリ
- REV:リビジョン番号
- URL:複製するリポジトリのURL
- USER:ユーザー名
リポジトリのURL形式
リポジトリは情報をファイルシステムツリーの形で保持します。
svnやgitではリポジトリにアクセスするための場所はURLによって表現され、以下のような形式があります。
・主なリポジトリのURL形式
リポジトリの作成
svnやgitリポジトリを作成する。これをやらないと何も始まらない。
svnの場合 gitの場合 $ svnadmin create [REPO] $ cd [REPO] $ git init git initコマンドを実行すると、カレントディレクトリに.gitディレクトリが作成され、gitリポジトリの管理ファイルがこの中に作成される。(なお、古いバージョンのgitの場合には、git init dbコマンドで実行するらしい。)
また、svnやgitでは以下のようなディレクトリを各プロジェクトのルートディレクトリ直下に作成する慣習になっている。
git
- branches/:svnのtrunk/やbranches/を兼ねたようなところ
- tags/:新バーションをリリースする時などにその時点でのスナップショットを保存しておくところ
gitにはtrunk/という概念はなく、branch間で主従関係を決めることでtrunk/(masterと呼ばれるベースになる主branch)の代わりを設けている。
リポジトリが複数プロジェクトを含む場合は、プロジェクトごとにレイアウトをインデックス化する。
モジュールの登録
新しいプロジェクトをリポジトリに登録する。
svnの場合 gitの場合 $ svn import [URL] $ git add . $ git commit
作業コピーの取り出し
作業コピーをリポジトリから取り出すためにはsvn checkout/git cloneコマンドを用いる。
svnの場合 gitの場合 $ svn checkout [URL] ([DIR]) $ git clone [URL] ([DIR]) 取り出し時にディレクトリをURLで指定する。また、作成するディレクトリ名を指定することもできる。
最新のリビジョンを取得するだけの目的でgit cloneコマンドを実行する場合は、「--depth」オプションで取得するリビジョン数を指定する。どのリポジトリからcheckout/cloneしたかは次のコマンドで分かる。
svnの場合 gitの場合 $ svn info $ cd [REPO] $ git remote -v svn infoコマンドはsvnにしかない機能(git infoコマンドはない)であり、gitにおけるリポジトリの各種設定の情報は.git/config内に記録される。したがって、gitでは.git/config内を調べる必要があるのだが、サブディレクトリにいる時には開くまでが面倒であり、ファイルの中身が多すぎてURLを見つけ出すのも大変である。そこで、git configのgetでURLを取得する。
$ git config --list
$ emacs ~/.gitconfig
[alias]
url = config --get [URL]
$ git urlあるいはもっと簡単に、git remoteコマンドでURLを表示することもできる。
このコマンドでは複数のリモートサーバーを設定していればそれら全てのURLが表示される。
作業コピーの状態表示
作業コピーに加えられた変更点を表示するためにはsvn status/git statusコマンドを用いる。
svnの場合 gitの場合 $ svn status $ git status 引数なしで実行するとツリー全体の変更を表示できる。
ここで、svn statusコマンドの出力の行頭5桁の意味は以下のようになる。
1桁目ー追加/削除/変更など
- ' ':no modifications
- 'A':Added
- 'C':Conflicted
- 'D':Deleted
- 'G':Merged
- 'I':Ignored
- 'M':Modified
- 'R':Replaced
- 'X':item is unversioned, but is used by an externals definition
- '?':item is not under version control
- '!':item is missing (removed by non-svn command) or incomplete
- '~':versioned item obstructed by some item of a different kind
2桁目ーファイルやディレクトリの属性
- ' ':no modifications
- 'C':Conflicted
- 'M':Modified
3桁目ー作業コピーのロック
- ' ':not locked
- 'L':locked
4桁目ー履歴付きの追加予告
5桁目ー作業コピーからブランチへのスイッチ
- ' ':normal
- 'S':switched
履歴の表示
ファイルやディレクトリの履歴を表示するためにはsvn log/git logコマンドを用いる。
svnの場合 gitの場合 $ svn log | less $ git log コミットログは新しいものから順に表示される。
また、ファイル名やディレクトリ名を指定して履歴を見ることもできる。
svnの場合 gitの場合 $ svn log [FILE/DIR] $ git log [FILE/DIR] 特定のファイル/ディレクトリをその過去のバージョンと比較する場合、どのバージョンのファイル/ディレクトリと比較するかはリビジョン番号で指定する。
作業コピーの変更点の差分表示
ファイルに加えられた変更点を調べるためにはsvn diff/git diffコマンドを用いる。
svnの場合 gitの場合 $ svn diff | less $ git diff また、リビジョン番号やURLを指定して変更点の差分を見ることもできる。
svnの場合 gitの場合 $ svn diff -r [REV] [URL] $ git diff [REV] [URL]
作業コピーの編集の取消
編集を取り消して最後にアップデートまたはコミットした内容に作業コピーを戻すためにはsvn revert/git checkoutコマンドを用いる。
svnの場合 gitの場合 $ svn revert [URL/REV] $ git checkout [URL/REV]
作業コピーの編集の反映
ファイル編集後に変更点をリポジトリに反映させるためにはsvn commit/git commitコマンドを用いる。
svnの場合 gitの場合 $ svn commit $ git commit -a $ git push [URL] git commit -aコマンドによりローカルリポジトリにコミットし(「-a」オプションにより変更が加えられたファイルを自動検出する)、その後にgit push [URL]コマンドにより他人のリポジトリにコミットする手順となる。
git pushコマンドにより自分の作業コピーの変更を他の作業コピーにも反映させる。また、以下のようなオプションを任意で指定することができる。
- --message(-m):ログメッセージの指定
- --file:ファイル名の指定
ツリーの変更
・アイテムの追加
ファイルやディレクトリを追加するためにはsvn add/git addコマンドを用いる。
svnの場合 gitの場合 $ svn add [FILE] $ git add [FILE] $ svn mkdir [DIR] $ git mkdir [DIR] ただし、svn addコマンドはファイルやディレクトリをリポジトリに追加予告するだけで、リポジトリへの登録はコミットで行われる。
ディレクトリを追加するにはmkdirコマンドでディレクトリを作成しておいてsvn add/git addコマンドで作成する方法とsvn mkdir/git mkdirコマンドで一気にやってしまう方法がある。・アイテムの削除
ファイルやディレクトリを削除するためにはsvn rm/git rmコマンドを用いる。
svnの場合 gitの場合 $ svn rm [FILE] $ git rm [FILE] ファイルの場合は作業コピーから直ちに削除されるが、ディレクトリの場合は削除予告されるだけである。
また、ディレクトリを削除するためには予めディレクトリの中身を空にしておく必要がある。・アイテムのコピー
新しいアイテムを作るためにはsvn copy/git copyコマンドを用いる。
svnの場合 gitの場合 $ svn copy [FILE] $ git copy [FILE]
・アイテムの移動
アイテムの移動または名前の変更を行うためにはsvn mv/git mvコマンドを用いる。
svnの場合 gitの場合 $ svn mv [FILE] $ git mv [FILE]
作業コピーの更新
他の作業コピーで行われたリポジトリの変更を自分の作業コピーに反映させるためにはsvn update/git pullコマンドを用いる。
svnの場合 gitの場合 $ svn update $ git pull 本当なら変更点の取り出し元リポジトリのURLを指定する必要があるが、svn checkout/git cloneコマンドで作成したリポジトリの場合、複製元リポジトリのURLが自動的に記録される。そのためsvn update/git pullコマンドを実行する場合は上記のように取り出し元リポジトリを指定しなくてもよいことになる。
また、
svnの場合 gitの場合 $ svn update -r [REPO] $ git checkout [REPO] $ svn update $ git checkout [現在のbranch] ファイルに対する変更は行頭に表示される1文字のコードで示される。
- A:Added
- D:Deleted
- U:Updated
- C:Conflict
- G:Merged
ブランチの作成・管理
・ブランチ情報の表示およびブランチの作成
現在のソースツリーを元に新たなブランチの作成を行うためにはsvn copy/git branchコマンドを用いる。
svnの場合 gitの場合 $ svn copy [trunkURL] [branchURL] $ git branch [branchFILE]
・ブランチの切り替え
操作対象とするブランチの切り替えを行うためにはsvn switch/git checkoutコマンドを用いる。
svnの場合 gitの場合 $ svn switch [branchURL] $ git checkout [branchFILE] なお、gitでは「-b」オプションにより新たにブランチを作成してそのブランチに切り替える作業をgit checkout -b [branchFILE]のように1つのコマンドで実行することができる。
・ブランチ履歴の表示
ブランチ履歴の表示を行うためにはsvn list/git show-branchコマンドを用いる。
svnの場合 gitの場合 $ svn list [branchDIR] $ git show-branch gitでは、前半の「---」までがブランチ履歴、「---」から後半が最近のコミット履歴を表している。ブランチを階層構造で表示し、「*」が付いている行が現在の作業ブランチとなる。
svnとgitのコマンド体系は似ているところがありますが、…
■各種機能
svnとの連携
今までsvnとgitを比較してきて、冒頭ではgitに移行した方がいい的な発言をしましたが、実は分散管理型VCSを利用する場合でも、成果物を共有する拠り所として中央管理型VCSが必要になります。例えば、svnのファイルロック機能は有効です。
- git-svngitには、gitリポジトリとsvnリポジトリを同期させるgit svnコマンドがある。マスターリポジトリとしてsvnを利用して、各自の作業を行うローカルリポジトリにgitを利用することにより、各自のローカルリポジトリを管理するツールを変更してもマスターリポジトリに影響を与えず、新しくツールを覚えたくない場合にはsvnクライアントを従来通りに利用することができる。Macportsでインストールする場合、普通にgit-coreをインストールしてもgit svnは有効にならないので、
$ sudo port install git-core +svn
とする必要がある。ここではこれ以上の具体的な利用方法についての説明は行わない。
GUIツール
- svn
- TortoiseSVN(http://tortoisesvn.net/downloads.html)GUIによるバージョン管理ができるWindows用のsvnクライアント。日本語化もされていて分かりやすい。
- git
- TortoiseGIT(http://code.google.com/p/tortoisegit/)TortoiseSVNのgit版クライアント。コマンドラインでの操作が基本となる。開発段階であるので実用的ではない?
- GitX(http://gitx.frim.nl/)GUIによるバージョン管理ができるOSX用のgitクライアント。開発段階であるので実用的ではない?
無料リポジトリ
- svn多数ありw
- git
■参考にしたページ
あとでまとめて更新しておきます。