1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

git/github 入門学習内容整理

Last updated at Posted at 2025-03-22

手書きノートの文字起こしの途中で心が折れたため途中からchatGPTでの文字起こし+補足になっています

参考にさせていただいた資料一覧

ありえんぐらい字の汚い原文+図解

S__33374218_0.jpg
S__33374217_0.jpg
S__33374216_0.jpg
S__33374215_0.jpg
S__33374214_0.jpg
S__33374213_0.jpg
S__33374211_0.jpg

P1.第1章:Git / GitHub のコアコンセプト

— そもそも Git / GitHub とは何か?


一言で言うと?

  • Git とは

    変更履歴をローカルで記録・操作できる、スナップショット方式の分散型バージョン管理システム

  • GitHub とは

    Git リポジトリをインターネット上で共有・管理できるホスティングサービス


Git が提供する価値 / 解決する課題

① 変更履歴の安全な記録と活用

  • 過去の状態を正確に再現できる(スナップショット方式)

  • コミットログで誰が・いつ・何を・なぜ変更したかを記録

  • 差分だけでなく、全体の状態を保存しているため履歴の信頼性が高い

  • 実装ミス・バグ発生時に「いつ壊れたか」を調査しやすい

    git log, git diff, git blame など


② ブランチ機能で柔軟な開発が可能に

  • 本流とは別の作業ラインを自由に作れる(ブランチ)

  • 試験的な機能追加、バグ修正などを本番に影響なく行える

  • 複数ブランチの統合(merge / rebase)も強力

  • 「1人の中に複数の自分がいて、別の道を試し、あとで1つにできる」

    → 開発の自由度と安全性が大幅に上がる


③ 分散型であることの強み

  • ネットがなくても作業できる(ローカルに完全な履歴あり)

  • 開発者一人ひとりが履歴の完全なコピーを保持している

  • 中央サーバーが壊れても復元可能(他の人の履歴を復元すればよい)

  • 各自が自由に作業した後で、マージによって「合流」できる

    → 柔軟で安全な並行開発を支える仕組み


GitHub が提供する価値 / 解決する課題

① オンラインでの履歴共有とコラボレーションの促進

  • Gitリポジトリをオンライン上で共有・保存できる
  • git remote add, clone, push, pull などのリモート操作が可能
  • チーム全体で履歴を一元管理し、複数人での開発を容易に

② チーム開発におけるコラボレーション支援

  • Pull Request(PR)によるレビュー・提案の仕組み

  • Issue や Projects でタスク・バグ管理も可能

  • ブランチ戦略(Git Flow, GitHub Flow)との連携が強力

  • コメント・Diff 表示・自動テスト(GitHub Actions)など

    開発の見える化・品質向上に貢献


補足キーワードと用語理解

  • バージョン管理とは?

    → プロジェクトの変更履歴を記録・管理する仕組み

    → 誰が・いつ・何を・なぜ変えたかを後から追えるようにする

  • スナップショットとは?

    → ファイルやプロジェクトのある時点での完全な状態を記録すること

    → Git ではこのスナップショットの連続として履歴が構成される

  • ホスティングサービスとは?

    → ソースコードなどのリソースをインターネット上で管理・共有できる仕組み

    → GitHub や GitLab、Bitbucket などがこれに該当


まとめ:Git / GitHub を学ぶ土台として

項目 Git GitHub
役割 バージョン管理ツール オンライン上でのリポジトリ共有・運用サービス
特徴 分散型・スナップショット・ブランチ中心 PR・Issue・CI/CD・チーム支援機能
価値 個人でもチームでも安全に変更履歴を記録・操作できる 複数人で効率よく開発を進められる

P2.第2章:Git のメカニズム

— 変更履歴をどのように実現しているのか?


Git の「変更履歴の管理」はどう実現されている?

Git は単なるファイルの差分管理ツールではなく、

内部で「オブジェクト」と呼ばれる構造体を組み合わせて履歴を構成しています。

この仕組みにより、Git は高速・堅牢・柔軟な履歴管理を実現しています。


登場人物(Git のオブジェクト)

Git の .git/objects/ に保存されるのは、以下の4種類のオブジェクトです:

1. ブロブ(blob)オブジェクト

  • ファイルの中身そのもの(内容に対してハッシュを計算)
  • 中身が同じなら、別ファイルでもハッシュは同じ=重複の最小化
  • ファイル内容の保存に特化した最小単位

