Git の面接質問: 25 問と回答
Git の面接では、データモデル(コミット、インデックス、ブランチ、HEAD)の理解、merge と rebase、fetch と pull、reset と revert の違い、コンフリクトの解決と失われたコミットの復元、GitHub Flow や Git Flow などのチームでのワークフローが主に確認されます。
Git は、開発者、テスター、DevOps エンジニアの面接でほぼ必ず話題になります。独立した項目として聞かれることもあれば、「失敗したリリースはどう取り消しますか」のような形で質問に織り込まれることもあります。面接官が知りたいのは、フラグの暗記よりも、コミット、ブランチ、履歴の書き換えといった仕組みの理解です。以下に、最もよく出る 25 問を、好印象を与える水準の回答とともに挙げます。
質問は基礎から応用へ並んでいます。回答では、可能であれば実務からの短い例を添えてください。ドキュメントの暗唱よりも高く評価されます。
基礎の質問
1. Git とは何か。分散型のバージョン管理システムは集中型とどう違うのか。
Git は分散型のバージョン管理システムで、プロジェクトの変更履歴を保存し、複数の人が並行して作業できるようにします。SVN などの集中型では、履歴の全体が1台のサーバーにあり、開発者の手元にあるのは作業コピーだけです。Git では、それぞれのクローンが履歴の全体を持っているため、コミット、ブランチ、履歴の閲覧、マージがネットワークなしでローカルに行えます。
実務上のメリットは、速度が速いこと、オフラインで作業できること、単一障害点がないことです。GitHub や GitLab のようなサーバーは、Git にとっては技術的な必要条件ではなく、チームがどのコピーを「本家」とするかという取り決めにすぎません。
2. Git の作業は3つの領域からなります。それぞれは何か。
作業ディレクトリ(ディスク上のファイル)、インデックスまたはステージングエリア(次のコミットのスナップショット)、ローカルリポジトリ(履歴を持つ .git フォルダ)です。git add は作業ディレクトリからインデックスへ、git commit はインデックスからリポジトリへ変更を移します。
補足として、4つ目の領域であるリモートリポジトリに触れ、それを扱う git push と git fetch を挙げると、さらに良い印象になります。
3. コミットを直接できるのに、なぜインデックスが必要なのか。
インデックスを使うと、コミットを意図的に組み立てられます。変更された10個のファイルのうち、ひとつの作業に関係する3つだけをコミットし、残りは後回しにできます。git add -p を使えば、ファイルの中の個別の部分さえ選べます。
これがアトミックなコミットの基礎です。1つのコミットは1つの論理的な変更を表します。そのような履歴は読みやすく、レビューしやすく、revert で取り消しやすく、cherry-pick で移しやすくなります。
4. Git の内部で、コミットとは何か。
コミットは、プロジェクトのすべてのファイルのスナップショットであるツリー(tree)への参照、親コミットへの参照、作成者、コミッター、日時、メッセージを保持するオブジェクトです。全体の内容から計算された SHA-1 のハッシュで識別されます(新しいバージョンには SHA-256 の実験的なサポートもあります)。
重要な考え方は、Git が差分ではなくスナップショットを保存するということです。変更されていないファイルは複製されず、ツリーは同じ blob を参照します。ハッシュは親に依存するため、古いコミットを変更すると、それ以降のすべてのハッシュも変わってしまい、そのような変更は不可能に近いのです。
5. ブランチと HEAD とは何か。
ブランチは、コミットを指す移動可能なポインタにすぎません。.git/refs/heads/ にあるハッシュの入ったファイルです。そのため、ブランチの作成は瞬時に終わり、何もコピーしません。新しいコミットを作ると、現在のブランチのポインタがそのコミットへ進みます。
HEAD は、今どこにいるかを示すポインタです。通常はブランチを指します(ref: refs/heads/main)。特定のコミットやタグに切り替えると、HEAD はコミットを直接指します。これが detached HEAD の状態です。
6. detached HEAD とは何か。どこが危険なのか。
HEAD がブランチではなくコミットを指している状態です。たとえば git switch --detach v1.0 や git checkout a1b2c3d の後です。コードを見ることも、コミットすることもできますが、新しいコミットはどのブランチにも属しません。
そのまま別のブランチへ移ると、それらのコミットには到達できなくなり、やがてガベージコレクションで削除されます。作業を守るには、ブランチを作ります: git switch -c fix-from-detached。すでに離れてしまった場合でも、ハッシュは git reflog から見つけられます。
7. git fetch と git pull の違いは何か。
git fetch は新しいコミットをダウンロードし、origin/main のようなリモート追跡ブランチを更新しますが、ローカルのブランチやファイルには触れません。git pull は fetch に統合を加えたものです。既定では merge、--rebase または設定 pull.rebase=true を使うと rebase で統合します。
経験豊富な開発者は、fetch を単独で行い、git log HEAD..origin/main で内容を確認してから、統合の方法を決めることが多いです。
8. .gitignore はどう働くのか。ファイルを除外に加えたのに追跡され続けるのはなぜか。
.gitignore は、Git が追加を提案しないファイルのパターンを定めます。依存関係、ビルド成果物、ログ、秘密情報を含むローカル設定などです。ルールは追跡されていないファイルにだけ作用します。
すでにコミットされたファイルには、除外は効きません。ディスクに残したまま追跡だけを外すには git rm --cached config.local.php を実行し、その削除をコミットします。どのルールが働いているかは git check-ignore -v パス で確認できます。
ブランチ、マージ、コンフリクト
9. fast-forward マージとは何か。
統合先のブランチが分岐してから先へ進んでいなければ、Git は統合のときに、そのポインタを統合元ブランチの最新コミットへ動かすだけです。新しいコミットは作られず、履歴は一直線のままです。
--no-ff を付けると、この場合でもマージコミットを作ります。これにより、履歴から、ひとまとまりのコミットが独立した機能だったことが分かります。逆に --ff-only は fast-forward だけを許し、本当のマージが必要な場合は拒否します。
10. マージのコンフリクトはどのように起き、どう解決するか。
両方のブランチで同じ行が変更された場合(あるいは、一方でファイルが削除され、もう一方で変更された場合)、Git は自動では決められません。マージを止め、該当箇所を <<<<<<<、=======、>>>>>>> のマーカーで示します。
git status # コンフリクトのあるファイルの一覧
# ファイルを直し、正しい版を残す
git add app.js
git commit # merge の場合。rebase の場合は git rebase --continue
良い回答には予防策も含まれます。小さなブランチ、本流の頻繁な pull、フォーマットの取り決めです。引き返したいなら git merge --abort もあります。
11. merge と rebase の違いは何か。
merge は2つのブランチをつなぎ、親を2つ持つマージコミットを作ります。既存のコミットは変わらず、履歴は並行作業を正直に示します。rebase は、自分のブランチのコミットを別のブランチの上に載せ直し、新しいハッシュのコピーを作ります。履歴は一直線になります。
一般的な目安は、rebase は公開前の自分のローカルブランチを整えるために、merge は共有ブランチへの統合のために使う、というものです。他の人が作業している公開済みのコミットを rebase すると、重複や混乱が起きます。
12. 対話的な rebase とは何で、何に使うのか。
git rebase -i HEAD~5 は直近5つのコミットの一覧を開き、各コミットに対して操作を選べます。pick はそのまま残す、reword はメッセージを変える、edit は止まって修正する、squash と fixup は直前のコミットに統合する、drop は削除する、です。行の順番を入れ替えることもできます。
典型的な場面は、pull request の前に「wip」「fix typo」「もう一度修正」を、意味のある2〜3個のコミットにまとめることです。便利な組み合わせは git commit --fixup=<hash> と、その後の git rebase -i --autosquash です。
13. squash merge とは何で、どんな場合に選ぶのか。
squash merge では、ブランチのすべてのコミットを、統合先のブランチの1つのコミットにまとめます(git merge --squash、または GitHub や GitLab のボタン)。主要ブランチは機能ごとに1コミットを受け取ります。
利点は、main の履歴がすっきりすることです。欠点は、機能の内部の詳細な履歴が失われ、Git が元のブランチを統合済みとみなさないため、git branch -d ではなく -D が必要になることです。
14. cherry-pick とは何で、いつ使うのが適切か。
git cherry-pick <hash> は、1つのコミットの変更を現在のブランチに適用し、同じ内容だが別のハッシュを持つ新しいコミットを作ります。典型的な例は、develop から、リリースブランチやホットフィックスブランチへバグ修正を移す場合です。
乱用はよくありません。同じ修正が2つのコミットに存在することになり、後でブランチを統合する際にコンフリクトが起きることがあります。-x を付けると、元のコミットへの参照がメッセージに追加されます。
変更の取り消しと復元
15. git reset の --soft、--mixed、--hard の違いは何か。
| モード | ブランチのポインタ | インデックス | 作業ディレクトリ |
|---|---|---|---|
--soft | 移動する | 変わらない | 変わらない |
--mixed(既定) | 移動する | リセットされる | 変わらない |
--hard | 移動する | リセットされる | リセットされ、変更が失われる |
git reset --soft HEAD~3 は、直近の3つのコミットを1つにやり直すのに便利です。--hard はコミットされていない変更にとって危険です。その変更は reflog でさえ戻せません。
16. git revert は git reset とどう違うのか。
reset はブランチのポインタを後ろに戻し、実質的に履歴を書き換えます。revert は、指定したコミットの変更を打ち消す新しいコミットを作り、何も書き換えません。
そのため、共有ブランチで公開済みのコミットに対する正しい答えは revert です。同僚の履歴が壊れず、取り消しもログに見えます。マージコミットの場合は、本流の親を指定します: git revert -m 1 <hash>。
17. 誤って git reset --hard を実行したら、コミットはどう復元するか。
git reflog を使います。HEAD とブランチの移動の履歴が、ローカルに保存されています(既定では記録はおよそ90日間残ります)。失敗したコマンドの前の記録を探し、そこに戻ります。
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~2
# 9f8e7d6 HEAD@{1}: commit: Добавить оплату
git reset --hard 9f8e7d6
重要な注意点として、reflog が救えるのはコミットされたものだけです。一度もコミットや stash に入っていない変更は、Git では復元できません。
18. ファイルの変更を取り消す方法と、インデックスから外す方法は何か。
現在の正しいコマンドは、git restore app.js(インデックスの状態に戻す)と、git restore --staged app.js(インデックスから外すが、変更は残す)です。以前は git checkout -- app.js と git reset HEAD app.js を使っていました。これらも今でも動きます。
19. git stash とは何か。どんな落とし穴があるか。
git stash は、コミットされていない変更を一時的に保存し、作業ディレクトリを空にします。たとえば、緊急のホットフィックスに切り替えたいときに使います。戻すには git stash pop か apply を使います。
落とし穴は次のとおりです。既定では、追跡されていないファイルは保存されない(-u が必要)。pop でコンフリクトが起きると、記録はリストから削除されない。stash は忘れられやすい。長い作業には、別のブランチへのコミットが適しています。
応用の質問とチームでの作業
20. 機能を壊したコミットはどう見つけるか。
git bisect を使います。これは履歴の二分探索です。明らかに壊れたコミットと、正しく動いていたコミットを指定すると、Git が範囲の中央へ切り替え続け、log2(N) 回の確認で犯人を見つけます。
git bisect start
git bisect bad # 現在のバージョンは壊れている
git bisect good v2.3.0 # ここまでは動いていた
# 確認して good か bad で答え、Git がコミットを特定するまで繰り返す
git bisect reset
確認スクリプトがあれば、git bisect run npm test で自動化できます。
21. git push --force が危険なのはなぜか。何で代替するか。
--force はリモートのブランチを自分のバージョンで上書きするため、同僚がすでに push したコミットがサーバーから消えてしまいます。より安全なのは git push --force-with-lease です。最後に fetch したときと同じ状態であれば、ブランチを上書きします。
rebase した自分の feature ブランチへの強制 push は普通のことです。main などの共有ブランチへは、サーバー側の保護設定で強制 push を禁止するのが一般的です。
22. どんな Git ワークフローを知っているか。
GitHub Flow: 常にデプロイ可能な1つの main と、レビューと CI を経て pull request で統合される短い feature ブランチ。Git Flow: main と develop に加え、feature/*、release/*、hotfix/*。バージョン管理されたリリースのあるプロダクト向けです。トランクベース開発: 全員が非常に頻繁にトランクへ統合し、未完成の機能は feature フラグの背後に隠します。
強い回答は、選択の理由を説明します。たとえば、継続的にデプロイする Web サービスには Git Flow は過剰ですが、複数バージョンを保守するライブラリには適しています。
23. pull request とは何か。そこで何を確認するのか。
pull request(GitLab では merge request)は、ブランチを統合するための要求で、マージの前にコードレビューと自動 CI のチェックを通ります。これは Git 自体ではなく、プラットフォーム(GitHub、GitLab、Bitbucket)の機能です。
良い PR は小さく、1つの課題を解決し、分かりやすい説明があり、トラッカーのタスクとつながっています。レビュアーは、正しさ、読みやすさ、テスト、そして余計なファイルや秘密情報が含まれていないかを確認します。
24. どんなコミットメッセージのルールを守っているか。
50〜72文字程度の、命令形の短い件名(例: 「メールアドレスの検証を追加」)、空行、そして「何が変わったか」ではなく「なぜ」を説明する本文です。「何が変わったか」は差分を見れば分かります。多くのチームは Conventional Commits を使います: feat:、fix:、docs:、refactor:。
こうしたメッセージがあれば、チェンジログを自動生成でき、git log --grep ですぐに見つけられ、何年後でも変更の理由が分かります。
25. 誤ってパスワードをリポジトリに push したら、どうするか。
最初にすべきことは、シークレットを無効化して再発行することです。すぐに削除しても、クローン、フォーク、キャッシュにすでに存在するため、漏えいしたものとみなします。その後、ファイルを追跡対象から外し、.gitignore に加えます。必要に応じて、git filter-repo などで履歴を消去し、強制 push を行い、チームに周知します。
面接官はここで優先順位を見ています。まず履歴を書き換えようとして、キーの再発行を忘れる候補者は、不正解です。
面接の準備の仕方
最も確実な方法は、回答を暗記することではなく、テスト用のリポジトリで各シナリオを実際に試すことです。コンフリクトを作って解決する、reset --hard を実行して reflog から復元する、対話的な rebase でコミットをまとめる、などです。Git の面接では、実践的な課題を出されたり、コマンドの前後のコミットグラフを描くよう求められたりすることもあります。自分で試したことがあれば、答えは自然に出てきます。
自己確認のための短いテストも役立ちます。ヒントなしで、git rebase main や git revert HEAD の後に履歴がどう変わるかを答えてみてください。3つの領域で何が変わるかに自信をもって答えられれば、基礎はできています。
まとめ
Git の面接は、ほとんどの場合3つのテーマに集約されます。データモデル(コミット、ブランチ、HEAD、インデックス)、変更の統合(merge、rebase、コンフリクト、fetch と pull)、安全な取り消し(reset、revert、reflog)です。チームでのワークフローとプルリクエストの理解を加えれば、ほとんどの質問に答えられます。これらのシナリオ(チームでの作業や高度なツールを含む)は、Gitコースで実践的に練習できます。
よくある質問
面接で新人とシニアには、どんな Git の質問が聞かれますか?
新人には add、commit、ブランチ、コンフリクト、fetch と pull が聞かれます。経験のある開発者には、rebase、reflog、ワークフロー、リリース戦略の理解と、チームで壊れた履歴を立て直す方法が期待されます。
Git の実技の課題は出ますか?
よくあります。コンフリクトの解決、rebase 後のグラフの描画、公開済みのコミットを取り消すコマンドの選択などです。テスト課題の一部として、コミット履歴も評価されることがあります。
Git の内部構造まで知っている必要がありますか?
基礎レベルでは必要です。コミットがスナップショットと親への参照を保持し、ブランチがポインタにすぎないことは理解してください。オブジェクト形式や packfile の詳細はあまり聞かれません。
採用担当者は応募者のコミット履歴を見ますか?
よく見ます。GitHub のプロフィールや、テスト課題の履歴を確認することがあります。分かりやすいメッセージと、整ったアトミックなコミットは良い印象を与えます。 </content>