origin と origin/main の正体 — clone・remote・branch -r

Claude Code の出力や git status には origin や origin/main が何度も出てきますが、どちらも GitHub そのものではありません。origin は GitHub の住所に付けた呼び名で、origin/main は最後に GitHub と話したときの GitHub の main の位置を、手元に貼っておいた付箋です。この回では、git clone で手元に何ができるかを見てから、git remote -v と git branch -r で中身を確かめ、「GitHub が進んでも origin/main は動かない」ことを確かめます。

画面の見方
  • 上のターミナルは、実際に打ったときと同じ出力です(Git は英語で答えます。通信の進み具合を示す行は省いています)
  • 下の中で起きていることは、グラフが2段になります。上が GitHub 側、下が手元です。同じコミットは、上下で同じ横位置に並びます
  • 丸がコミット、黒い札がブランチ、ピンクの札が HEAD です。手元のグラフにある点線の札(origin/main など)は、手元に貼ってある GitHub の写しです
  • 右の説明をスクロールして読み進めると、左のターミナルでコマンドが1つずつ打たれます。→ キーでも1つずつ進みます(← で1つ戻ります。スマホでは「次へ」ボタン)。最後まで進んでから → を押すと次の区間へ移ります。黄色く光っているのが、そのコマンドで変わった場所です

1. git clone — GitHub のリポジトリを手元に写す

第1部では git init でリポジトリを作りました。もう1つの始め方が git clone です。GitHub のリポジトリの URL を渡すと、リポジトリを丸ごと手元に写して、すぐ作業できる状態にします。題材は、第1部の memo-app を GitHub に置いたものです。GitHub 側には main のほかに、第1部で作った memo ブランチ(notes.txt にメモを書いたもの)もあります。

git clone — GitHub のリポジトリを手元に写す

  1. 上が GitHub 側です。memo-app にはコミットが4つあり、ブランチは main と memo の2本です。下の手元には、まだ何もありません。

  2. git clone URL は、GitHub のリポジトリを手元に丸ごと写します。コミットは4つとも 手元に来て、上下の同じ横位置に並びました。

    $ git clone https://github.com/you/memo-app.git
    Cloning into 'memo-app'...
  3. clone は、いまいる場所にリポジトリと同じ名前のフォルダ memo-app を作ります。

    $ ls
    memo-app
  4. ただし、いまいるのはまだ memo-app の外です。Git は not a git repository(ここは Git のリポジトリではない)と言って止まります。

    $ git status
    fatal: not a git repository (or any of the parent directories): .git
  5. フォルダの中に入ります。プロンプトに、乗っているブランチ main が出るようになりました。

    $ cd memo-app
  6. 作業ツリーにあるのは todo.txt だけで、memo ブランチにある notes.txt はありません。clone が作業ツリーに取り出すのは main の中身だけです。

    $ ls
    todo.txt
  7. origin/ が付いていない付箋は main だけです。origin/main・origin/memo・origin/HEAD は、GitHub 側の付箋の写し です。

    $ git log --oneline --all
    a7c3e19 (origin/memo) メモを追加
    e5c0a62 (HEAD -> main, origin/main, origin/HEAD) パンを追加
    8b41d07 卵を追加
    3f2a9c1 牛乳を追加
  8. 手元のブランチの一覧には main 1本しか出ません。memo のコミットは手元にありますが、それを指しているのは origin/memo の付箋だけです。

    $ git branch
    * main

clone が1回でしていることを並べると、こうなります。

clone がすることこの画面で見えたもの
リポジトリと同じ名前のフォルダを作るls に memo-app
GitHub 側のコミットをすべて手元に写す4つのコミットが上下に並んだ
GitHub の住所に origin という呼び名を付ける(次の節の git remote -v)
GitHub の各ブランチの位置を、origin/ の付いた付箋として貼るorigin/main・origin/memo
GitHub の既定のブランチを origin/HEAD として覚えるorigin/HEAD が origin/main と同じ位置
既定のブランチ(main)だけを手元に作り、作業ツリーに取り出す手元のブランチは main 1本。notes.txt は無い
手元の main の上流を origin/main にする(次の節の git branch -vv)

つまずきやすいのは2つです。1つは、clone した直後は、まだフォルダの外にいること。cd memo-app で中に入るまで、git のコマンドは止まります。もう1つは、GitHub に memo があっても、手元に memo ブランチは作られないことです。作り方は4節で見ます。

