Git・開発の進め方の用語
コードの変更を記録し、安全に進めるための言葉。失敗から復旧するための道具も含む。
それぞれ「なぜそれがあるのか」と「つまずきやすい点」まで書いています。実際にこのサイトを作る中で出てきた具体例も入れました。
コミット / ステージ / ハッシュ / ブランチ / プルリクエスト / マージ / リポジトリ / index.lock / git stash / git reset / CI / reflog
コミット(こみっと)
変更内容を、説明を添えて履歴に記録すること。またはその記録そのもの。
変更内容を説明を添えて履歴に記録することです。記録されたもの自体もコミットと呼びます。
なぜこまめに行うのか
Gitで本当に失われるのは、コミットしていないものだけです。逆に言えば、コミットさえしてあれば、たいていの失敗は取り返せます。
危ない作業の前にコミットを1つ挟むのは、いちばん安いお守りです。
注意したいこと
コミットに意図した変更が全部入っているかを確認する習慣が要ります。実際に、5ファイル直したはずのコミットに2ファイルしか入っていないまま公開してしまう、という失敗が起こり得ます。
この状態でもビルドは通り、デプロイも成功します。ファイル数を数えるだけで、事前に気づけます。
ステージ(すてーじ)
次のコミットに含める変更を、一時的に選んで置いておく場所。
Gitがファイルを管理している3つの場所のうちの真ん中で、「次のコミットに含めると決めたもの」を置いておく場所です。インデックスとも呼ばれます。
作業ツリー →(add)→ ステージ →(commit)→ 履歴
編集中 準備中 記録済み
なぜ間に挟まっているのか
いま編集しているものすべてを、必ず一緒に記録したいとは限りません。複数の変更を、意味ごとに分けてコミットできるようにするための仕組みです。
実務での効き方
ステージにあるものと、まだ入っていないものは、状態表示で区別できます。コミット前にここを確認すると、意図しないファイルが混ざっていることに気づけます。
ハッシュ(はっしゅ)
どんな長さのデータも決まった長さの値に変換したもの。一致の確認に使う。
どんな長さのデータでも、決まった長さの値に変換したものです。同じ入力からは必ず同じ値が出て、1文字でも違えばまったく別の値になります。
何に使えるのか
2つのものが同じかどうかを、中身を比べずに確かめられます。
手元のファイル → 変換 → 3209980085
本番のファイル → 変換 → 558273598
↑ 違う = 中身が違う
数万文字を1文字ずつ見比べるのは現実的ではありません。1つの値に潰してしまえば、一致するかどうかだけを見れば済みます。
Gitでの登場
コミットに付いている c5ce23e のような文字列も、この値です。変更内容から計算されるので、内容が違えば別のコミットとして区別されます。
注意
変換は一方通行です。値から元の中身は取り出せません。一致の確認には使えますが、復元には使えません。
ブランチ(ぶらんち)
本流から分岐した作業用の系統。本番に影響を与えずに作業できる。
本流から枝分かれさせた作業用の系統です。ここでいくら変更しても、本流には影響しません。
なぜ分けるのか
本流で直接作業すると、壊れていた場合に「戻す」しか選択肢がありません。ブランチなら、本番を触らないまま作業を進められます。
デプロイ先によっては、ブランチごとに確認用のURLを作ってくれます。本番と同じビルドで動作を確かめてから、本流に取り込めます。確認の機会を1回増やすだけで、事故の大きさが変わります。
運用の目安
1つのブランチでは1つの目的だけを扱います。ライブラリの更新と機能追加を混ぜると、何か起きたときに原因を切り分けられなくなります。
役目を終えたブランチは削除します。-d での削除は取り込み済みのものしか消さないので、安全な確認としても機能します。
プルリクエスト(ぷるりくえすと)
ブランチの変更を取り込んでほしいと提案する仕組み。レビューと確認の場になる。
「このブランチの変更を取り込んでください」と提案する仕組みです。GitHubでの呼び名で、PRと略されます。
1人で開発していても役に立つ
レビューのための仕組みと思われがちですが、1人でも価値があります。
変更の一覧が見える形になり、自動テストやビルドの結果が集まり、確認用のURLが用意されます。「取り込む前に立ち止まる場所」ができること自体が効きます。
使い方の目安
タイトルには何をしたかを、説明にはなぜそうしたかを書きます。半年後に読み返したとき、判断の理由が残っていると助かります。
マージ(まーじ)
別のブランチの変更を、いまのブランチに取り込むこと。
あるブランチの変更を、別のブランチに取り込むことです。作業用ブランチで完成したものを本流に入れる場面で使います。
コンフリクトとは
両方のブランチで同じ場所を違う内容に変えていた場合、Gitはどちらを採用すべきか判断できません。この状態をコンフリクト(衝突)といいます。
このときGitは作業を止めて、人に判断を求めます。勝手にどちらかを選ばないのは、意図しない上書きを防ぐためです。
減らすコツ
ブランチを長く放置しないことです。分岐している期間が長いほど、本流との差が広がり、衝突する確率が上がります。小さく作って早く取り込むほうが、結果的に楽になります。
リポジトリ(りぽじとり)
ソースコードと、その変更履歴をまとめて保管する場所。
ソースコードと、それがどう変わってきたかの履歴をまとめて保管する場所です。「リポ」と略されることもあります。
ファイルのフォルダと何が違うのか
通常のフォルダは「いまの状態」しか持ちません。リポジトリは「いつ、誰が、何を、なぜ変えたか」を全部保持しています。
そのため、過去のどの時点にも戻れますし、ある1行がいつ書かれたのかも追えます。
手元とリモート
自分のパソコンにあるものと、GitHubなどのサーバーにあるものは別々のリポジトリです。片方を変えても、もう片方には自動では反映されません。
この「別々である」という前提を理解しておくと、pushが拒否される理由やpullが必要な理由が自然に分かります。
index.lock(インデックスロック)
Gitが操作中に作る目印のファイル。残ったままだと、以後の操作が全部止まる。
Gitが操作のたびに作る「いま作業中です」という目印のファイルです。.git/index.lock に作られ、終わると消えます。
なぜ止まるのか
何らかの理由でこのファイルが消し損ねられると、Gitは以後すべての操作を拒否します。本当に別のプロセスが動いている可能性があるからです。
fatal: Unable to create '.git/index.lock': File exists.
対処
他でGitを動かしていないことを確認してから、このファイルを削除します。0バイトで中身が無く、Gitのデータは一切入っていません。単なる目印なので、消しても情報は失われません。
起きやすい状況
同じリポジトリを複数の経路から触っているときに起きます。片方に書き込み権限が足りないと、作れたのに消せない、という状態になります。.git は排他制御を前提にしているので、複数経路からの同時操作は避けるべきです。
git stash(ギットスタッシュ)
作業中の変更を一時的に退避し、あとで戻せるようにするコマンド。
作業中の変更を一時的に脇へ置いて、作業ツリーをきれいにするコマンドです。あとで戻せます。
いつ使うのか
作業の途中で別のブランチに移りたいとき、最新の変更を取り込みたいとき。捨てたくはないが、いまは邪魔という場面です。
知っておくべき落とし穴
既定では、Gitがまだ知らない新規ファイルを退避しません。そのまま取り込み作業をすると「未追跡のファイルを上書きすることになるので中断する」と止められます。
-u を付けると新規ファイルも含まれます。この一手間を知らないと、原因が分かりにくい形で止まります。
運用のコツ
退避したものにはメモを付けられます。溜まると何が何だか分からなくなるので、いつ・なぜ退避したかを書いておくと後で助かります。
git reset(ギットリセット)
履歴を巻き戻すコマンド。–hard を付けると未コミットの変更が消える。
履歴を巻き戻すコマンドです。「取り消し」ではなく「破棄」だと理解しておくのが安全です。
| 指定 | 作業中の編集 |
|---|---|
--soft |
残る |
| 指定なし | 残る(ステージから降りる) |
--hard |
消える。戻せない |
なぜ危ないのか
コミット済みの変更は履歴にあるので取り戻せます。しかし未コミットの編集は履歴に無いので、履歴から復元できません。当たり前のことですが、この当たり前が事故になります。
使い分け
「一旦きれいにしたい」「ブランチを切り替えたい」という理由なら、その用途は git stash です。捨てずに退避してくれます。
また、すでに公開した変更を戻すときは git revert を使います。resetで消すと他の人の履歴と食い違います。
CI(シーアイ)
コードを変更するたびに、自動でビルドやテストを実行する仕組み。
Continuous Integration(継続的インテグレーション)の略。コードを変更するたびに、自動でビルドやテストを走らせる仕組みです。
何が変わるのか
壊れたことにすぐ気づけます。まとめて確認する運用だと、どの変更が原因かを探すところから始まります。
組み合わせると効くもの
脆弱性の検知、リンクの死活監視、サイトの応答確認。定期的に自動で回して、問題があれば通知する仕組みを作れます。
ただし、通知先が見られていないと意味がありません。気づける場所に届けるところまで設計する必要があります。
限界も知っておく
CIが緑なのは「壊れていない」証明であって、「意図した通りになっている」証明ではありません。変更が入っていなければ、当然すべて通ります。
関連記事: 公開したあとの話 — 脆弱性検知と監視の仕組みを作る
reflog(リフログ)
自分がGitに対して行った操作の履歴。消えたはずの変更を探す手がかりになる。
コミットの履歴ではなく、「自分がGitに何をしたか」の履歴です。checkout、reset、pull、commit——すべて記録されています。
いつ役に立つのか
「変更が消えた」「いつのまにか違うブランチにいる」というとき、まずこれを見ます。何が起きたかを推測せずに済みます。
c5ce23e HEAD@{0}: commit: ...
682faf3 HEAD@{1}: reset: moving to HEAD ← ここで何かした
682faf3 HEAD@{2}: pull: Fast-forward
復旧にも使える
「間違ってリセットしてしまったコミット」も、reflogに残っていれば戻せます。コミットしてありさえすれば、見た目上消えても回収できることが多いです。
ただし記録は永久ではなく、既定では数十日で消えます。