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 の管理対象にする
現在のディレクトリを Git の管理対象(リポジトリ)として初期化する
git init
実行すると、カレントディレクトリ配下に .git ディレクトリが作成されます。
リモートリポジトリをコピーしてローカルリポジトリを作る
git clone <リポジトリURL>
現在の状態を確認する
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 は強制削除です。
誤って作業中のブランチを消さないように注意してください。
ローカルリポジトリのコミットをリモートリポジトリへ送信
push は、ローカルリポジトリのコミットをリモートリポジトリへ送信する操作です。
git push
毎回明示的にpush先を指定する。
ローカルのfeatureAブランチをリモートのfeatureB へプッシュする。
現在チェックアウト中のローカルブランチは関係ない。
git push origin featureA:featureB
Upstream を設定してpush
Upstream を設定することで、「このローカルブランチとリモートブランチを今後のデフォルトの対応先として登録する」ことができる。
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 fetch
git merge
リモートに存在しなくなった追跡ブランチを削除
リモートの最新状態を取得(fetch)し、リモートに存在しなくなった追跡ブランチを削除(prune)する。
git fetch --prune
これを実施するとgit branch -aで、リモートに存在しなくなったremotes/origin/xxxxxxが表示されなくなる。
ローカルの変更を捨てて、リモートの最新状態に合わせる
git restore .
git pull --rebase
- git pull --rebase の効果:
- サーバーにある最新のコードを取得し、ローカルの履歴(この場合はほぼ空か、最後のコミットのみ)と結合します。ローカルに変更がない場合、単にリモートの最新コードをローカルに取り込むだけになります。
リモートの最新情報を取得する
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 で確認するのが安全です。
コミット履歴を確認する
git log
1行で見やすく表示する場合:
git log --oneline
ブランチの流れも見たい場合:
git log --oneline --graph --all
ファイル単位の履歴を確認する
git log -- ファイル名
変更内容も含めて確認する場合:
git log -p -- ファイル名
例:
git log -p -- README.md