Gitとは? バージョン管理のしくみとGitHubとの違い
バージョン管理とは、ファイルの変更を「いつ・誰が・何を・なぜ」と一緒に記録し、前の状態に戻せるしくみです。代表のソフトがGitで、その時点の全体の写し(コミット)を順につなぎ、枝分かれ(ブランチ)で並行して作業できます。GitHubはGitではなく、Gitの保管場所を預かり、チームでの確認を助けるWebのサービスです。
この記事でわかること
- バージョン管理で何が変わるか
- コミット・履歴・ブランチ・マージ・コンフリクトの意味
- 集中型(Subversion)と分散型(Git)の違い、GitとGitHubの違い
- プルリクエストとレビュー、Gitが中身を見分けるしくみ(ハッシュ値)
- パスワードやAPIキーをコミットしてはいけない理由
前提知識: 特にありません。パソコンでファイルを保存したり、フォルダに分けたりしたことがあれば読めます。
身近なところでは
共有フォルダに、こんなファイルが並んでいるのを見たことはないでしょうか。「企画書.docx」「企画書_最終.docx」「企画書_最終_v2.docx」「企画書_最終_v2_最新.docx」。どれが本当の最新なのか、v2で何を直したのか、名前からはわかりません。
2人が同じファイルを別々に開いて直すと、もっと困ります。後から保存した人が、先の人の修正を消してしまうからです。
ソフトウェアの開発では、これが桁違いの規模で起きます。何千ものファイルを、何十人もが同時に書き換えることもあります。そこで使われているのが「バージョン管理」のしくみです。
バージョン管理とは: 変更の記録を残すしくみ
Gitの公式サイトで公開されている解説書『Pro Git』は、バージョン管理を次のように説明しています。ファイルへの変更を時間を追って記録し、後で特定の版を呼び出せるようにするしくみ。版は「バージョン」ともいい、そのためのソフトを「バージョン管理システム」と呼びます。
日付つきのフォルダにファイルを写す方法は簡単ですが、『Pro Git』は誤りやすいと書いています。違うフォルダのファイルに上書きしやすいからです。バージョン管理システムなら、どの変更を誰がいつ入れたかもわかり、問題の原因探しにも役立ちます。
代表的なソフトがGit(ギット)です。主な対象はプログラムですが、文字で書かれたファイルなら同じように管理できます。半導体チップの回路も、文章のような形で書いて設計することが多くあります(「コンパイラとは?」)。
しくみ① コミット: 説明つきの「その時点の写し」
Gitで記録を残す単位を「コミット」と呼びます。1つのコミットは、その時点のファイル全体の写しです。これに「誰が」「いつ」と、変更の理由を書いた短い文(コミットメッセージ)がつきます。
実際には、変わらなかったファイルは前に保存したものを指すだけにして、場所を節約します。ここでは話を簡単にするため、「全体の写しが残る」と考えます。
大事なのは、コミットはファイルの保存とは別の操作だという点です。ファイルを何度保存しても、自動でコミットされることはありません。「見出しを直した」のように、意味のあるまとまりができたところで、自分でコミットします。
しくみ② 履歴: 前の版を見る、戻す、比べる
コミットは、1つ前のコミットがどれかを覚えています。そのため、コミットをたどると、最初から今までの変更が一本の流れとして並びます。これを「履歴」と呼びます。
履歴があると、2つの版の違いだけを取り出して見られます。この違いを「差分」と呼びます。1,000行のファイルのうち3行を直したなら、その3行と前後の数行だけが示されます。
前の状態に戻すこともできます。ファイル1つだけでも、全体でも戻せます。チームで共有した後の取り消しは、「前の変更を打ち消す変更」を新しいコミットとして足すのが基本です。履歴を消さないので、「いつ、なぜ戻したか」も記録に残ります。
得意なのは、文字で書かれたファイルです。Wordの文書や画像も保存はできます。ただ、そのままでは差分が「中身が違う」としか表示されません(『Pro Git』8.2節)。
しくみ③ ブランチとマージ: 枝分かれして、合流する
新しい機能を作っている途中のファイルは、動かないことがあります。それを本流に入れると、ほかの人の作業まで止まってしまいます。そこでGitでは、履歴を枝分かれさせて、本流に影響を与えずに作業を進めます。
この枝分かれを「ブランチ」(枝)と呼びます。中身は、ある流れの一番新しいコミットを指す、名前のついた目印です。ファイルを丸ごと複製しないので、すぐに作れて場所もとりません。本流のブランチには、main や master という名前がよく使われます。
機能ができあがったら、ブランチの変更を本流に取り込みます。これを「マージ」(合流)と呼びます。Gitは、枝分かれした地点から両方で何が変わったかを比べます。別々の場所の変更なら、自動で両方を組み合わせます。
Gitの命令は、例えば次のような形です。画面のボタンで同じことをする道具もよく使われます。
| 命令の例 | 意味 |
|---|---|
| git commit -m "見出しの誤字を直す" | 選んだ変更を、説明をつけてコミットする |
| git log --oneline | 履歴を1コミット1行で表示する |
| git switch -c new-feature | new-feature(新機能)というブランチを作って移る |
| git merge new-feature | new-feature の変更を、今いるブランチに合流させる |
しくみ④ コンフリクト: 同じ場所を別々に直したとき
自動で組み合わせられないこともあります。2つのブランチで、同じファイルの同じ部分が、別々の内容に書き換えられていた場合です。例えば、Aさんは会議の時刻を「10時」に、Bさんは「11時」に直していたとします。
どちらが正しいかは、Gitには判断できません。そこでGitは、勝手にどちらかを選ばずにマージを止めます。ファイルのその部分には、両方の内容が並べて示されます。区切りには「<<<<<<<」などの印がつきます。この状態を「コンフリクト」(衝突)と呼びます。
直すのは人の仕事です。2人で相談して正しい内容に書き直し、印を消してからコミットします。コンフリクトは故障ではなく、「人が決めるべき食い違い」の知らせです。こまめに合流させると起きにくくなります。
集中型と分散型: SubversionとGit
バージョン管理システムには、大きく2つの型があります。1つ目は、履歴をすべて1台のサーバに置き、各自がそこから最新の版を取り出して作業する型です。これを「集中型」と呼びます。代表はSubversion(サブバージョン)で、2000年に開発が始まりました。公式サイトも自らを集中型と紹介しています。
集中型は、全員が同じ場所を見るので、管理しやすいのが利点です。一方で、『Pro Git』は弱点も挙げています。サーバが止まっている間は、誰も記録を残せません。サーバのディスクが壊れ、控えもなければ、履歴をすべて失います。このように、1か所止まると全体が止まる場所を単一障害点と呼びます。
2つ目が、Gitの「分散型」です。各自のパソコンに、最新の版だけでなく、履歴の全部を写して持ちます。そのため、コミットや履歴を見る操作のほとんどは手元で済み、ネットワークがなくても作業できます。どの人の写しも、全データの控えになります。
版の呼び方も違います。Subversionでは、版に1、2、3と通し番号がつきます。各自がばらばらにコミットするGitでは番号を決められないので、中身から計算した値を使います。
Gitが生まれたいきさつ
Gitは、OSのLinux(リナックス)を開発するために生まれました。『Pro Git』によれば、1991〜2002年、Linuxの変更は差分や圧縮ファイルの形でやり取りされていました。2002年からは、ある会社の分散型の製品BitKeeperを無料で使うようになります。
2005年、Linuxの開発者たちとその会社の関係がこじれ、無料で使えなくなりました。そこでLinuxを作ったリーナス・トーバルズを中心に、自分たちの道具を作りました。それがGitです。目標には、速いこと、何千もの枝分かれを並行して扱えることなどがありました。
リモートリポジトリと、GitHub・GitLab
Gitで、ファイルと履歴の全部をしまっておく場所を「リポジトリ」(保管庫)と呼びます。自分のパソコンにあるものは手元のリポジトリです。チームで共有するために、サーバに置いたリポジトリを「リモートリポジトリ」と呼びます。
手元でコミットしただけでは、ほかの人には見えません。git push という命令でリモートに送り、ほかの人は git pull で取り込みます。送るまでは、手元で何度でもコミットを重ねられます。
リモートリポジトリを預かるサービスの代表が、GitHub(ギットハブ)やGitLab(ギットラボ)です。GitHubは自らを「コードを保管し、共有し、ほかの人と一緒に書くためのクラウドのプラットフォーム」と説明しています。GitLabは、リポジトリの管理にレビューや自動テストの機能を加えた製品で、自社のサーバに置いても使えます。
つまり、Gitは手元で動くソフト、GitHubやGitLabはGitの保管場所を預かるサービスです。Gitは社内のサーバだけで使うこともできます。
プルリクエスト: 合流の前に見てもらう
チームの開発では、自分のブランチを勝手に本流へマージしないのがふつうです。その前に、「この変更を本流に入れてください」という提案を出します。GitHubではこれを「プルリクエスト」、GitLabでは「マージリクエスト」と呼びます。
提案の画面には、変更の差分と説明が並びます。ほかの人は差分を読んで気になる行にコメントし、出した人は直してコミットを足します。この確認を「コードレビュー」と呼び、了承が得られたらマージします。
提案のたびに、テストを自動で走らせる設定もよく使われます。変更をこまめに本流へ統合し、そのたびに自動で確かめる進め方を、継続的インテグレーション(CI)と呼びます。
Gitは中身をどう見分けている?
Gitは、保存するファイルの中身から、決まった長さの値を計算します。同じ中身からは必ず同じ値が出て、1文字でも違えばまったく別の値になります。この計算をハッシュ関数、出てくる値をハッシュ値と呼びます。
Gitが標準で使うハッシュ関数はSHA-1で、値は0〜9とa〜fの40文字で表されます。次の表は、1文字だけ違う2つのファイルについて、Gitと同じ方法で計算した値の先頭10文字です。
| ファイルの中身(最後に改行1つ) | ハッシュ値(先頭10文字) |
|---|---|
| 会議は10時から | d7a6150543… |
| 会議は11時から | 3eec220ecf… |
Gitは、この値をファイルやコミットの名前として使います。中身が同じなら名前も同じなので、同じものを2回しまわずに済みます。保存した中身が壊れても、計算し直した値が名前と合わなくなるので気づけます。
コミットの名前も同じ方法で決まります。コミットには、1つ前のコミットの名前も書き込まれています。そのため、過去のコミットを1つでもこっそり書き換えると、それより後のすべての名前が変わってしまいます。ふだんは先頭の7文字ほどに縮めて表示します。
暗号で使うハッシュ関数は、同じ値になる別のデータを作るのが、事実上できないように設計されています。通信の誤りを見つけるCRCとの大きな違いです。
ただ、SHA-1は2017年に、同じ値になる2つのデータを実際に作る攻撃が示されました。Gitはその攻撃を見破る工夫を加え、後継にSHA-256を選んでいます。2026年10月時点のGitの説明書では、標準はまだSHA-1です。次の大きな版のGit 3.0で、新しいリポジトリの標準をSHA-256に変える予定ですが、時期は決まっていません。
パスワードやAPIキーは、コミットしない
バージョン管理は「消えない」ことが強みです。ところが、これが裏目に出ることがあります。パスワードや、サービスを使うための秘密の鍵(APIキー)を、うっかりファイルに書いてコミットした場合です。
気づいてファイルから消し、もう一度コミットしても、前のコミットには残っています。リポジトリを見られる人なら、履歴をたどって取り出せます。GitHubの説明書も、履歴を書き換えても、ほかの人の写しなどに残りうると注意しています。
そのため、一度でも共有の場所に送った秘密は、漏れたものとして扱います。発行元でその鍵を無効にし、新しいものに取り替えるのが基本です。そもそも秘密はプログラムのファイルに書かず、別の場所に置きます。キーの守り方は「APIとは?」で説明しています。入れたくないファイルの名前を「.gitignore」に書くと、まだGitの管理に入れていないものは無視されます。
よくある誤解
誤解: GitとGitHubは同じもの
実際は、Gitは手元のパソコンで動くバージョン管理のソフトです。GitHubは、Gitのリポジトリを預かり、プルリクエストなどの共同作業の機能を加えたWebのサービスです。GitはGitHubがなくても使えます。名前が似ていて、一緒に使われることが多いので、混同されやすいのです。
誤解: コミットすれば、チームの全員に変更が届く
実際は、コミットは手元のリポジトリへの記録です。ほかの人に届けるには、git push でリモートリポジトリに送る必要があります。逆に、ほかの人の変更も、取り込むまでは手元に入りません。集中型のSubversionでは記録を残す操作がそのままサーバに届くので、同じ言葉から誤解が生まれやすいのです。
誤解: バージョン管理は、プログラマーだけの道具
実際は、ほとんどどんなファイルでも管理できます。『Pro Git』も、画像やレイアウトの版を残したいデザイナーに勧めています。ただし、Wordの文書などは差分が見えにくくなります。
数字で見る
| 項目 | 数字・時期 | メモ |
|---|---|---|
| Linuxの変更を差分や圧縮ファイルでやり取り | 1991〜2002年 | 『Pro Git』 |
| Subversionの開発の開始 | 2000年 | 集中型の代表 |
| Gitの誕生 | 2005年 | リーナス・トーバルズら |
| SHA-1のハッシュ値の長さ | 40文字(160ビット) | 0〜9とa〜fで表す |
| 縮めた表示の長さ | 7文字から | 見分けられないときは長くする |
| 偶然に同じ値が出る確率が半々になる数 | 約2の80乗(約1.2×10の24乗)個 | 『Pro Git』の見積もり |
| SHA-1で同じ値を作る攻撃の発表 | 2017年2月 | SHAttered |
| Gitが後継にSHA-256を選ぶ | 2018年後半 | 標準はまだSHA-1。Git 3.0で新しいリポジトリの標準にする予定(時期は未定、2026年10月時点) |
2の80乗は、1兆の1兆倍ほどの数です。偶然に同じ値が出る心配はまずなく、心配なのはわざと同じ値を作る攻撃のほうです。それがSHA-256へ移る理由です。
もっと詳しく学ぶ
- 次の一歩の用語: CI/CD、SSH、アジャイル開発、テスト駆動開発(TDD)
- 関係する記事: 「APIとは?」(秘密の鍵の守り方)、「暗号とは?」(ハッシュと暗号の違い)、「パスワードはなぜ破られる?」
- 土台から読む: 「コンパイラとは?」、「データベースとは?」、「クラウドとは?」