2. ツリー(tree)オブジェクト

  • ディレクトリ構造やファイル名・モードを表現
  • ファイル名とブロブとの対応関係、階層構造を記録する

→ 例えるなら、「フォルダ構成のスナップショット」


3. コミット(commit)オブジェクト

  • スナップショットへのポインタ(=ルートツリーへの参照)
  • 作者・日時・メッセージなどのメタ情報
  • 直前のコミットへの参照を持つ(1つ or 複数)

→ これによって、コミットはチェーン(履歴)として連結される


4. タグ(tag)オブジェクト(この章では割愛)


スナップショットと履歴の仕組み

Git の「変更履歴」はどう構成されているか?

各コミットは以下のような構造を持っています:


commit (C3)
│
├── parent → C2
├── tree → T3
│   ├── fileA → blob a1
│   └── fileB → blob b2

→ これが スナップショット

コミットオブジェクトは、「この瞬間の状態(tree)」と「直前の履歴(parent)」を覚えている。


図で理解:スナップショットの構造変化

1つ目のコミッ(C1)


C1
│
└─ T1
    ├─ b (fileA)
    └─ b (fileB)

2つ目のコミット(C2)では fileB が変化


C2
│
└─ T2
    ├─ b (fileA) ← 同じブロブ再利用
    └─ b' (fileB) ← 新しい内容 → 新しいブロブ

差分を保存するのではなく、全体を構成し直すが、同一ブロブは再利用することで効率的


なぜこの構造が強いのか?

  • 任意のコミットオブジェクトがあれば、そこから完全なスナップショットを再構成できる
  • 同じ内容は同じブロブとして再利用される(効率的・重複がない)
  • ツリー・ブロブ・コミットすべてが SHA-1 / SHA-256 によって指されているため壊れにくい
  • 履歴の整合性が保証されている(ハッシュが連鎖しているため改ざんに強い)

まとめ:Git の履歴管理のメカニズム

要素 内容・役割
blob ファイルの中身。内容単位でハッシュ化
tree ディレクトリ構造と blob との対応
commit メタ情報 + treeへの参照 + 親commitへの参照
スナップショット commitオブジェクトから全体を復元できる構造
履歴の流れ commit → commit → commit とチェーン状に連結

P.2補足:Gitのオブジェクト構造とスナップショットの正体


Gitが扱う3つの主要オブジェクト(基本構造の整理)

オブジェクト 役割 実体の保存場所 内容
blob ファイルの中身 .git/objects バイナリのまま圧縮された内容
tree ディレクトリの構造・名前・モード .git/objects ファイル名や他のtree/blobの参照
commit スナップショットのラベルと履歴 .git/objects treeへの参照+親コミット+メタ

blob(ブロブ)=ファイルの「中身」

  • ファイルの内容だけを SHA-1 でハッシュ化して保存
  • 名前も拡張子も記録しない
  • 同じ内容なら何度addしても同じblobになる(重複しない)

Gitは「ファイルを保存する」のではなく「内容の状態を保存する


tree(ツリー)=ディレクトリとファイルの構造

  • ファイル名、実行権限(モード)、blobへの参照(ハッシュ)を保持
  • サブディレクトリもtreeオブジェクトとして再帰的に管理

ディレクトリ1階層ごとにtreeができる

→ 最終的に「ルートディレクトリのtree」がコミットに登録される


commit(コミット)=履歴とメタデータのセット

  • ルートtreeへのポインタ
  • 親コミット(parent)への参照
  • メタ情報(日時、作者、メッセージ)

これにより「履歴」が鎖のようにつながる(linked list)


補足①:なぜ「差分」ではなく「スナップショット」なのか?

  • Subversionなどは「前との差分」を保存(パッチ方式)
  • Gitは「今の全体の状態(tree)を記録し、前のコミットと繋ぐ」

メリット:

  • どのcommitからでも完全にプロジェクト状態を復元可能
  • 破損に強く、履歴の構造がわかりやすい
  • blobの重複排除により容量も効率化されている

補足②:オブジェクトの構成と履歴のつながり(図解補足)

C1
│
├── tree T1
│   ├── fileA → blob a1
│   └── fileB → blob b1

C2
│
├── tree T2
│   ├── fileA → blob a1(変化なし)
│   └── fileB → blob b2(内容が変化)

  • fileA は内容が同じなので blob a1 を再利用
  • fileB の変更により、新たに blob b2 が生成され、tree T2 に登録

Gitはファイル単位ではなく「内容単位」での履歴管理を行っている


補足③:この構造の理解が活きる操作

