この投稿は インタープリズムの面々が、普段の業務に役立つ記事を丹精込めて書き上げる! Advent Calendar 2016 - Qiitaの11日目 の記事です。
はじめに
当社でもgitユーザー(=ファイル履歴管理にgitを使う社員)が半分を超えてきました。 新人研修も2015年以降、成果物の管理をsvnからgitに切り替えて行うようになりました。 svnの説明は比較的に簡単にできるし、説明を受ける側も比較的に簡単に理解しているように見受けられるのですが、gitは一回の説明では、なかなか理解してもらえないことが多いように感じます。
そこで、今回はsvn,gitについて超絶簡単にまとめることで、新たにgitを説明する際の資料として利用しようかなと思っています。
前提知識
一応、svnの説明も行いますが、前述のとおりsvnの説明で躓くことはあまりないので、丁寧な説明は行いません。 svnはある程度理解できるけど、gitの理解で躓く人にsvnの対比によってgitを理解してもらうことをこの記事の主な目的としています。
バージョンコントロールシステム、リポジトリ
(ファイル)バージョンコントロールシステム(以後vcs)とは、特定のフォルダ以下のフォルダ構成ならびにファイルの状態を履歴管理するためのシステムです。
また、その履歴情報を管理する機能をリポジトリと呼びます。
svnもgitもvcsの一種です。できることは概ね同じですが、gitの方がsvnよりも後発な分だけ、より高機能(svnも十分高機能なので、正確には、設計ポリシーの違いかもしれません)なシステムになっています。
svn
まずはsvnから。
開始手順は以下のとおりです。
- サーバーにsvnのサーバー環境を構築
- サーバーにsvnリポジトリの作成
- クライアントでリポジトリ内の特定のフォルダをチェックアウト(checkout)
- クライアントでチェックアウトしてきたフォルダ内でファイルを新規に作ったり、編集したり、削除したり、フォルダ構成を変更したりする
- コミットしてクライアントの変更をサーバのリポジトリに反映させる(commit)
図示すると以下のとおりとなります。
その後、他の人のcommit(変更)を取り込みながら、ファイルの編集を進めていくときの大まかな作業は以下のようになります。
- サーバーから最新の状態を取得(update)
- ファイルやフォルダの編集
- 変更をサーバーに反映(commit)
git
svnの対比でgitを説明します。 svnと比較した時のgitの一番の特徴はサーバーにあったリポジトリがクライアントに来るということではないかと思います。 まずは、アーキテクチャの比較がわかりやすいと思うので、まずは図解します。
このように、一見複雑そうに見えるgitも要約して考えると サーバーにあるリポジトリをまるごとローカルに持ってきて、まずはそのローカルリポジトリにコミットして、変更されたリポジトリとサーバー上のリポジトリの同期をとる だけのことです。
従って、開始手順は以下のようになります。
- サーバーにgitのサーバー環境を構築
- サーバーにgitリポジトリの作成
- サーバーに作ったリポジトリをローカルにコピー(clone)
- クライアントのフォルダ内でファイルを新規に作ったり、編集したり、削除したり、フォルダ構成を変更したりする
- コミットしてクライアントの変更をローカルのリポジトリに反映させる(commit)
- ローカルリポジトリをサーバのリポジトリに反映(push)
その後、他の人のcommit(変更)を取り込みながら、ファイルの編集を進めていくときには、以下のルーチン作業を行うようになります。
- サーバーから最新のリポジトリの状態をクライアントのリポジトリに反映(pull)
- ファイルやフォルダを編集
- ローカルリポジトリに変更を反映(commit)
- ローカルリポジトリをサーバリポジトリに反映(push)
細かいこと言い出すと切りがないし、結局初心者を惑わすだけなので、まずは上記をしっかりと理解することが重要ではないかと思っています。
ブランチ、リベース、マージ
ここからは、少し中級者向けの記事になります。 基本的に上記の作業をする限りにおいては、svnもgitもほとんど違いを感じません。では何のためにgitが生まれたのでしょうか。gitがその威力を最も発揮するのはブランチ作業においてだと思っています。
vcsにおいて、ブランチとは、一本に繋がった履歴の派生系のことです。コミットの度に履歴(=リビジョン)が管理されるのですが、ある時から、その履歴を2つに枝分かれさせて、二本の履歴を管理していきたくなるときがあります。(いろんなケースがありますが、その例が思い浮かばない人はまだこの記事を読む時ではないかもしれませんw)
そんな時に使うのが ブランチ です。
樹 に相当する部分をsvnではtrunk、gitではmasterと呼びますが、システム的には、trunk、masterもブランチの一種であり、本来は他のブランチと等価なものですが、基本的にブランチは枝分かれしていく特性上、発散しやすいので、やはり 樹 という概念が必要なため、trunk、masterは特別な扱いをします。
枝分かれして作業していて、樹の変更分を取り込みたくなる時があります。そんな時に、枝分かれポイントを変更する作業をリベースといいます。
ブランチにより枝分かれしたものを樹に反映させることをマージ(merge)と呼びます。(ブランチどうしのマージもありですが、説明を単純にするためにあえてこのような表現をしています!)
このブランチ、リベース、マージ作業をする際に、gitは圧倒的に有利になっていると思っています。
svnとgitのブランチ作業の違い
一言で言ってしまえば、gitの場合、リポジトリがローカルにあり、まずはローカルリポジトリに対して、いろいろな操作を行い、まとめてサーバのリポジトリと同期をとるため、 圧倒的にパフォーマンスがよい という特徴が挙げられると思います。
svnの場合、樹からブランチにブランチから樹に作業を切り替えるには、改めてサーバーからブランチもしくは樹のファイルをまとめて取得し直さなければならず、リポジトリが大きくなってくるとその切替時間を持っていられなくなってしまうため、どうしてもブランチを作成することに慎重になってしまいます。
その点gitの場合リポジトリはローカルに存在しており、サーバーとの同期で差分を取り込むだけなので、基本的に ブランチの切り替えは極めて高速に処理される ことになるため、気軽にブランチを作成したりリベースすることができます。
個人的な経験からも、svnの時には、アプリケーションのメジャーバージョンアップをして、それぞれのバージョンで開発単位を分ける時ぐらいにしかブランチは作成しませんでしたが、gitを使うようになると、原則的に 個人の作業は全て新たにブランチを作成して行い 、それをマスター(樹)に反映させていくスタイルに変わりました。
最後に
以上、本当にざっくりしたsvn、gitの概念の解説でした。細かい機能の説明はググってもらえれば、いくらでもあると思いますので、そちらにおまかせしたいと思います。
インタープリズムの面々が、普段の業務に役立つ記事を丹精込めて書き上げる! Advent Calendar 2016 - Qiitaの12日目の記事