はじめに
みなさん Git 使ってますか?
このご時世 Git も AI に操作させて自分じゃ触らなくなったって人も多いかもしれません。
Git で何ができるのかを知っておくと、AI への指示出しがスムーズになったり、手元でちょっと確認したいときにいちいちトークンを消費しなくて済んだりと、便利なこともあります。
普段 GUI や基礎的なコマンドを中心に使っている人が「へ~!」ってなりそうな内容をまとめてみました。
無視したいときの対応いろいろ
Git に出したくない差分を無視する方法としては .gitignore が一般的です。
ただ、状況によっては .gitignore では対応できない場合があります。
.gitignore 以外にもいくつか方法があるので紹介します。
| 方法 | 他の人にも影響 | Git登録済み | Git未登録 | 複数プロジェクト横断 |
|---|---|---|---|---|
プロジェクトの .gitignore
|
✅ | ❌ | ✅ | ❌ |
.git/info/exclude |
❌ | ❌ | ✅ | ❌ |
git update-index --skip-worktree |
❌ | ✅ | ❌ | ❌ |
グローバルの .gitignore(core.excludesFile) |
❌ | ❌ | ✅ | ✅ |
プロジェクトの .gitignore
プロジェクトの .gitignore です。どのプロジェクトでもルートに1つは置いていることが多いです。
ここに記述したファイルは Git の差分に出てこなくなります。
プロジェクトで共通のものなので開発メンバー全員に同じ設定が共有されます。
.gitignore は未登録のファイルにのみ有効で、すでに登録済みのファイルには無効であることに注意です。
こんなとき使う
- キャッシュ
- ビルド成果物
- 依存ライブラリ
- ログ
-
.envなどの環境別ファイル - エディタ設定
.git/info/exclude
自分だけが無視したいプロジェクトのファイルがある場合に使います。
.gitignore に入れるほどじゃない個人的なファイルを無視したい場合にいいかもしれません。
各開発メンバーのローカルリポジトリで設定するため、他の人には影響しません。
こんなとき使う
- 自分用スクリプト
- ソースの近くで管理したいメモ
- 一時ファイル
各自のローカルの .git フォルダの中にある .git/info/exclude に .gitignore と同じように記述することで設定できます。
skip-worktree
自分だけが無視したいプロジェクトのファイルがある場合に使います。
.gitignore や .git/info/exclude とは逆に、すでにインデックスに登録済みのファイルにのみ有効で、未登録のファイルには効きません。
各開発メンバーのローカルリポジトリで設定するため、他の人には影響しません。
こんなとき使う
- ローカル設定ファイル
- ローカル開発時に一時的に変更したい箇所(ログ出力など)
以下のコマンドで登録・解除が可能です。
skip-worktree に設定されているファイルがリモートで変更されると、ローカルに取り込む際にエラーになるため、一度解除する必要があります。
# 登録
git update-index --skip-worktree <ファイルパス>
# 解除
git update-index --no-skip-worktree <ファイルパス>
# Windows で確認
git ls-files -v | findstr "^S"
# Linux で確認
git ls-files -v | grep '^S'
グローバル .gitignore
複数プロジェクトで共通に無視したいファイルがある場合、端末共通の .gitignore を設定できます。
開発メンバーには共有されず、どのリポジトリでも自分の環境でだけ効きます。
こんなとき使う
- OS が勝手に作るファイル(
.DS_Store、Thumbs.dbなど) - 自分だけが使うエディタ・ツールの設定ファイル
- 自分専用のメモや作業ファイル
ちなみに私は、*.gapaorice、.gapaorice のように自分専用プレフィックスを設定しておいて、メモなどはすべてここに置くようにしています。
どのリポジトリでも誤コミットを防げて便利です。(前にどこかで見た方法を真似しています)
グローバルの .gitignore ファイルの場所は git config --global core.excludesFile で確認できます。
何も表示されない場合は未設定で、そのときは ~/.config/git/ignore が使われます。
コンフリクトで何が何だか分かんなくなったら
コンフリクトが起きて怖い!元に戻したい!というとき、だいたい --abort で戻すことができます。
コンフリクトが起きる操作(マージ・リベース・リバート・チェリーピック)共通で使えます。
たとえコマンドを忘れても git status で教えてくれるので、困ったらまずこれを実行するのがおすすめです。
git reset でも戻せますが、リベース中に使うと、ブランチは戻ってもリベース中の状態が残ったりするのでおすすめしません。
それぞれの操作の状態をきちんと片付けてくれる --abort を使うのが安全です。
間違えてリセットした
Git でリセットの操作を間違えて手元の変更を消し飛ばしたことはありますか?私はあります。
コミット列の先頭にあるブランチをリセットで移動させると、参照できなくなったコミットが画面上から消えてしまうことがあります。
GUI や git log で見えなくなってしまうので結構焦りますが、リセットしてすぐなら取り戻すことが可能です。
git reset --hard ORIG_HEAD または git reset --hard HEAD@{1} を使うことで、HEAD が1つ前に指していたコミットに移動することができます。
Git のリセットはブランチの位置を変える操作であり、内部で保持されているコミットを消す操作ではありません。
リセットした直後であればまだコミットの情報が残っており、そのコミットを参照するブランチを作ってあげることでまた見えるようになります。
どのブランチ・タグからも参照されていないコミットは、デフォルトで30日ほどで期限切れになり、その後消えてしまいます。無限にさかのぼれるわけではないことに注意してください。
また、この方法で戻せるのは一度でもコミットした内容のみです。
未コミットの状態で git reset --hard をしてしまうと、基本的には Git から取り出せないので注意しましょう。
ORIG_HEAD や HEAD@{1} を使うことで1つ前の位置に戻ることができますが、git reflog でさかのぼれる時点であればどこでも行けます。
git reset --hard 'HEAD@{yesterday 12:00}' みたいな書き方をすることで、昨日の12時時点にリセットなども可能です。
HEAD ってなに? ORIG_HEAD って何?
HEAD とは今いる場所を指すポインタです。
ブランチやタグの仲間ですが、Git の中では特別な立ち位置を持つものです。
お手元の適当なリポジトリの .git フォルダを開いて、その中の HEAD ファイルをメモ帳などで開いてみてください。
ブランチ名やコミットハッシュが書かれているはずです。
これが GUI などで HEAD として表示されるものの正体です。
現在チェックアウトしているブランチ or コミットを指します。
ORIG_HEAD も HEAD と同様に .git フォルダの直下に保持されます。
特定の操作(リセット、マージ、リベース、プルなど)を行うとき、その操作を行う前に HEAD が指していたコミットのハッシュが保存されます。
コミットやチェックアウトなど保存されない操作もあります。
GUI で origin/HEAD のように表示されているのは、リモートリポジトリのデフォルトブランチを指す目印です。
クローンした時点のデフォルトブランチを指していて、ローカルの HEAD とは意味が異なります。
リモート側でデフォルトブランチを変えても自動では更新されません。普段の作業で使うことはほとんどないので気にしなくて大丈夫です。
よく見る記法
~n は親をn世代さかのぼる
数字を省略すると1扱いになる
git reset --soft HEAD~ # 直前のコミットを取り消す
git rebase -i HEAD~3 # 直近3コミットを整理する
^n はn番目の親
数字を省略すると1扱いになる
git diff HEAD^ HEAD^2 # マージ前の2つのブランチの先端同士の差分
<ブランチ名>@{n} は、そのブランチがn回前に指していたコミットです。
親子関係ではなくブランチが動いた履歴(reflog)をたどるので、リベースやリセットをやらかしたときの復旧に使えます。
ブランチ名を省略すると今いるブランチになります。
git reset --hard @{1} # ブランチを1つ前の位置に戻す(リセットの取り消しなど)
git diff main@{1} main # 直前のプルで main に入ってきた変更を確認
main@{yesterday} や main@{"2026-10-01 18:00"} のように日時での指定も可能です。
main がその時点に指していたコミットの位置を参照できます。
ブランチの位置を変えたいとき
ブランチの位置を最新化したいとき、普通はプルを使いますが、私は git switch -C main origin/main のように switch コマンドを使うのが好きです。
switch はブランチを切り替えるコマンドで、-C オプションをつけると「ブランチを指定したコミットの位置に作り直してから切り替える。ブランチがなければ新しく作り、すでにあればその位置を強制的に移動させる」操作になります。
特定のリモートブランチの位置に同名のローカルブランチを作りたいけど、すでにあるなら置き換えたいってときに、ブランチの存在確認をせずに同じコマンドで切り替えられます。
git checkout -B main origin/main と同じ意味です。
ワークツリー
現在のワークスペースとは別の場所にソースを持ってきてそこで作業を行うことができます。
並行作業でワークスペースを分けられるので、AI 開発と相性がいいです。
クローンするのとは違い1つのローカルリポジトリでの作業なので、差分確認や取り込みが楽です。
1つのブランチを複数のワークツリーでチェックアウトできない点には注意が必要です。
また、不要になったワークツリーを削除するとき、フォルダを物理的に消すだけでは Git の内部でワークツリーの状態が残ってしまいます。コマンドから削除しましょう。
マージコミットのチェリーピック
チェリーピックでマージコミットを普通に選択するとエラーになりますが、-m オプションで親を選ぶことでチェリーピックが可能です。
例えば feature/バグ修正 が2コミット進んだ後に main にマージされた場合に、feature/バグ修正 をリリースブランチにチェリーピックしたいとします。
普通なら2コミットをそれぞれ取り込む必要がありますが、マージコミットを選べば1回で済みます。
リモートは複数登録できる
リモートはリポジトリに複数登録可能です。
別リポジトリで管理しているコードで、ソースを比較したり差分を取り込んだりしたいとき、git diff や git restore で直接扱えるので便利です。
途中で分岐した顧客別のリポジトリの差分確認をするときなんかに使っています。
オーファンブランチ
祖先がいない孤立したブランチをオーファンブランチといいます。
リポジトリの最初のコミットは親を持たないルートコミットですが、それ以降は普通にコミットしていると前のコミットにつながっていくので、通常は作られることがありません。
ソースとは無関係な中身を同じリポジトリに置きたいときに使われます。
以下のコマンドで作成することが可能です。
git switch --orphan new-branch
祖先が異なるコミット同士は通常のマージが行えないので、オプションをつけてマージする必要があります。
git merge --allow-unrelated-histories <ブランチ名>
過去の履歴を書き換える
過去の履歴全体に対して修正を行いたい場合、git filter-repo を使うのがおすすめです。
過去にコミットしたファイルを履歴のすべてから取り除くとか、ファイルの階層を変えてその変更を過去のすべての履歴に適用するとかがしたい場合に使えます。
git filter-repo --path secret.txt --invert-paths # ファイルを全履歴から消す
git filter-repo --to-subdirectory-filter a # 全体をサブフォルダに移す
注意点として、コミットのハッシュが全部変わるので、共有済みのリポジトリでは強制プッシュが必要になります。
git filter-repo は Git 本体には含まれないサードパーティ製ツールで別途インストールが必要になりますが、公式ドキュメントでも紹介されているものです。
モノレポ化したいとき
今まで複数リポジトリで管理していたものを、今後は1つのリポジトリ(モノレポ)で管理するようにしたいということがあります。
今までの履歴を保持したまま移行する場合は、
- 旧リポジトリをそれぞれクローン
- クローンしたリポジトリで、過去の履歴すべてに対してフォルダを一階層下に移動
- 新リポジトリを作成
- クローンしたリポジトリを新リポジトリのリモートに登録
- 旧リポジトリを新リポジトリにマージで合流
といった手順でモノレポ化できます。
おわりに
どれか1つでも「へ~!」となるものがあったらうれしいです。
全部を覚えておく必要はなくて、「こういうことができたはず」と頭の片隅にあるだけでも十分だと思います。
特にリセットの取り消しや --abort あたりは、知っているだけで焦る場面がぐっと減るのでおすすめです。