このオブジェクト構造を理解しておくと、以下の操作が内部で何をしているのかが見えるようになります:

操作 内部での変化
git commit ステージされたtreeを元にcommitオブジェクト作成
git reset --soft HEADの位置(commitオブジェクトの参照)だけ戻す
git reset --hard HEADとWT(作業ツリー)とindexをすべて巻き戻す
git cat-file -p <ハッシュ> オブジェクトの中身を読むコマンド(学習に最適)

補足まとめ:Gitはファイルの履歴を管理しているのではない

Gitが管理しているのは「ファイル内容のスナップショットを連結した構造」です。

  • blob:ファイルの本質(内容)
  • tree:構造(名前・位置)
  • commit:意味(時系列・履歴)

この3つが分かれているからこそ:

  • 同じ内容は何度使っても一度しか保存されない
  • 同じ履歴でもブランチを分けて使える
  • rebaseやmergeの高度な履歴操作が可能になる

P3.第2章:Git のメカニズム

— 変更履歴をどのように実現しているのか?


では、スナップショットはどのように作られるのか?

Git は、ローカルで次の3つの領域を使い分けることで、変更の確認・選別・確定という一連の操作を可能にしています。


ローカルの3領域構造(3ステージモデル)

名称 略称 正式名称 役割と中身
ワーキングツリー WT Working Tree 編集作業を行うディレクトリ
ステージングエリア SA Index / Staging 次のコミットに含める内容を準備する中間領域
ローカルリポジトリ LR .git/objects 確定された履歴(コミット、ブロブなど)が保存される

図で見る構造(文章版)


[ ワーキングツリー ]
    ↑ ↓ ファイルの編集
    |
[ ステージングエリア ] ← git add
    ↑ ↓ インデックスの更新
    |
[ ローカルリポジトリ ] ← git commit


それぞれの役割をもう少し詳しく:

① ワーキングツリー(WT)

  • 実際に編集・削除・作成などを行う「作業場」
  • ファイルはまだ Git に認識されていない/されているが未ステージ状態

② ステージングエリア(SA)

  • git add によって、「このファイルを次のコミットに含める」と明示されたものが入る
  • ファイルの**パス・モード・ブロブID(ハッシュ)**などが記録される
  • .git/index に実体がある(バイナリ形式)

③ ローカルリポジトリ(LR)

  • git commit によって、ステージングエリアの状態を snapshot として記録
  • .git/objects/blob(中身)、tree(構造)、commit(履歴) が作られる

私たちが日常でやっている操作は?

操作フローと対応コマンド:

ステップ やること コマンド 内部の変化
ファイルを編集する 直接編集 WTが変化。Git未認識 or 差分あり
変更をGitに伝える(ステージする) git add SAに記録され、次のコミット候補になる
変更を履歴として確定する(コミット) git commit LRに記録(オブジェクト生成)

なぜこの構造が良いのか?

  • ステージングエリアがあることで:
    • 「変更を一部だけ選んで確定できる」
    • 「ファイルの段階的な追加」ができる(部分add, hunk単位など)
  • ローカルリポジトリでコミットできるので:
    • オフライン作業が自由
    • 履歴のやり直しが効く(reset, amend, rebase)

補足知識:それぞれを確認するコマンド

  • git status:どこにどのファイルがいるか分かる
  • git diff:WT と SA の差分(未ステージ)
  • git diff --cached:SA と LR の差分(ステージ済みの内容)

まとめ:Git のローカル3階層モデル

役割 関連コマンド
ワーキングツリー 編集作業を行う作業空間 vim, code, diffなど
ステージングエリア 次のコミット候補を登録する git add, git restore --staged
ローカルリポジトリ 履歴として保存された状態 git commit, log, show

P.3補足:Git の3ステージ構造とスナップショット生成の実装


基本の構造(おさらい)

Git にはローカルに3つの「作業領域」があります:

略称 名称 役割 実体
WT ワーキングツリー ファイルを編集する場所(作業ディレクトリ) 実際のフォルダ・ファイル
SA ステージングエリア 次のコミットに入れるファイルを登録する場所 .git/index
LR ローカルリポジトリ コミット済みの履歴(確定されたスナップショット) .git/objects ディレクトリ群

📌 この3つは操作のたびにデータが少しずつ流れていく構造になっています。


フロー:スナップショットを作るまでの流れ

[WT] --git add--> [SA] --git commit--> [LR]

あなたが普段使っている git addgit commit は、実は「この3つの領域をまたぐ明確な移動操作」なのです。


