Git とは
Git は、ファイルの変更履歴を管理するためのツールです。
主に以下の用途で使われます。
- ソースコードの変更履歴を残す
- 変更前の状態に戻す
- 複数人で同じプロジェクトを開発する
- ブランチを使って作業を分ける
- GitHub / GitLab などのリモートリポジトリと連携する
Git の仕組み
.git/ ディレクトリ
Git 管理されているディレクトリには、基本的に .git/ ディレクトリがあります。
project/
├── .git/
├── README.md
├── src/
└── config/
.git/ の中には、以下のような情報が保存されています。
- コミット履歴
- ブランチ情報
- リモートリポジトリ情報
- ステージング情報
- Git の設定情報
つまり、
.git/ がある = Git リポジトリ
と考えるとわかりやすいです。
ただし、厳密には git worktree や submodule を使う場合、.git/ がディレクトリではなくファイルになっていることもあります。
通常の初心者向け理解としては「.git/ が Git 管理の本体」と考えて問題ありません。
Git はどこを管理するのか
Git は、.git/ があるディレクトリをリポジトリのルートとして扱います。
例えば、以下の構成があるとします。
project/
├── .git/
├── README.md
└── app/
└── main.py
この場合、Git は project/ 配下をまとめて管理します。
cd project/app
git status
のように、サブディレクトリ内で Git コマンドを実行しても、Git は親ディレクトリをたどって .git/ を探します。
そのため、基本的にはリポジトリ内のどこで Git コマンドを実行しても、そのリポジトリに対する操作になります。
用語集
リポジトリ
リポジトリとは、Git で管理されるプロジェクト単位のことです。
ソースコード、設定ファイル、ドキュメント、変更履歴などをまとめて管理します。
例:
my-app/
├── .git/
├── README.md
├── src/
└── docker-compose.yml
この my-app 全体が 1つのリポジトリです。
ローカルリポジトリ
自分の PC やサーバ上にある Git リポジトリです。
自分のPC上の作業場所
リモートリポジトリ
GitHub、GitLab、Bitbucket などにあるリポジトリです。
GitHub 上のリポジトリ
GitLab 上のリポジトリ
複数人で開発する場合、リモートリポジトリを中心にして変更を共有します。
commit
コミットとは、変更内容を Git に記録する操作です。
Git における「保存」に近いですが、単なる上書き保存ではなく、変更履歴として記録されます。
git commit -m "ログイン機能を追加"
コミットすると、その時点のファイル状態がスナップショットとして保存されます。
branch
ブランチとは、作業を分岐させる仕組みです。
例えば、main ブランチを安定版として残したまま、新機能の作業を別ブランチで行えます。
main
└── feature/login
ブランチを使うことで、作業中の変更が本番用のコードに直接混ざることを防げます。
Merge Request / Pull Request
Merge Request / Pull Request は、別ブランチで作業した内容を、main などのブランチに統合してよいか依頼する仕組みです。
GitLab では主に Merge Request、GitHub では Pull Request と呼ばれます。
意味としてはほぼ同じです。
feature/login の内容を main に取り込んでよいですか?
という申請です。
Organization / Group
GitHub では Organization、GitLab では Group と呼ばれることが多いです。
複数のリポジトリやメンバー、権限をまとめて管理する単位です。
Organization / Group
├── repo-a
├── repo-b
└── repo-c
会社やチーム単位で使われることが多いです。
Git の基本構造
Git では、変更がいきなりリポジトリに保存されるわけではありません。
以下の流れで管理されます。
作業ツリー
↓ git add
ステージングエリア
↓ git commit
ローカルリポジトリ
↓ git push
リモートリポジトリ
作業ツリー
実際にファイルを編集している場所です。
README.md を編集する
main.py を修正する
設定ファイルを追加する
といった通常の作業場所です。
ステージングエリア
次のコミットに含める変更を一時的に置く場所です。
git add README.md
を実行すると、README.md の変更がステージングエリアに登録されます。
ローカルリポジトリ
git commit した履歴が保存される場所です。
git commit -m "READMEを修正"
この時点では、まだ GitHub などのリモートリポジトリには反映されていません。
リモートリポジトリ
GitHub や GitLab 上のリポジトリです。
git push
することで、ローカルのコミットをリモートへ送信できます。
よく使う Git コマンド
現在の状態を確認する
git status
現在の変更状態を確認します。
よく確認できる内容は以下です。
- 変更されたファイル
- 新規作成されたファイル
- ステージング済みのファイル
- まだ add されていないファイル
- 現在のブランチ
Git を使うときは、まず git status を確認する癖をつけると安全です。
ファイルをステージングする
git add ファイル名
例:
git add README.md
ディレクトリごと追加する場合:
git add src/
現在のディレクトリ配下の変更をまとめて追加する場合:
git add .
git add . は便利ですが、不要なファイルまで追加してしまうことがあります。
コミット前には必ず確認すると安全です。
git status
git diff --staged
コミットする
git commit -m "コミットメッセージ"
例:
git commit -m "READMEを更新"
コミットメッセージには、何を変更したのかを簡潔に書きます。
良い例:
git commit -m "ログイン画面を追加"
git commit -m "不要な設定ファイルを削除"
git commit -m "Docker起動手順をREADMEに追記"
悪い例:
git commit -m "修正"
git commit -m "いろいろ変更"
git commit -m "update"
差分を確認する
未ステージの差分を確認します。
git diff
ステージング済みの差分を確認します。
git diff --staged
ブランチ間の差分を確認します。
git diff main..feature/login
これは、main と feature/login の差分を確認するコマンドです。
ブランチ操作
現在のブランチを確認する
git branch --show-current
または、
git branch
現在のブランチには * が付きます。
ブランチ一覧を表示する
ローカルブランチ一覧:
git branch
リモートブランチも含めて表示:
git branch -a
ブランチを作成する
git branch ブランチ名
例:
git branch feature/login
ブランチを切り替える
git switch ブランチ名
例:
git switch feature/login
古い書き方では checkout も使えます。
git checkout feature/login
ただし、現在はブランチ移動には git switch を使う方がわかりやすいです。
ブランチを作成してそのまま移動する
git switch -c ブランチ名
# または
# git checkout -b ブランチ名
例:
git switch -c feature/login
リモートブランチからローカルブランチを作って切り替える。
git clone/fetchで取得済みのリモートブランチを元に、ローカル作業用ブランチを作って、そのブランチに移動する。
git switch --track origin/<remote-branch>
# `--track` 「このローカルブランチは、このリモートブランチを相手にする」という紐付け
git switch -c <local> origin/<remote-branch>
# `-c`でローカルブランチの名前を指定する
ブランチを統合する
ブランチを統合するには git merge を使います。
例えば、feature/login の内容を main に取り込みたい場合は、まず main に移動します。
git switch main
git merge feature/login
重要なのは、git merge ブランチ名 は、
指定したブランチを、現在いるブランチへ取り込む
という意味だということです。
例えば、
git switch initial
git merge main
とすると、main の内容を initial ブランチへ取り込むことになります。
initial を main に取り込むわけではありません。
ブランチを削除する
安全に削除する場合:
git branch -d ブランチ名
-d は、マージ済みのブランチだけ削除できます。
未マージの変更があるブランチを強制削除する場合:
git branch -D ブランチ名
-D は強制削除です。
誤って作業中のブランチを消さないように注意してください。
git push と Upstream
push とは
push は、ローカルリポジトリのコミットをリモートリポジトリへ送信する操作です。
git push
初回 push
新しく作成したブランチを初めてリモートに push する場合、Upstream を設定します。
git push --set-upstream origin feature/login
短く書く場合:
git push -u origin feature/login
意味は以下です。
- ローカルの
feature/loginブランチをリモートへ送信する - リモート側にも
feature/loginブランチを作成する - 次回以降
git push/git pullだけで対象ブランチを判断できるようにする
Upstream の確認
git branch -vv
例:
* feature/login abc1234 [origin/feature/login] ログイン画面を追加
main def5678 [origin/main] READMEを更新
[origin/feature/login] のように表示されていれば、Upstream が設定されています。
リモートリポジトリの確認
git remote -v
例:
origin https://github.com/user/repo.git (fetch)
origin https://github.com/user/repo.git (push)
origin は、リモートリポジトリの名前です。
通常、最初に登録したリモートリポジトリは origin という名前になります。
リモートの変更を取り込む
git pull
git pull
git pull は、リモートリポジトリの最新変更を取得し、現在のブランチへ反映します。
ざっくり言うと、以下をまとめて行うコマンドです。
git fetch
git merge
ローカルの変更を捨てて、リモートの最新状態に合わせる
git restore .
git pull --rebase
- git pull --rebase の効果:
- サーバーにある最新のコードを取得し、ローカルの履歴(この場合はほぼ空か、最後のコミットのみ)と結合します。ローカルに変更がない場合、単にリモートの最新コードをローカルに取り込むだけになります。
git fetch
git fetch
git fetch は、リモートの最新情報を取得するだけです。
作業中のファイルや現在のブランチには直接反映しません。
安全にリモート状況を確認したいときに使えます。
変更を取り消す
未ステージの変更を取り消す
git restore ファイル名
例:
git restore README.md
現在のディレクトリ配下の未ステージ変更をすべて戻す場合:
git restore .
ただし、git restore . で戻せるのは、基本的に Git が追跡しているファイルの変更です。
新規作成した未追跡ファイルは削除されません。
ステージングを取り消す
git restore --staged ファイル名
例:
git restore --staged README.md
ステージングエリアをまとめて空にする場合:
git restore --staged .
これは、git add を取り消す操作です。
ファイルの中身は元に戻りません。
あくまで「次のコミット対象から外す」だけです。
未追跡ファイルを削除する
新しく作成したが、Git 管理されていないファイルを削除するには git clean を使います。
削除対象を確認するだけ:
git clean -n
実際に削除する:
git clean -f
ディレクトリも含めて削除する:
git clean -fd
注意点として、git clean はファイルを本当に削除します。
実行前に必ず -n で確認するのが安全です。
.gitignore
.gitignore とは
.gitignore は、Git に管理させたくないファイルを指定するためのファイルです。
例えば、以下のようなファイルは Git 管理しないことが多いです。
- ログファイル
- キャッシュファイル
- 一時ファイル
- OS やエディタが自動生成するファイル
- パスワードや API キーを含む設定ファイル
- ビルド生成物
- 仮想環境ディレクトリ
.gitignore の例
# ログファイル
*.log
# 一時ファイル
*.tmp
# Python
__pycache__/
*.pyc
.venv/
# Node.js
node_modules/
# 環境変数ファイル
.env
# OS / エディタ
.DS_Store
.vscode/
.idea/
.gitignore の基本ルール
特定のファイルを無視する
.env
特定の拡張子を無視する
*.log
特定のディレクトリを無視する
node_modules/
例外的に追跡する
*.log
!important.log
この場合、基本的には .log ファイルを無視しますが、important.log だけは Git 管理対象にできます。
.gitignore が効かない場合
.gitignore でよくある勘違いがあります。
それは、
.gitignore に書けば、すでに Git 管理されているファイルも無視される
というものです。
これは間違いです。
.gitignore が効くのは、まだ Git 管理されていないファイルです。
すでに git add や git commit されているファイルは、.gitignore に書いても追跡され続けます。
すでに Git 管理されているファイルを管理対象から外す
すでに Git 管理されているファイルを、ローカルには残したまま Git 管理から外すには、git rm --cached を使います。
git rm --cached ファイル名
例:
git rm --cached .env
その後、.gitignore に追記します。
.env
そしてコミットします。
git add .gitignore
git commit -m ".envをGit管理対象から除外"
ディレクトリごと Git 管理から外す
ディレクトリごと管理対象から外す場合は、-r を付けます。
git rm -r --cached ディレクトリ名
例:
git rm -r --cached node_modules/
その後、.gitignore に追記します。
node_modules/
コミットします。
git add .gitignore
git commit -m "node_modulesをGit管理対象から除外"
git rm -r --cached . の使い方
.gitignore を後から整備した場合、リポジトリ全体に対して Git 管理対象を見直したいことがあります。
その場合、以下のコマンドを使うことがあります。
git rm -r --cached .
git add .
git commit -m ".gitignoreを反映"
意味は以下です。
git rm -r --cached .
Git の管理対象から一度すべて外します。
ただし、--cached を付けているため、ローカルファイル自体は削除されません。
git add .
.gitignore のルールに従って、必要なファイルだけ再度ステージングします。
git commit -m ".gitignoreを反映"
変更をコミットします。
--cached の意味
--cached は、
Git の管理対象からは外すが、ローカルファイルは残す
という意味です。
通常の git rm は、Git 管理から外すだけでなく、作業ディレクトリ上のファイルも削除します。
git rm ファイル名
これはファイル自体も削除します。
一方で、
git rm --cached ファイル名
は、Git 管理から外すだけで、ファイル自体は残します。
注意:機密情報をコミットした場合
.env や API キーなどの機密情報を一度コミットしてしまった場合、git rm --cached だけでは不十分です。
なぜなら、現在の管理対象からは外れても、過去のコミット履歴には残っているためです。
その場合は、以下の対応が必要になります。
- API キーやパスワードを無効化・再発行する
- Git の履歴から機密情報を削除する
- すでにリモートへ push している場合は、チームメンバーにも共有する
初心者のうちは、まず .env や秘密鍵などを絶対にコミットしないように .gitignore を最初に作っておくのが安全です。
ログ確認
コミット履歴を確認する
git log
1行で見やすく表示する場合:
git log --oneline
ブランチの流れも見たい場合:
git log --oneline --graph --all
ファイル単位の履歴を確認する
git log -- ファイル名
変更内容も含めて確認する場合:
git log -p -- ファイル名
例:
git log -p -- README.md
git worktree
git worktree とは
git worktree は、1つのリポジトリから複数の作業ディレクトリを作成できる機能です。
通常、1つのリポジトリでは同時に1つのブランチしかチェックアウトできません。
しかし git worktree を使うと、別ディレクトリに別ブランチを展開できます。
repo-main/ main ブランチ
repo-feature/ feature/login ブランチ
worktree の一覧確認
git worktree list
worktree を追加する
git worktree add ../repo-feature feature/login
worktree を削除する
git worktree remove ../repo-feature
一時的に別ブランチを確認したいときや、複数ブランチを並行して作業したいときに便利です。
よく使う流れ
新規ファイルを追加してコミットする
git status
git add README.md
git commit -m "READMEを追加"
git push
変更内容を確認してからコミットする
git status
git diff
git add .
git diff --staged
git commit -m "設定ファイルを更新"
新しいブランチで作業する
git switch main
git pull
git switch -c feature/login
作業後:
git add .
git commit -m "ログイン機能を追加"
git push -u origin feature/login
その後、GitHub や GitLab 上で Pull Request / Merge Request を作成します。
まとめ
Git の基本的な流れは以下です。
編集する
↓
git add
↓
git commit
↓
git push
重要なポイントは以下です。
-
.git/が Git 管理の本体 - Git は変更履歴をコミットとして保存する
-
git addはコミット対象を選ぶ操作 -
git commitはローカルに履歴を保存する操作 -
git pushはリモートへ送信する操作 -
.gitignoreは Git 管理したくないファイルを指定する - すでに管理されているファイルには
.gitignoreは後から効かない - その場合は
git rm --cachedを使う -
git branch -dは安全な削除 -
git branch -Dは強制削除
Git は最初はコマンドが多く見えますが、まずは以下を覚えれば十分です。
git status
git add .
git commit -m "message"
git push
git pull
git switch
git branch
git diff