2. origin は GitHub の住所に付けた呼び名 — remote と branch -r

clone の直後の手元を、コマンドで確かめます。出てくる言葉は3つです。

  • リモート — 手元から見た「相手のリポジトリ」。ここでは GitHub のリポジトリ
  • origin — リモートの住所(URL)に付けた呼び名。clone すると、clone 元に自動でこの名前が付く
  • 追跡ブランチ — origin/main のように、GitHub 側のブランチの位置を手元に写した付箋。乗ってコミットすることはできず、GitHub と通信したときにだけ動く

origin の正体 — remote -v と branch -r・-a・-vv

  1. 前の動画で clone したリポジトリの中にいます。git remote は、このリポジトリが知っている リモート(相手のリポジトリ)の呼び名を出します。clone すると、clone 元に origin という呼び名が付きます。

    $ git remote
    origin
  2. -v を付けると、呼び名の後ろに住所(URL)が出ます。origin は、この URL に付けた呼び名 です。(fetch) は取ってくるとき、(push) は送るときの住所で、ふつうは同じです。

    $ git remote -v
    origin	https://github.com/you/memo-app.git (fetch)
    origin	https://github.com/you/memo-app.git (push)
  3. オプションなしの git branch は、手元のブランチだけを出します。手元にあるのは main 1本です。

    $ git branch
    * main
  4. -r は、origin/ の付いた 追跡ブランチ だけを出します。origin/main と origin/memo は、clone したときの GitHub の main と memo の位置です。origin/HEAD -> origin/main は「GitHub の既定のブランチは main」という印です。

    $ git branch -r
      origin/HEAD -> origin/main
      origin/main
      origin/memo
  5. -a は、手元のブランチと追跡ブランチを両方出します。追跡ブランチには remotes/ が前に付きます。

    $ git branch -a
    * main
      remotes/origin/HEAD -> origin/main
      remotes/origin/main
      remotes/origin/memo
  6. -v は、手元のブランチごとに、指しているコミットの ID とメッセージを添えます。

    $ git branch -v
    * main e5c0a62 パンを追加
  7. -vv にすると、角かっこの中に 上流(このブランチの相手)が出ます。clone した main には最初から origin/main が上流に付いているので、git push や git pull だけで相手が決まります。

    $ git branch -vv
    * main e5c0a62 [origin/main] パンを追加

origin という名前に特別な意味はありません。clone のときに Git が付ける既定の呼び名で、中身は「この URL を origin と呼ぶ」という1行の設定です。コマンドに origin と書くのは、毎回 URL を打つ代わりだと考えると分かりやすくなります。git push origin main は「その URL に main を送る」という意味です。

clone は手元の main に上流(upstream。このブランチがふだんやりとりする相手)も設定します。上流が決まっているので、git push や git pull を相手を書かずに打てます。git branch のオプションは次のように使い分けます。

コマンド出すもの読み方
git branch手元のブランチ* が今乗っているブランチ
git branch -r追跡ブランチだけorigin/HEAD -> origin/main は「GitHub の既定のブランチは main」という印
git branch -a両方追跡ブランチには remotes/ が前に付く
git branch -vv手元のブランチ+コミット+上流(-v は上流なし)[origin/main] が上流。ずれていれば [origin/main: ahead 1, behind 2]

ahead はまだ push していないコミットの数、behind はまだ取り込んでいないコミットの数です。どちらも、手元の main と手元の origin/main を比べた数です。

3. origin/main は自動では動かない

origin/main は「GitHub の main」と読みたくなりますが、正確には最後に GitHub と話したときの GitHub の main の位置です。Git は GitHub をいつも見張っているわけではなく、origin/main が動くのは fetch・pull・push を打ったときだけです。Windows のノート PC で作業している間に、Mac が GitHub に push した場面を見てみます。