🔍 各ステージの補足解説

🟦 ① ワーキングツリー(WT)

  • 実際にファイルがある作業場所(エディタやエクスプローラで見える場所)
  • Git から見ると「変更されたかどうか」は git statusgit diff で判定される

🔹 補足:

  • ここにあるファイルは Gitにはまだ「知られていない」状態も含む(untracked)

🟩 ② ステージングエリア(SA)

  • git add によってファイルの現在の状態(内容のハッシュ)・パス情報などが登録される
  • 実体は .git/index というバイナリファイルにある

🔹 補足:

  • コミット前に「入れる/入れない」を選べる、Gitの中間バッファ

  • 部分的にファイルを分割してステージングすることも可能

    
    git add -p
    

🟥 ③ ローカルリポジトリ(LR)

  • git commit によって、ステージングエリアの内容をオブジェクト(blob/tree/commit)として保存する
  • 履歴として残る「確定状態」

🔹 補足:

  • ローカルであれば、ここからいくらでも履歴をやり直せる
  • ここに入った内容だけが、最終的に push 可能になる

🧠 スナップショットとは実際には何か?

コミット時、Gitは:

  1. ステージングエリアにある全ファイルの内容を blob オブジェクト化
  2. ファイル構成を tree オブジェクトとして記録
  3. それらをまとめて commit オブジェクトにして、前の commit を参照する

→ これが「完全なスナップショット」の本体。


⚠️ 実務的なトラブル例と3ステージ構造の関係

現象 原因となる操作 解決への理解ポイント
git commit したのに変更が入ってない git add をしていなかった WT→SA に移動してない
git diff が何も出ないのに git status は赤い SA とは一致、WT とは不一致 git diff --cached で確認できる
変更が消えてしまった(取り消された) git restore を WT に対して実行 SA/LR にはまだ残っている可能性がある

🔄 各操作とデータの流れを可視化

操作 データの流れ
git add WT → SA(インデックスへ登録)
git commit SA → LR(オブジェクト保存)
git restore SA or LR → WT(ファイルを戻す)
git reset HEAD SA → WT(ステージングを解除)

P4.第2章(Git のメカニズム:ブランチ編):変更履歴の枝分かれと並行開発を可能にする仕組み


✅ テーマ:「並行開発を支えるGitの仕組みとは?」

Git では、ある時点の履歴から枝分かれして新たな開発を行い、あとから統合するという操作が非常に簡単かつ軽量にできます。

その背後にあるのが、以下の2つの仕組みです:

  • ブランチ(branch)
  • HEAD(ヘッド)

🔹 登場人物①:ブランチ(branch)

ブランチとは、**あるコミットを「名前付きで指し示すポインタ」**です。

✅ 技術的には:

  • .git/refs/heads/ブランチ名 というファイルに、**最新のコミットID(SHA-1)**が書かれている
  • つまり、ブランチは「この名前は、この履歴のどこを指しているか?」を記録しているだけ

🔸 例(図解イメージ):

.git/refs/heads/
├── main     ← C4
└── feature  ← C2

  • main ブランチはコミット C4 を指している
  • feature ブランチはまだ C2 に止まっている

→ 各ブランチが「どの地点に立っているか」を表しているだけで、履歴本体とは独立している


🔹 登場人物②:HEAD(ヘッド)

HEAD は、**「いま作業中のブランチはどれか?」**を指し示すポインタです。

✅ 具体的には:

  • .git/HEAD というファイルに、次のように書かれている:
ref: refs/heads/main

→ 現在の作業対象が main ブランチであることを表している

→ コミット時は、このブランチだけが新しいコミットを指すように更新される


🔄 ブランチとHEADの動き:実際の挙動

例:b1b2 という2つのブランチがあるとき


# 最初
HEAD → b1 → C1

# git commit すると
HEAD → b1 → C2
(b2 は変化しない)

# git switch b2
HEAD → b2 → C1

# git commit
b2 → C3
(b1 は C2 のまま)

🧠 HEAD がどのブランチを指しているかが「どのブランチが更新されるか」を決める鍵


✅ まとめ:並行開発ができる理由

要素 意味・役割
ブランチ 名前付きのコミットへのポインタ(追従する)
HEAD 現在作業中のブランチを指すポインタ
commit HEAD の先のブランチのみを更新する
switch HEAD の参照先(ブランチ)を切り替える

このシンプルで強力な構造により、Gitでは極めて柔軟な分岐と統合が可能になっているのです。

