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 のリポジトリを手元に写す
上が GitHub 側です。
memo-appにはコミットが4つあり、ブランチはmainとmemoの2本です。下の手元には、まだ何もありません。git clone URLは、GitHub のリポジトリを手元に丸ごと写します。コミットは4つとも 手元に来て、上下の同じ横位置に並びました。$ git clone https://github.com/you/memo-app.git Cloning into 'memo-app'...clone は、いまいる場所にリポジトリと同じ名前のフォルダ
memo-appを作ります。$ ls memo-appただし、いまいるのはまだ
memo-appの外です。Git はnot a git repository(ここは Git のリポジトリではない)と言って止まります。$ git status fatal: not a git repository (or any of the parent directories): .gitフォルダの中に入ります。プロンプトに、乗っているブランチ
mainが出るようになりました。$ cd memo-app作業ツリーにあるのは
todo.txtだけで、memoブランチにあるnotes.txtはありません。clone が作業ツリーに取り出すのはmainの中身だけです。$ ls todo.txtorigin/ が付いていない付箋は
mainだけです。origin/main・origin/memo・origin/HEADは、GitHub 側の付箋の写し です。$ git log --oneline --all a7c3e19 (origin/memo) メモを追加 e5c0a62 (HEAD -> main, origin/main, origin/HEAD) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加手元のブランチの一覧には
main1本しか出ません。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
前の動画で clone したリポジトリの中にいます。
git remoteは、このリポジトリが知っている リモート(相手のリポジトリ)の呼び名を出します。clone すると、clone 元にoriginという呼び名が付きます。$ git remote origin-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)オプションなしの
git branchは、手元のブランチだけを出します。手元にあるのはmain1本です。$ git branch * main-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-aは、手元のブランチと追跡ブランチを両方出します。追跡ブランチにはremotes/が前に付きます。$ git branch -a * main remotes/origin/HEAD -> origin/main remotes/origin/main remotes/origin/memo-vは、手元のブランチごとに、指しているコミットの ID とメッセージを添えます。$ git branch -v * main e5c0a62 パンを追加-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 は自動では動かない
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ここで、Mac が「バターを追加」を GitHub に push しました。上の GitHub 側の
mainだけが1つ進みます。手元のターミナルには何も起きません。もう一度 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手元には「バターを追加」がありません。
origin/mainは 最後に GitHub と話したときの位置 を手元に貼った付箋で、GitHub が進んでも自動では動きません。$ git log --oneline --all e5c0a62 (HEAD -> main, origin/main, origin/HEAD) パンを追加 8b41d07 卵を追加 3f2a9c1 牛乳を追加-vvも[origin/main]だけで、遅れ(behind)は出ません。status も -vv も手元の付箋どうしを比べているだけなので、付箋が古ければ答えも古くなります。$ git branch -vv * main e5c0a62 [origin/main] パンを追加付箋を新しくするのが
git fetchです。GitHub に問い合わせて足りないコミットを取ってきて、origin/mainをe5c0a62..c41f0e2と進めました。mainは動きません。$ git fetch From https://github.com/you/memo-app e5c0a62..c41f0e2 main -> origin/main今度は
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「バターを追加」が手元に来て、
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つをまとめて行います。
origin/memoと同じコミットに、手元のmemoを作るmemoの上流をorigin/memoにするmemoに乗り換える
origin/memo から手元の memo を作る — git switch
clone した直後のリポジトリです。手元のブランチは
mainだけで、memoはremotes/origin/memo(GitHub 側の写し)としてしかありません。このmemoで作業の続きをしたいとします。$ git branch -a * main remotes/origin/HEAD -> origin/main remotes/origin/main remotes/origin/memoorigin/を付けたまま打つと止まります。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.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'作業ツリーが
memoの中身に入れ替わり、notes.txtが出てきました。$ ls notes.txt todo.txt手元のブランチが2本になり、どちらにも上流が付いています。
memoの上流はorigin/memoです。$ git branch -vv main e5c0a62 [origin/main] パンを追加 * memo a7c3e19 [origin/memo] メモを追加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 牛乳を追加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/memo | detached 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 が断られるときを見ていきます。