Git とは・なぜ必要か
コードを書いていると、必ずこういう場面に遭遇します。「昨日まで動いていたのに、今日変えたらおかしくなった」「あの変更を元に戻したい」「別の機能を並行して作りたいが、完成前に本番に入れたくない」。
Git はこうした問題をすべて解決するためのバージョン管理システムです。
バージョン管理とは
ゲームに「セーブ機能」があるように、コードにも「いつでも過去の状態に戻れる」仕組みが必要です。昔ながらのやり方はこうでした。
// バージョン管理を知らない時代のファイル管理
main.java
main_20260601.java
main_バックアップ.java
main_最終版.java
main_最終版2.java
main_本当の最終版.java
// 何が最新か分からない
// どこを変えたか分からない
// 誰が変えたか分からない
Git はこの問題を解決します。変更の履歴をすべて記録し、いつでも過去の状態に戻せるようにします。チームで開発するときは「誰が、いつ、何を、なぜ変えたか」まで記録できます。
Gitの基本概念
Gitを触りはじめて最初に迷子になるのは、専門用語が一気に4つも出てくることです。ここで一度整理しておけば、以降の説明がすっと入ってきます。
- リポジトリ(Repository)
- プロジェクトのファイルと変更履歴をまるごと格納する場所。「レポ」と略されることが多い
- コミット(Commit)
- 変更内容を1つの記録として保存する操作。「セーブ」に相当する。コミットには作者・日時・メッセージが記録される
- ブランチ(Branch)
- 作業の「分岐」。本番コードに影響なく新機能の開発や修正ができる。後でメインに統合(マージ)する
- リモート(Remote)
- GitHubなどのサーバー上にあるリポジトリ。ローカルの変更をアップロード(push)して共有する
ローカルとリモートの関係
「push」「pull」という言葉だけを聞くと方向がイメージしにくいですが、図にすると単純な仕組みです。
// Gitのざっくりした構造
[あなたのPC(ローカル)] [GitHub などのサーバー(リモート)]
.git/ push → リモートリポジトリ
(変更履歴がここに入る) ← pull
作業中のファイル
ローカルで好きなだけ変更を記録し、準備ができたらリモートに送ります。チームメンバーはリモートから最新を取得できます。
Gitが入っているか確認する
# ターミナルで確認
git --version
# git version 2.xx.x と表示されればOK
# まだ入っていない場合(Ubuntu/WSL)
sudo apt install git
# 初回設定(名前とメールアドレスを登録)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
コミットには「誰が変更したか」が記録されます。チーム開発では誰の変更か一目で分かるよう、正確な情報を設定します。個人開発でも、GitHub と連携する場合はGitHubアカウントのメールアドレスを使うと履歴が紐付きます。
.gitignoreを読む——「記録しないファイル」を決める
AIが生成したプロジェクトを開くと、ほぼ必ず.gitignoreという名前のファイルが入っています。中身をよく見ずに放置している人も多いですが、これはGitの安全性に直結する重要なファイルです。
# .gitignore の例
__pycache__/ # Pythonの中間ファイル
venv/ # 仮想環境まるごと
node_modules/ # JavaScriptの依存ライブラリ
.env # パスワードやAPIキーが入る設定ファイル
*.log # ログファイル全般
.gitignoreは「このパターンに一致するファイルはGitの記録対象にしない」というルール一覧です。特に.envのようなパスワードやAPIキーを含む設定ファイルが記載から漏れていると、うっかりそれをGitHubに公開してしまう事故に直結します。AIが生成したプロジェクトを使うときは、機密情報を含むファイルが.gitignoreにきちんと入っているかを、コミットする前に自分の目で確認しましょう。
コンフリクト——2つの変更がぶつかったとき
チームでGitを使っていると、いつか必ず遭遇するのが「コンフリクト(衝突)」です。名前だけ聞くと怖い印象がありますが、起きている状況はシンプルです。
同じファイルの同じ場所を、2人(あるいは自分の別ブランチ)が別々に変更してマージしようとしたとき、Gitは「どちらを採用すればいいか判断できません」と止まります。これがコンフリクトです。
<<<<<<< HEAD
const greeting = "こんにちは";
=======
const greeting = "やあ";
>>>>>>> feature-branch
- <<<<<<< HEAD 〜 =======
- 今いるブランチ(自分側)の内容
- ======= 〜 >>>>>>> feature-branch
- 取り込もうとしている相手側のブランチの内容
解決するには、どちらか一方(または両方をうまく組み合わせた内容)を残し、<<<<<<<や=======などの記号ごと削除してから、あらためてコミットします。AIにコンフリクトの解消を手伝ってもらう場合も、両方の意図を伝えた上で「どちらを残すべきか」を最終判断するのは人間の役割です。
AIコードでよくあるはまりポイント
Gitそのものの仕組みを理解していても、AIと一緒に開発するようになってから増えた独特のはまりポイントがあります。
git add を忘れてコミットが空になる
ファイルを編集したのにgit commitしても変更が記録されていない——初心者が最初につまずくのがこれです。Gitではgit addで「次のコミットに含めるファイル」を選んでから、git commitで実際に記録する、という2段階の操作になっています。
git commitの前に必ずgit statusを実行する習慣をつけましょう。「Changes not staged for commit」と表示されているファイルは、git addされていないため、このままコミットしても含まれません。AIが提案したコマンドをそのまま実行する前に、この一手間を挟むだけでミスが大幅に減ります。
AIに勧められるまま force push してしまう
「リモートと履歴が食い違ってpushできません」というエラーに対して、AIがgit push --forceを提案してくることがあります。これはリモート側の履歴を強制的に上書きするコマンドで、チームメンバーが積み上げた変更を消してしまう危険があります。個人の作業ブランチであれば問題ないことが多いですが、mainやmasterのような共有ブランチに対しては安易に使うべきではありません。エラーの原因(誰かが先にpushしていないか)を確認せずに実行しないよう注意しましょう。
もっと深く知りたい人へ・個別テーマの記事一覧
ここまでの内容はGitの土台となる基本概念です。実務で使う場面が多い個別の操作については、それぞれ1本ずつ独立した記事にまとめています。
- ブランチとプルリクエスト — fast-forward・マージコミット・squashという3種類のマージと、コードレビューの読み方
- git rebase — 分岐点を付け替えて履歴をまっすぐにする仕組みと、共有ブランチでは使ってはいけない理由(Golden Rule)
- git stash — コミットするほどでもない変更を一時退避する方法と、pop・apply・dropの使い分け
- git reset と git revert — --soft/--mixed/--hardの違いと、共有履歴を安全に取り消す方法
- git reflog — HEADの移動履歴から、消えたと思ったコミットを復元する方法
- git log — --oneline/--graphによる俯瞰と、コードの中身そのもので検索するpickaxe検索
- コミットメッセージの書き方 — 「なぜ」を書く重要性と、Conventional Commitsという共通ルール
- git cherry-pick — 特定のコミットだけを別のブランチに移植する方法と、重複コミットの落とし穴
- git blame — 各行の最終変更者を追う方法と、一括整形コミットに埋もれてしまう問題への対処