P4.第2章(Git のメカニズム:ブランチ編):ブランチとHEADの仕組み(後編)

〜 並行開発を可能にする2つのポインタ 〜


🧭 はじめに

Git で複数の作業を並行して行えるのは、

**「ブランチ」と「HEAD」**という2つのポインタの仕組みによるものです。

この資料ではその役割と挙動を、図とともに理解していきます。


🧱 1. ブランチとは?

🔹 ブランチ = コミットへのポインタ

ブランチとは、**あるコミットを「名前付きで指し示す参照(ポインタ)」**です。


.git/refs/heads/main   → C4 のコミットIDが書かれている


🖼️ 図:ブランチのイメージ

C2 ← C3 ← C4
             ↑
          main

  • mainC4 を指している
  • C1C4 はすべて Git のオブジェクトとして .git/objects に保存されている

🧠 2. HEADとは?

🔹 HEAD = 現在作業中のブランチを指す参照


.git/HEAD → ref: refs/heads/main

  • HEAD がどのブランチを指しているかで、どのブランチがコミットに更新されるかが決まる

🖼️ 図:HEADの構造


.git/HEAD → refs/heads/main → C4


🔄 3. ブランチとHEADの動き:操作例つき

✍️ ステップ①:ブランチ b1 にいるとき


HEAD → b1 → C1

✍️ ステップ②:git commit をすると


HEAD → b1 → C2(新しいコミット)

※ b2 は何も変わらない!


✍️ ステップ③:git switch b2 をすると


HEAD → b2 → C1

✍️ ステップ④:b2 で git commit


HEAD → b2 → C3(b2だけ進む)
b1 → C2(そのまま)


🧠 まとめ:この仕組みが並行開発を可能にする

ポインタ 役割
ブランチ コミットを名前付きで指す参照
HEAD 現在作業中のブランチを指す
commit HEADが指すブランチだけが進む

✅ だからできること

  • 機能ごとにブランチを分けて並行作業
  • 後から自由に統合(merge)
  • 履歴を壊さず、きれいに保つ

補足①:ブランチは「参照名」であり実体はない

Gitにおけるブランチ(LB)は、ただのラベル=ポインタにすぎません。

🔹 実体はどこにあるか?


.git/refs/heads/main

このファイルの中にはただコミットID(SHA-1)が書かれているだけ。

例:

d3a4e8d94f7e8f0123c1a9f1a43f5bd3b4c117

📌 つまり、**「mainという名前がどのコミットを指しているか」**を保持しているだけ。


✅ 補足②:HEADの本当の役割は「操作対象の指定」

HEAD は特別なポインタであり、

**「いま、自分がどのブランチを見て作業しているか?」**を示しています。

  • HEAD は .git/HEAD に保存されており、通常は:

ref: refs/heads/main

のように、**ブランチへの「参照」**を持ちます。


✅ 補足③:コミット時に何が動くか?

これが最も誤解されがち。

✨ 正確な動きはこう:

  • HEAD が指すブランチ(例:main)のポインタが
  • 新しいコミットを指すように更新される

C1 ← C2  ← C3(新規コミット)
        ↑
      main(← HEAD)

→ 他のブランチ(例えば develop)は完全に無関係。

Gitは**「いま見てる場所だけ」を変えるシステム**です。


✅ 補足④:HEADが直接コミットを指す状態(detached HEAD)

以下のようなコマンドを実行したとき:


git checkout <コミットID>

すると、.git/HEAD の中はこうなります:

d7d3a4e8d94f7e8f0123c1a9f1a43f5bd3b4c117

→ ブランチではなく、特定のコミットそのものを指している

→ この状態を「detached HEAD」と呼ぶ

📌 この状態でコミットしてもブランチに残らない(捨てられやすい)

git switch -c 新ブランチ名 で退避可能


✅ 深掘り①:HEADが動くだけ → Gitの効率性

ブランチの切り替え(git switch, git checkout)は

HEADの参照を書き換えるだけなので超高速。

  • Git は「ブランチという分岐したコピー」を作っているわけではない
  • 履歴はすべてコミットオブジェクトが持っている
  • ブランチはその中の「どこにラベルが付いているか」だけ

✅ 深掘り②:rebaseやmergeが扱えるのもこの構造のおかげ

  • merge → 2つの履歴(ポインタ)を統合し、新しいコミットを作る
  • rebase → 別のベースに履歴を並べ直し、ポインタだけ付け直す

→ すべて「ブランチ = ポインタ」という構造があるから柔軟