origin/main は自動では動かない

  1. Windows のノート PC に clone したリポジトリです。同じリポジトリは Mac にもあり、どちらからも GitHub に push しています。Your branch is up to date with 'origin/main'. は、「main は origin/main と同じ位置にある」という意味です。

    $ git status
    On branch main
    Your branch is up to date with 'origin/main'.
    
    nothing to commit, working tree clean
  2. ここで、Mac が「バターを追加」を GitHub に push しました。上の GitHub 側の main だけが1つ進みます。手元のターミナルには何も起きません。

  3. もう一度 status を見ても、up to date のままです。GitHub の main は進みましたが、手元の origin/main は動いていません。

    $ git status
    On branch main
    Your branch is up to date with 'origin/main'.
    
    nothing to commit, working tree clean
  4. 手元には「バターを追加」がありません。origin/main は 最後に GitHub と話したときの位置 を手元に貼った付箋で、GitHub が進んでも自動では動きません。

    $ git log --oneline --all
    e5c0a62 (HEAD -> main, origin/main, origin/HEAD) パンを追加
    8b41d07 卵を追加
    3f2a9c1 牛乳を追加
  5. -vv も [origin/main] だけで、遅れ(behind)は出ません。status も -vv も手元の付箋どうしを比べているだけなので、付箋が古ければ答えも古くなります。

    $ git branch -vv
    * main e5c0a62 [origin/main] パンを追加
  6. 付箋を新しくするのが git fetch です。GitHub に問い合わせて足りないコミットを取ってきて、origin/main を e5c0a62..c41f0e2 と進めました。main は動きません。

    $ git fetch
    From https://github.com/you/memo-app
       e5c0a62..c41f0e2  main       -> origin/main
  7. 今度は behind 'origin/main' by 1 commit(1コミット遅れている)と出ました。付箋が新しくなったので、遅れが分かるようになりました。

    $ git status
    On branch main
    Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
      (use "git pull" to update your local branch)
    
    nothing to commit, working tree clean
  8. 「バターを追加」が手元に来て、origin/main がそこを指しています。main を追いつかせる git pull は、2-3 で扱います。

    $ git log --oneline --all
    c41f0e2 (origin/main, origin/HEAD) バターを追加
    e5c0a62 (HEAD -> main) パンを追加
    8b41d07 卵を追加
    3f2a9c1 牛乳を追加

GitHub が進んだあとも、git status は up to date と言い続けました。これは「手元の main は手元の origin/main と同じ位置にある」という意味です。status の up to date は「GitHub と同じ」ではなく、「最後に確かめたときの GitHub と同じ」です。

付箋を新しくするのが git fetch です。GitHub に問い合わせて手元に無いコミットを取ってきて、origin/ の付箋を GitHub と同じ位置に動かします。手元のブランチと作業ツリーには触りません。だから fetch したあとの status で、初めて behind が分かります。pull は中で fetch してから手元の main も動かし、push は送れたら origin/main を送った位置に動かします。fetch と pull の違いは2-3 fetch と pullで扱います。

4. origin/memo から手元のブランチを作る — git switch

GitHub の memo ブランチで作業の続きをするには、git switch memo と打つだけです。手元に memo が無く origin/memo があるとき、Git は次の3つをまとめて行います。

  1. origin/memo と同じコミットに、手元の memo を作る
  2. memo の上流を origin/memo にする
  3. memo に乗り換える

origin/memo から手元の memo を作る — git switch

  1. clone した直後のリポジトリです。手元のブランチは main だけで、memo は remotes/origin/memo(GitHub 側の写し)としてしかありません。この memo で作業の続きをしたいとします。

    $ git branch -a
    * main
      remotes/origin/HEAD -> origin/main
      remotes/origin/main
      remotes/origin/memo
  2. origin/ を付けたまま打つと止まります。a branch is expected, got remote branch は「ブランチを指定してください。指定されたのは追跡ブランチです」という意味です。追跡ブランチは GitHub の写しなので、乗ってコミットすることはできません。

    $ git switch origin/memo
    fatal: a branch is expected, got remote branch 'origin/memo'
    hint: If you want to detach HEAD at the commit, try again with the --detach option.
  3. origin/ を外して git switch memo と打ちます。Git は origin/memo と同じ位置に手元の memo を作り、origin/memo を上流に付けてから乗り換えます(set up to track)。

    $ git switch memo
    branch 'memo' set up to track 'origin/memo'.
    Switched to a new branch 'memo'
  4. 作業ツリーが memo の中身に入れ替わり、notes.txt が出てきました。

    $ ls
    notes.txt  todo.txt
  5. 手元のブランチが2本になり、どちらにも上流が付いています。memo の上流は origin/memo です。

    $ git branch -vv
      main e5c0a62 [origin/main] パンを追加
    * memo a7c3e19 [origin/memo] メモを追加
  6. memo と origin/memo が同じコミットに貼られています。ここで memo にコミットすれば、git push だけで GitHub の memo に送れます。

    $ git log --oneline --all
    a7c3e19 (HEAD -> memo, origin/memo) メモを追加
    e5c0a62 (origin/main, origin/HEAD, main) パンを追加
    8b41d07 卵を追加
    3f2a9c1 牛乳を追加
  7. main に戻ります。作業ツリーも main の中身に戻り、notes.txt は見えなくなります。

    $ git switch main
    Switched to branch 'main'
    Your branch is up to date with 'origin/main'.

