Chapter 1.1 - Fundamentals - Version Control
Introductionでも触れた通り、Gitは バージョン管理システム(VCS, Version Control System) の一つです。
VCSを利用する最大のメリットは ファイル毎の変更履歴を追跡できること 、そして 複数人でも変更とその追跡が可能であること にあります。
「変更を保存したファイルを変更前の状態に戻したい」といったようなケースにおいて最も簡単にそれを実現する方法というと、下の図のようにファイルのバックアップを作成しそれぞれに日付やインデックスを付与するといったようなものがありますが、これは手間が掛かる上に間違いが発生しやすく、ファイルの命名に一貫性を持たせないとすぐにディレクトリの秩序も乱れてしまいます。
では、Gitを利用するとどうでしょうか。
Gitは一つのリポジトリ (repository) で一つのディレクトリ(と、そのディレクトリが含むファイルとサブディレクトリ全て)の変更履歴を追跡することができます。
変更 (commit) の履歴はrepositoryに記録されていき、それぞれにSHA-1によって生成されたハッシュ値 (commit id) が付与されます。ユーザーはこのcommit idをもとにcommitのログを参照し、「いつ・誰が・何を・どのように・どうしたのか」を任意のタイミングで確認することができるわけです。
repositoryに蓄積されたこれらのcommitの情報は、ユーザーが任意のタイミングでそれらを確認することができるのと同時に、ディレクトリ(後述のworking directory)にその内容を反映させることができます。過去のcommitの情報を参照・反映させることによって、変更してしまったファイルを元に戻すことも、消してしまったファイルを復元させることでさえも可能となるのです。
具体的な例としては、
rm -rf *.hoge
などのコマンドを実行したときに、意図しないファイルまで消えた場合に容易に復元できる- 削除でなくても、複数のファイルに対する変更を復元によって取り消しできる
- 数日分の実装を無かったことにして元に戻せる(数commit分さかのぼって復元できる)
などがあります。
How does Git generate unique id ?
commit idの生成に使われているハッシュ関数のSHA-1は、入力された文字列 (キー) から20バイトのハッシュ値を生成するハッシュ関数で、Gitの場合はその生成に使うキーとしてrepository内のデータベースに格納するコンテンツにヘッダーを付加した文字列を入力します。SHA-1によって生成されたハッシュ値は重複することがないので、上記の通り特定のcommitを参照するためのcommit idとして使われます。
Various VCSs
バージョン管理システムは、リポジトリの管理方法によって 分散型バージョン管理システム(DVCS) と 集中型バージョン管理システム(CVCS, Centralized Version Control System) に分けられます。
CVCSは、リモートサーバーに置かれたrepository (remote repository, remote) に対して直接変更履歴を記録します。
Apache Subversion(SVN)やConcurrent Versions System(CVS)などはこのCVCSの一種で、各ユーザーはworking directory内でファイルに対して加えられた変更を直接remote repositoryにcommitすることによってバージョン管理を行います。
CVCSはcommitとupdateの操作にremote repositoryが置かれているサーバーへの接続が必要なので、そのサーバーに接続できないような環境ではremote repositoryに対するcommitや最新のcommitの取得ができなくなってしまいます。
一方DVCSでは、CVCS同様にサーバーに置かれたremote repositoryの他に、各ユーザーのコンピュータ上にローカルリポジトリ (local repository, local) が保持されます。
各ユーザーのコンピュータ上にあるlocal repositoryはサーバー上にあるremote repositoryの複製 (clone) であり、サーバーに接続可能な状況下においてlocalからremoteへ push 、もしくはremoteからlocalに pull することによってその同期を図ります。
DVCSではユーザーはサーバーに接続可能か否かに関わらずlocal repositoryに対してcommitをして、サーバーに接続可能な任意のタイミングでlocal repositoryの内容をremote repositoryに反映 (push) することができ、また同様に他のユーザーがremote repositoryに対して反映させたcommitを自分のlocal repositoryに反映 (pull) することができます。
この、 「各ユーザーのコンピュータ上にrepositoryが存在する」 というのがDVCSが分散型たる所以であり、CVCSには無いような以下のメリットがあります。
- サーバー上のremote repositoryにアクセス出来ない状況でもcommitやcommitのログ参照ができる
- サーバーが壊れたとしても、いずれかのlocal repositoryを複製してremote repositoryを復元することができる
- ブランチ (branch) というシステムを利用できる ※後のchapterで解説します
bare or non-bare
先ほどは一口に"repository"と説明しましたが、実は厳密にはrepositoryとは2つのものを指します。
一つは、 bare repository。先ほど述べた、commit履歴などの情報が保管されているrepositoryのことです。bare repositoryにはrepositoryの管理用情報しか含まれておらず、原則ユーザーはbare repositoryの中で作業をすることはできません。Gitではgit init
コマンドを実行したときにworking directoryのroot直下に生成される、.git
というディレクトリがこのbare repositoryに相当することになります。
もう一つは、 non-bare repository。Gitでは先述のbare repository(.git
)を含んだworking directoryのディレクトリツリーそのものを指してnon-bare repositoryと呼び、Gitにおけるlocal repositoryは普通はこの形で運用されることになります。こちらはbare repositoryとは違い、ユーザーがその中でファイルのcommit、branchに対する操作などを行うことができます。
bare repositoryとnon-bare repositoryの違いに関してあまり神経質になる必要はありません。厳密に使い分ける必要は特にありませんが、認識としてbare repository(.git
)とnon-bare repository(local repository)を混同しないように気をつけましょう。
この資料では一応2つのrepositoryを区別するために、bare repositoryを git repository、non-bare repositoryを local repository と呼称することにします。
バージョン管理の概念をすぐに理解することは中々簡単なことではないかもしれませんが、本頁を何度も読み返すなり講師に質問するなりしてバージョン管理の基本概念をきちんと理解できるように頑張りましょう。
次の Chapter 1.2 では、Gitのシステムや特有の概念などをコマンドの例などを交えながら解説していきます。