✅ 深掘り③:トラブルの理解に直結する

この仕組みが分かると、以下のようなエラーの意味もスッと理解できます:

  • fatal: not a git repository (or any of the parent directories): .git
  • You are not currently on a branch.
  • Your branch is ahead of 'origin/main' by N commits.

✅ 補足まとめ

概念 正体 補足
ブランチ 名前付きのコミット参照(ファイル) 内容はただの SHA-1、位置だけを示す
HEAD 現在の作業対象を示す特別な参照 通常はブランチへの「参照」
コミット ツリーへの参照+前コミットへのリンク これで履歴が鎖状に繋がる
HEADの移動 単なる「見る場所の切り替え」 実際にファイル構成が変わるのは checkout時
detached HEAD コミットを直接指している状態 ブランチに属していない→消える可能性あり

P5.第2章(Git のメカニズム:GtHub編):3種類のブランチとリモート連携の構造

〜 ローカルとリモートのブランチはどう分かれているのか? 〜


🧠 テーマ:「オンラインでのバージョン管理を実現する仕組み」

GitHubなどのリモートリポジトリを使うことで、Gitは複数人での履歴共有とコラボレーションが可能になります。

その実体は、**ローカルとリモートを結ぶ「ブランチの三層構造」**です。


✅ 登場人物と用語

1. RR(Remote Repository)

  • GitHub 上にあるリポジトリ
  • サーバー側の .git/refs/heads にブランチがある
  • 我々は直接中身を見ることは少ない(clone や fetch で取得)

2. LB(Local Branch)

  • ローカルで作業する「通常のブランチ」
  • たとえば main, feature/login など
  • .git/refs/heads/ に存在

3. RTB(Remote Tracking Branch)

  • 「ローカルに保存されたリモートの参照情報
  • origin/main, origin/feature のような名前で、.git/refs/remotes/ にある
  • 読み取り専用(直接コミット不可)

4. RB(Remote Branch)(GitHub上のブランチそのもの)

  • RTB の元になっているリモート側のブランチ
  • 我々は git fetch, git push, git pull などでやり取りする

🖼️ 図で理解:3つのブランチ構造


GitHub(RR)
│
├── refs/heads/main  ← Remote Branch(RB)

ローカルリポジトリ(LR)
├── refs/remotes/origin/main ← Remote Tracking Branch(RTB)
├── refs/heads/main          ← Local Branch(LB)
└── HEAD → refs/heads/main   ← 現在の作業ブランチ


🔄 実際のやりとりとブランチの関係

git fetch

  • GitHub から最新の RB(リモートブランチ)情報を取得
  • .git/refs/remotes/origin/ に **RTB(追跡ブランチ)**として保存

git push

  • ローカルブランチ(LB)の内容を GitHub 上の RB に反映
  • これによって他の人の RTB が更新される

git pull

  • fetch + merge/rebase
  • RTB と LB を統合(merge)

💡 実際に作るのはLBだけ!

  • RTB は git fetch などで自動的に更新される
  • RB は GitHub 側にある
  • 実際に自分が編集したりコミットできるのは LB(ローカルブランチ)のみ

✅ まとめ:ブランチの三層構造の違いと役割

名称 正体 作業可否 保存場所 いつ作られるか
RB リモートの実ブランチ ❌(サーバー側) GitHub (.git/refs/heads) GitHubで作成・pushで更新
RTB (origin/main) リモートのコピー ❌(読み取り専用) .git/refs/remotes/origin/ fetchcloneで作成
LB (main) ローカルの作業ブランチ ✅(編集・コミット可) .git/refs/heads/ checkout, switch -c 等で作成

要点の再確認(3種類のブランチ)

略称 ブランチ名例 実体 説明
LB main, feature/x ローカルの作業ブランチ 編集・コミットができる、HEADが指す対象
RTB origin/main リモート追跡ブランチ リモートブランチ(RB)のコピー、読み取り専用
RB GitHub上のmain リモートの実ブランチ push/pull でやり取りされるGitHub上の履歴先端

🔍 補足①:ローカルに「origin/main」があるのはなぜ?

これは git fetchgit clone 時に、

Git が リモートのブランチの状態をローカルに写し取って保存するためです。

  • origin/main は「最後に fetch したときの GitHub 上の main の状態」
  • 中身は .git/refs/remotes/origin/main に記録されています
  • これは GitHub 上の main を直接操作するのではなく、"追跡" しているにすぎない

📌 つまり RTB(origin/〜)は「GitHub 上のブランチの"影"」