git checkout memo でも同じことが起きます。気をつけたいのは origin/ を付けたまま打った場合です。シーンで見たとおり git switch origin/memo は止まりますが、git checkout origin/memo は止まらず、detached HEAD になります。そこでコミットしても、付箋の無い置き去りのコミットになります(1-4 checkout が分かるまでで見た状態です)。手元で作業するときは、origin/ を外した名前で乗り換えてください。

5. Claude Code と origin

Claude Code が打った Git のコマンド(延べ約14,000回)を数えると、git fetch が555回あり、そのうち405回は -q(進み具合の表示を出さない)付きでした。Claude Code が作業の前に fetch を打つのは、手元の origin/main が古いかもしれないからです。fetch しないまま status を見ても、「最後に確かめたときの GitHub」としか比べられません。

もう1つよく出てくるのが git branch -r --contains コミットID です。そのコミットを含む追跡ブランチを一覧するコマンドで、「このコミットはもう GitHub に上がっているか」を確かめるのに使います。これも手元の付箋を読むだけなので、答えは最後の fetch の時点のものです。Windows と Mac の2台で使っていて「Mac で直したものが Windows に無い」ときも、たいていは Windows の origin/main がまだ古いだけです。まず fetch してから status を見ます。

6. Claude Code の許可画面で見かけたら

この回で見たコマンドを、「何が消えうるか」で並べるとこうなります。

コマンド何が起きるか消えうるもの
git remote / git remote -vリモートの呼び名と URL を見るだけなし
git branch -r / -a / -vv / -r --contains付箋の一覧を見るだけなし
git clone URL新しいフォルダを作り、GitHub のリポジトリを写すなし(同じ名前の空でないフォルダがあれば止まる)
git fetch / git fetch -qコミットを取ってきて、origin/ の付箋を動かすなし(手元のブランチと作業ツリーには触らない)
git switch memo(origin/memo だけがあるとき)手元の memo を作って上流を付け、乗り換えるなし(上書きされる書きかけがあれば止まる)
git checkout origin/memodetached HEAD になる注意 そこで作ったコミットを置き去りにしやすい

ほぼすべて「なし」なのには理由が2つあります。1つは、どれも GitHub 側を1バイトも変えないこと。clone と fetch は GitHub から読むだけで、GitHub を書き換えるのは push です。もう1つは、手元で変わるのが origin/ の付箋(GitHub の写し)だけだということ。fetch は写しを新しくするだけで、自分のブランチ・作業ツリー・ステージには触りません。fetch は許可してよく、むしろ判断の前に打つべきコマンドです。

まとめ

  • git clone URL は GitHub 側のコミットをすべて手元に写し、既定のブランチ(main)だけを手元に作る。ほかのブランチは origin/memo のような付箋だけ
  • origin は GitHub の住所(URL)に付けた呼び名。git remote -v で URL が見える
  • origin/main は、最後に GitHub と話したときの GitHub の main の位置を手元に貼った付箋。動くのは fetch・pull・push のときだけ
  • status の up to date や -vv の ahead / behind は、手元の origin/main と比べた答え。新しい答えが要るときは先に git fetch
  • git switch memo は origin/memo から手元の memo を作って上流を付ける。origin/ を付けたままでは乗り換えられない

次の回では、手元のコミットを GitHub に送る git push を扱います。この回のコマンドと違って、push は GitHub 側を書き換えます。送ると GitHub の main と手元の origin/main がどう動くか、初めて送るブランチに付ける -u、push が断られるときを見ていきます。