Gitでつまずく人の多くは、コマンドを覚えていないのではありません。
「いま自分がどこにいて、何がどこへ動いたのか」が見えていないだけです。
ボタンを押すと枝が伸びる図を作りました。
commit・switch・merge に加えて、rebase・cherry-pick・reset・tag・push・pull まで図の上で試せます。
まず「再生」を押してください
お手本は3つあります。選んでから「再生」を押すと、自動で流れます。
- 枝を切って合流:機能ブランチを切って、作業して、mainへ合流。早送りとマージコミットの両方が出ます
- rebaseで一直線に:別々に進んだ枝を、rebaseで付け替えてから合流させます
- リモートと同期:push・tag・resetで、名札がどう動くかを追います
操作できるコマンド
図の上で何が動いているのか
- 丸=コミット:その時点のファイル全体の状態。中身は変わりません
- 線=親子関係:どのコミットの次に作られたか。Gitの本体はこの繋がりです
- 色の付いた札=ブランチ:特定のコミットを指す名札です。枝そのものではなく、ただの「印」です
- 黄色い札=タグ:commitしても動きません
- 灰色の札=リモート:pushしたところまでを指します
- HEAD=いま自分がいる場所:白い枠が付いている名札が、いまのHEADです
- 薄い丸=迷子のコミット:どの名札からもたどれなくなったものです。点線の輪が付きます
ブランチは「枝」ではなく「名札」です。
ここが最初の山です。
git switch -c feature を押しても、図はまったく枝分かれしません。
名札が増えるだけです。
枝が分かれるのは、そのあとcommitしたときです。
マージの2つの顔
デモで「再生」を押すと、この3つのうち最初の2つが順番に出てきます。
同じgit mergeでも、状況によって結果が違うのが分かります。
mergeとrebaseの違い
図の上で両方を試すと、「履歴が読みやすい代わりに、作り直している」という違いが目で分かります。
mergeとrebaseで履歴の形がどう変わるか
mainで git merge feature実行前実行後
親を2つ持つ丸Mができて線が合流。枝分かれの跡が残り、D・Eはそのまま。
featureで git rebase main実行前実行後
D・EをCの先に作り直したD'・E'(IDは別物)で一直線に。元のD・Eは迷子になる(reflogから戻せる)。
※A〜E・Mは説明用のコミット名です。
よくあるつまずき
switchとcheckoutの違い:checkoutは「移動」と「ファイルを戻す」を兼ねていて分かりにくいため、移動はgit switch、復元はgit restoreに分けられました(Git 2.23以降)- detached HEAD:ブランチ名ではなくコミットを直接指定して移動すると、名札の付いていない場所にHEADが立ちます。そこでcommitしても、どの名札も指していないので迷子になります
- コンフリクト:同じ場所(同じ行や隣り合う行)を両方の枝で書き換えたときに起きます。離れた場所を触っていれば、自動で合流します
mergeの向き:git merge featureは「featureを、いまの枝に取り込む」です。取り込まれる側に立っているか、図で確かめる癖をつけると間違えませんpushは枝を伸ばさない:手元の枝の状態を、そのままリモートに送るだけです。図の形は変わらず、灰色の名札だけが進みますreset --hardは消えない:コミットは残っていて、名札から外れるだけです。git reflogで位置を思い出せば戻せます
図の上で1回動かしてから同じコマンドを打つと、頭の中に同じ図が浮かぶようになります。
Gitが分からないのではなく、見えていなかっただけだと気づけるはずです。