🔍 補足②:「ブランチが3種類ある」のはあくまでローカルの視点

実際に存在するのは:

  • ローカルに2種類(LB, RTB)
  • リモートに1種類(RB)

でも、ユーザーとしては「3種類の情報」が出てくるので混乱しやすい

→ この三層構造は、fetch/push/pull の動作を正しく理解する土台


🔍 補足③:git push -u origin main の「-u」の意味

この操作は:

  • main(LB)を GitHub の main(RB)に push
  • 同時に、main に対して origin/main を追跡先(upstream)として設定

以後、git pushgit pull を省略形で使える

💡 このとき自動的に RTB (origin/main) も追跡対象として紐づく


🔍 補足④:RTBとLBの状態は git status に出る


$ git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.

  • これは:
    • LB = 2個先行している
    • RTB(origin/main)とはまだ差分がある(pushしていない)

✅ 状態を正確に知るには git branch -vv も便利です。


🔍 補足⑤:RTBを直接更新する方法はない

  • RTB(origin/mainなど)は手動で更新できない

  • git fetch によってのみ更新される

  • git pull は実は:

    
    git fetch
    git merge origin/main
    
    

🔍 深掘り:リモート追跡ブランチの正体

  • .git/config に次のような記録がされます:

[branch "main"]
  remote = origin
  merge = refs/heads/main

この設定があるから、Git は:

  • main を push するときは origin/main に送る
  • pull するときは origin/main から取り込む

→ この設定がないと、git pushgit pull に毎回フル指定が必要になります


✅ 実務でありがちな混乱パターン

状況 何が起きているか
git push しても GitHub に反映されない RTB が更新されただけ、または push 先が別ブランチだった
git pull したら意図しないマージが発生 RTB との履歴がズレていて自動マージされた(fetch + merge)
push したら新しいブランチが GitHub にできた ローカルブランチを -u せずに push し、新規作成された

✅ 補足まとめ:このページで理解すべき本質

  • GitHub 上のブランチ(RB)と、ローカルブランチ(LB)との間には RTB(origin/〜)というクッションがある
  • 直接 GitHub をいじっているわけではない
  • push/pull/fetch はこの「三者の位置関係」を変化させるコマンド

P.6補足:リモートとのやりとりとバージョン管理の共有


✅ 要点まとめ(原文ベース)

  • GitHub上の履歴(RR)を中心に、ローカル(LR)に取り込んで編集 → push で共有
  • 基本の流れ:
    1. cloneremote add で接続
    2. fetch, pull で取り込み
    3. push で反映

🛠 各操作のしくみと補足


git clone

GitHub上のリモートリポジトリをローカルに複製

Git操作の出発点

機能 内容
.git 配下の初期化 リモートの refs/heads 情報を取得
ローカルブランチ(LB)作成 origin/main を追跡する main ができる
remote 情報の保存 origin という名前でURLが登録される
オブジェクト(履歴)の複製 .git/objects にすべて保存

🔍 1回の clone でLB・RTB・RB の構造が整う


git remote add

後から別のGitHubリポジトリと連携したい場合に使用

clone後に新しいリモート接続先を登録する

  • git remote add origin <URL>
  • 履歴は取得されない(fetch が必要)
  • 単なる接続設定

git fetch

リモートの最新情報を取得(履歴は更新されない)

特徴 解説
RBの取得 GitHub上のブランチの最新状態を取得
RTBを更新 ローカルの origin/main を更新
LBは変化しない 手元の作業ブランチには影響を与えない

📌 履歴を壊さず、最新を知る安全な操作


git pull

fetch + merge or rebase

条件 説明
チェックアウト中の LB に対応する RTB が存在する その RTB を fetch → LB に統合
pull = fetch + merge が基本 デフォルト(Git 2.27以降は設定が必要)
pull --rebase 履歴を線形にしたいときに使用

🧠 RTB(origin/main)と LB(main)のズレがあると、自動マージコンフリクトが発生することも。


git push

ローカルのコミットをリモートブランチへ反映


git push <remote名> <LB>:<RB>

  • main:main → ローカルの main をリモートの main に反映
  • u をつけると upstream 設定が記録され、以後省略可能

📌 push はリモートに履歴を「転送する」操作で、GitHubに反映させる唯一の手段


🧠 実務で混乱しやすい点・補足

🔸 fetchとpullの違い

  • fetch → 安全確認、履歴の取得だけ
  • pull → fetch後に履歴統合が起こる(慎重に使う)

🔸 push で初めてブランチが「公開」される

  • ローカルだけでブランチを作っても他人は見えない
  • git push -u origin feature で共有される

🔸 upstream(追跡設定)に注意

  • git push -u で一度設定すれば、その後は git push だけでOK
  • git branch -vv で追跡状態が確認できる

✅ このページの本質まとめ

操作 説明 状態の変化
clone GitHub から全履歴を複製 LB/RTB/RB の初期状態が揃う
remote add URL を設定するだけ すぐには履歴は取得されない(fetch必要)
fetch リモートの状態を知る RTB のみ更新、LBは変更なし
pull RTBをLBに統合する 履歴が進み、競合する可能性もある
push 自分の履歴をリモートに反映 GitHubに履歴を共有できる

🔍 発展的な学習につなげる問い

  • pull 時の mergerebase の挙動の違いは?
  • fetchdiff origin/main で何が見えるか?
  • ローカルのブランチを削除せずに、リモートブランチだけ削除するには?

応用知識:実務で押さえておきたいこと

✅ push前の状態チェック(安全運用の3点セット)


git status        # 現在の追跡状況と差分
git log --oneline --graph --all   # 履歴の分岐状況
git diff origin/main              # 差分を直接比較


✅ upstream設定とは何か?

1回目の push で -u をつけると:


git push -u origin main

mainブランチに対して origin/main を「追跡先」として設定

→ 以後、git push, git pull だけで済むようになる(省略可)

設定ファイル .git/config に記録される:


[branch "main"]
  remote = origin
  merge = refs/heads/main


✅ push/pull時に起きやすいトラブル

症状 原因 対処
pushできない リモートの方が履歴が進んでいる(競合) git pull で先に同期
pullしたら意図しないマージが発生した rebase設定でなく mergeされた git config pull.rebase true を検討
push先を間違えて新しいブランチができた ローカルとリモートの追跡設定がずれていた git push -u origin 正しいブランチ名

P.7補足と学習の深化:ブランチ操作の理解と自信の獲得


✅ 1. ブランチ操作コマンドと補足知識

操作 コマンド 補足・背景
ブランチの作成 git switch -c ブランチ名 HEAD が新ブランチを指す。 -b オプションでも同様
ブランチの切替 git switch ブランチ名 .git/HEAD の参照先が変わるだけ(超高速)
履歴の確認 git log --oneline --graph --all ブランチや分岐・統合の様子を視覚的に確認できる
作業中の変更を一時退避 git stash WTとSAの内容を避難。コミットせずにブランチ切替可能
退避データの復元 git stash pop スタッシュ内容を取り出し、削除。applyなら復元だけ
ブランチをリモートに公開 git push -u origin ブランチ名 リモートブランチ(RB)を新規作成し、LBとRTBを紐づける

🧠 2. 各操作が Git 内部でどう作用しているか

🔸 switch -c(新規ブランチ作成)


HEAD → refs/heads/new_branch → C3(いまのコミット)

  • 実体は単に新しいブランチ名が作られ、HEADがそこを指すだけ
  • コミットはまだ何も起きない(履歴は共有されたまま)

🔸 stash / stash pop

  • stash は WTとSAの内容を一時的に .git/refs/stash に退避
  • pop は取り出して、WTとSAに再展開(そしてstashを削除)

📌 便利だけど「何を退避したか」は git stash show -p で確認すると安全


🔸 push -u の意味


git push -u origin feature/login

  • feature/login というローカルブランチ(LB)を GitHub に新規公開(RB作成)
  • 同時に RTB(origin/feature/login)も設定され、以後 pull/push を省略可

📌 これで「ブランチ三層構造」が整う


🎓 3. 実務での活用・理解を深める問いかけ


🔍 スタッシュを使うとどうなる?

  • 編集中にブランチを変えたい時どうする?
  • stash のあと、元の作業内容が消えたように見える…なぜ?

→ Git の「3ステージ構造(WT / SA / LR)」の理解とつながる


🔍 push -u したあとの挙動は?

  • なぜ git push だけで済むようになるのか?
  • .git/config にどう記録されているか?

🔍 git log --oneline --graph --all で何を読み取る?

  • どのブランチが分岐して、どこで統合されたか?
  • mergeコミットがどこか? rebaseとの違いは?

✅ まとめ:このページでの習得内容と次のステップ

🎯 習得したこと

  • ブランチの作成・切替・履歴の確認
  • スタッシュによる退避と復元
  • リモートブランチの公開と紐づけ
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?