git fetch と git pull は、どちらも GitHub などのリモート(ネットの向こうにある共有のリポジトリ)から最新の変更を取ってくるコマンドですが、取ってきたあとの動きが違います。git fetch は、変更の写しを手元にしまうだけで、いま作業しているブランチも、手元のファイルも変えません。git pull は、fetch のすぐあとに、merge か rebase でいまのブランチに取り込みます。
そして、今の Git では、手元とリモートで履歴が分かれていて、取り込み方(pull.rebase など)を決めていないと、git pull は取り込まずに止まります(fatal: Need to specify how to reconcile divergent branches.)。この記事は、初心者の方に向けて、公式の文書(git-scm.com)に沿って、fetch と pull の違いから、pull が止まる理由、--rebase・--ff-only の選び方、変更があるときの pull、取り消し、git fetch --prune までをまとめたものです。
コマンドの出力は git 2.39.3(Apple Git-145・macOS)のものです(2026年10月14日時点の最新は 2.56.0 です)。同じリモートを alice と bob の2人が使う場面を作って流しました。ハッシュ(コミットの名前になる英数字)は、流すたびに変わる例です。
- fetch と pull の違い(fetch は取ってくるだけ、pull はそのあと merge か rebase まで)
- 分かれたブランチで pull が止まる理由と、いつから止まるようになったか(Git 2.33.1、2021年10月)
- 止まったときに、merge・rebase・fast-forward だけ(
--ff-only)から選ぶ方法と、設定(pull.rebase・pull.ff) - コミットしていない変更があって pull できないとき、コンフリクトしたとき、pull を取り消したいとき
- リモートで消したブランチが手元に残るときの
git fetch --prune
git fetch と git pull の違いは?
公式の gitfaq(よくある質問)には、この違いがそのまま書かれています。fetch は、リモートの最新の変更の写しを手元にしまうだけで、作業ツリー(手元で編集しているファイルが置いてある場所)も、いまのブランチも変えません。そのあとで、中身を見る、merge する、rebase する、放っておく、を好きなときに選べます。pull は、fetch のすぐあとに、merge か rebase が続くものです。
git fetch | git pull | |
|---|---|---|
| リモートの変更を手元に取ってくる | する | する(先に fetch を走らせる) |
origin/main など(リモート追跡ブランチ)を進める | する | する |
| いまのブランチと作業ツリーを変える | しない | する(取り込む) |
| 取り込み方 | 自分で選ぶ | merge か rebase(分かれていて取り込み方を決めていなければ、止まる) |
origin/main のような <リモート名>/<ブランチ名> の名前は、リモート追跡ブランチといいます。Pro Git(Git の公式サイトで読める本)は、リモートのブランチの状態を指す参照で、「最後につないだときに、リモートのブランチがどこにあったか」のしおりだと説明しています。自分では動かせず、Git が通信のたびに動かします。
fetch の動きを、git 2.39.3 の出力で見てみます。bob がリモートに b.txt を push したあとの、alice の側です。
$ git fetch
From ../remote
6be44b5..34d1b38 main -> origin/main
$ 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
$ ls
a.txt
6be44b5..34d1b38 main -> origin/main は、origin/main が 6be44b5 から 34d1b38 に進んだ、という表示です。進んだのは origin/main だけで、手元の main も、手元のファイル(ls に b.txt は出ていません)も、そのままでした。git status が「origin/main より1コミット遅れている」と教えてくれています。
Pro Git は、git branch -vv の ahead(手元が進んでいる数)と behind(遅れている数)は、最後に fetch した時点のもので、サーバーにはつながない、最新の数がほしければ直前に fetch する、と書いています。手元の git 2.39.3 の git status でも、bob が push したあと、fetch する前は Your branch is up to date with 'origin/main'. と出て、fetch のあとに「behind」に変わりました。
fetch は、どこから取ってくる?
リモートを指定しない git fetch は、origin から取ります。いまのブランチに upstream(追跡しているリモートのブランチ)が設定されているときは、その側から取ります。既定では、すべてのリモートから取るには --all を付けます。設定 fetch.all を true にすると、リモートを指定しない fetch が --all を付けたときと同じ扱いになります。ただし fetch.all は Git 2.44.0 からで、手元の 2.39.3 には無く、流していません。
upstream は、clone したときに既定のブランチへ自動で設定されます。git push --set-upstream <リモート> <ブランチ> でも設定できます。引数なしの git pull と git fetch は、この upstream を使います。
git fetch --dry-run は、何が起きるかを表示するだけで、何も変えません。手元の git 2.39.3 では、--dry-run のあとも git status は「behind」になりませんでした。
fetch したあと、取り込む前に何を見る?自分で取り込むには?
fetch のあとは、取り込む前に中身を見られます。次の3つは、手元の git 2.39.3 で流したものです(上の続きです)。
$ git log --oneline main..origin/main
34d1b38 bob: add b
$ git diff --stat main origin/main
b.txt | 1 +
1 file changed, 1 insertion(+)
$ git branch -vv
* main 6be44b5 [origin/main: behind 1] first
git log --oneline main..origin/main は、リモートにだけあるコミットの一覧です。git diff --stat main origin/main は、変わるファイルの一覧です。git branch -vv は、手元のブランチごとの ahead/behind を見せます。
取り込むときは、自分で git merge origin/main を流します。公式の git pull の文書にも、git pull origin next と同じことは、git fetch origin と git merge origin/next でもできる、という例があります。遅れているだけなら、先端を前に進めるだけで追いつく fast-forward になります(git 2.39.3 の出力)。
$ git fetch
From ../remote
01e134c..cdd5177 main -> origin/main
$ git merge origin/main
Updating 01e134c..cdd5177
Fast-forward
d.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 d.txt
$ git status -sb
## main...origin/main
rebase で取り込みたいなら、fetch のあとに git rebase origin/main です。Pro Git も、git pull --rebase の代わりに、git fetch のあと git rebase <リモート>/<ブランチ> を自分で流してもよい、と書いています。手元と origin/main が分かれていた場面で、次のようになりました(git 2.39.3 の出力)。
$ git fetch
From ../remote
cdd5177..30b025a main -> origin/main
$ git rebase origin/main
Rebasing (1/1)
Successfully rebased and updated refs/heads/main.
$ git log --oneline --graph --all
* 08d70b1 alice: add alice1.txt
* 30b025a bob: add bob1.txt
* cdd5177 bob: add d
* 01e134c first
git merge・--ff-only・git fetch の基本は、Git コマンドのよく使う使い方の記事でも紹介しています。merge と rebase の違いは、merge と rebase の違いの記事で説明しています。
pull が「divergent branches」で止まるのはなぜ?
遅れているだけなら、そのまま進む
手元のブランチがリモートより遅れているだけなら、git pull は fast-forward で追いつきます(git 2.39.3 の出力)。
$ git pull
Updating 6be44b5..34d1b38
Fast-forward
b.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 b.txt
取り込むものが無いときは Already up to date. と出ます。手元が進んでいるだけ(リモートにない自分のコミットがあるだけ)のときも、同じ表示でした。
分かれていると止まる
手元にもリモートにも、お互いにないコミットがあるときは、履歴が分かれています(divergent)。次の例は、alice が alice1.txt をコミットしたまま(push していない)、bob が bob1.txt を push した場面です(git 2.39.3 の出力)。
$ git pull
From ../remote
d3078bd..ff5a94b main -> origin/main
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
終了コードは 128 で、取り込みは起きません。案内(hint)は、取り込み方を3つの設定から選ぶように言っています。git config を git config --global にすると、すべてのリポジトリの既定になります。コマンドに --rebase・--no-rebase・--ff-only を付ければ、その回だけ設定より優先されます。
公式の文書(最新)も、同じ考え方です。git pull の取り込み方は主に4つあり、--ff-only(fast-forward だけ。手元のブランチがリモートと分かれていたら失敗する)が既定です。--rebase は git rebase、--no-rebase は git merge、--squash は git merge --squash を使います。つまり、「pull は fetch と merge」とだけ覚えていると、今の動きとは合いません。 merge になるのは、たとえば --no-rebase を付けたときや、pull.rebase を false にしているときです。
止まるのは、取り込み方を何も決めていないときです。手元の git 2.39.3 では、分かれていても、--no-ff を付けたとき、pull.ff を true や false にしているとき、branch.<ブランチ名>.rebase を false にしているときは、止まらずにマージコミットができました。
止まっても、fetch は済んでいます。上の例のあとの状態です(git 2.39.3 の出力)。
$ git status
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
$ git branch -vv
* main f421b3a [origin/main: ahead 1, behind 1] alice: add alice1.txt
$ git log --oneline --graph --all
* f421b3a alice: add alice1.txt
| * ff5a94b bob: add bob1.txt
|/
* d3078bd first
origin/main は進んでいて、手元の main は動いていません。ahead 1, behind 1 は、手元に1コミット、リモートに1コミット、お互いにないものがある、という意味です。
なお、分かれたときの git status の案内の文は、Git の版で違います。この記事の 2.39.3 は (use "git pull" to merge the remote branch into yours) ですが、2.42.0 から (use "git pull" if you want to integrate the remote branch with yours) になっています。
いつから止まるようになった?
分かれていて取り込み方を決めていない pull が止まるようになったのは、Git 2.33.1(2021年10月12日) からです。
| 版 | 日付 | 分かれていて、取り込み方を決めていない pull |
|---|---|---|
| 2.27.0 | 2020年6月1日 | 警告が出る(止まらない) |
| 2.33.0 まで | 警告を出したうえで、merge していた | |
| 2.33.1 | 2021年10月12日 | 止まる |
| 2.34.0 | 2021年11月15日 | 止まる |
「2.34 から」と書かれていることもありますが、2.33.1 は 2.34 向けの直しをまとめて先に入れた版で、2.33.1 から止まります。また、2.27 は警告が出るようになった版で、止まるようにはなっていません。
この版は、リリースノートの一文からは分かりません。2.33.1 と 2.34.0 のリリースノートは、この変更を「pull の --rebase まわりの考え足らずの場合を直した」とだけ書いていて、「既定で止まるようになった」とは書いていないからです。そこで、変更のコミット(題は「fast-forward できないときは、既定で中止する」)、版ごとの Git のソース、版ごとの公式の文書で確かめました。ソースの builtin/pull.c に Need to specify how to reconcile divergent branches. が入っているのは、2.33.0 が0件、2.33.1 が1件です。2.35.0 のリリースノートには、案内に「merge が既定」と書いたままだったので直した、とあります。
止まったら、merge・rebase・fast-forward だけのどれにする?
止まったときの選び方は3つです。コマンドで、その回だけ選ぶこともできますし、設定で決めておくこともできます。
| 取り込み方 | コマンド(その回だけ) | 設定 | 分かれているとき |
|---|---|---|---|
| merge | git pull --no-rebase | git config pull.rebase false | マージコミット(2つの履歴をつなぐコミット)ができる |
| rebase | git pull --rebase | git config pull.rebase true | 手元にしかないコミットを、リモートの先端の上に載せ直す |
| fast-forward だけ | git pull --ff-only | git config pull.ff only | 取り込まずに止まる |
どれがよいか、を決める文は公式の文書にありません。履歴の見た目と、rebase の注意(下に書きます)を見て選びます。
merge で取り込むには?(--no-rebase)
--no-rebase は --rebase=false の略で、merge で取り込みます。分かれていれば、マージコミットができます(git 2.39.3 の出力)。
$ git pull --no-rebase
Merge made by the 'ort' strategy.
bob1.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 bob1.txt
$ git log --oneline --graph
* 5f74d88 Merge branch 'main' of ../remote
|\
| * ff5a94b bob: add bob1.txt
* | f421b3a alice: add alice1.txt
|/
* d3078bd first
マージコミットの件名は Merge branch 'main' of ../remote でした。履歴は、分かれて、またつながった形のままです。
rebase で取り込むには?(--rebase)
--rebase は、fetch のあと、いまのブランチ(の手元にしかないコミット)を upstream のブランチの上に載せ直します。同じ場面で流すと、履歴は一直線になりました(git 2.39.3 の出力)。
$ git pull --rebase
Rebasing (1/1)
Successfully rebased and updated refs/heads/main.
$ git log --oneline --graph --all
* 65f46eb alice: add alice1.txt
* ff5a94b bob: add bob1.txt
* d3078bd first
alice のコミットは、f421b3a から 65f46eb に変わっています。載せ直すときに、コミットが作り直されるからです。
注意: rebase は履歴を書き換えます。 公式の git pull の文書は、--rebase を「危ないことがある操作」と書いています。履歴を書き換えるので、すでに公開した履歴には向かず、git-rebase の文書をよく読むまで使わない、という注意です。pull.rebase の説明にも、意味が分かるまで使わない、と同じ注意があります。Pro Git は、自分のリポジトリの外にあって、ほかの人がその上で作業しているかもしれないコミットは rebase しない、一度も自分のコンピューターから出ていないコミットだけを rebase するなら問題ない、push したが誰もその上にコミットしていないなら、それも問題ない、と書いています。
また、ふつうの rebase は、手元のマージコミットを捨てて一直線にします。pull.rebase を merges にすると、--rebase-merges を渡して、手元のマージコミットを残します(interactive もあります)。手元の git 2.39.3 では、pull.rebase が false のときにできたマージコミットが、次に true にして pull したときに消えて、一直線になりました。
fast-forward だけにするには?(--ff-only)
--ff-only は、手元に分かれた履歴が無いときだけ、新しい履歴に進めます。分かれていると、取り込まずに止まります(git 2.39.3 の出力)。
$ git pull --ff-only
From ../remote
879a86f..8ef7400 main -> origin/main
fatal: Not possible to fast-forward, aborting.
$ git status -sb
## main...origin/main [ahead 1, behind 1]
終了コードは 128 で、手元の main は動いていません。
止まったときの表示は、何も付けない pull と違います。 何も付けない pull は Need to specify how to reconcile divergent branches.(取り込み方を決めて、という意味)、--ff-only は Not possible to fast-forward, aborting.(fast-forward できないので中止、という意味)でした。公式の文書は、最新のものが「--ff-only が既定」とはっきり書いています。手元の git 2.39.3 に当たる版の文書は、遅れているだけなら既定で fast-forward する、分かれているときは --rebase か --no-rebase(または pull.rebase)で指定が要る、という書き方です。どちらも、分かれていると止まる点は同じです。
なお、Git 2.41.0 から、--ff-only で止まるときは、その前に案内(分かれたブランチは fast-forward できない、git merge --no-ff か git rebase のどちらかを、という内容)も出ます。2.41.0 のリリースノートには、この案内の追加は書かれていません。
設定で決めておくには?
毎回選ぶのが面倒なら、設定で決めておきます。git config に --global を付けないと、そのリポジトリ(.git/config)だけの設定になり、付けると、すべてのリポジトリの既定になります。
$ git config pull.rebase false # merge で取り込む
$ git config pull.rebase true # rebase で取り込む
$ git config pull.ff only # fast-forward だけ(分かれていたら止まる)
手元の git 2.39.3 で、pull.rebase false は merge、true は rebase、pull.ff only は止まりました。pull.ff only を設定したままでも、コマンドに --rebase を付ければ、その回は rebase で取り込めます(コマンドの指定が設定より優先されます)。
$ git pull
From ../remote
df63a12..d82064e main -> origin/main
fatal: Not possible to fast-forward, aborting.
$ git pull --rebase
Rebasing (1/3)
Rebasing (2/3)
Rebasing (3/3)
Successfully rebased and updated refs/heads/main.
Pro Git には、pull の既定を rebase にしたいなら git config --global pull.rebase true、という書き方があります。ブランチごとに決めたいときは、設定 branch.<name>.rebase もあります(こちらは公式の文書で確かめただけで、流していません)。
コミットしていない変更があって、pull できないときは?
コミットしていない変更が手元にあるときの pull は、merge で取り込むか rebase で取り込むかで、止まり方が違います。
merge の pull の場合
取り込む変更と、手元のコミットしていない変更が同じファイルにかかると、pull は止まります。手元の git 2.39.3 では、次のように出ました。
$ git pull
From ../remote
5b44864..cdc3c4d main -> origin/main
error: Your local changes to the following files would be overwritten by merge:
a.txt
Please commit your changes or stash them before you merge.
Aborting
Updating 5b44864..cdc3c4d
$ git status -sb
## main...origin/main [behind 1]
M a.txt
a.txt を書き換えたままで、bob も a.txt を書き換えて push していた場面です。作業ツリーはそのままで、a.txt の変更は残っています。公式の文書(手元の 2.39.3 に当たる版)も、取り込む変更が手元のコミットしていない変更と重なると、merge は自動でキャンセルされて作業ツリーはそのまま、まず手元の変更を片づけるか、stash でしまっておくのがよい、と書いています。3行のファイルで、別の行を書き換えていても、同じファイルなら止まりました。
取り込む変更と手元の変更が別のファイルなら、そのまま進みます(git 2.39.3 の出力)。
$ git pull
From ../remote
e9bc772..dfd3c4e main -> origin/main
Updating e9bc772..dfd3c4e
Fast-forward
a.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git status -sb
## main...origin/main
M c.txt
止まったときの定番は、git stash でしまって、git pull して、git stash pop で戻す流れです。公式の git stash の文書にも、この例があります。手元の git 2.39.3 では、bob が a.txt の1行目を書き換えて push し、alice が同じ a.txt の3行目をコミットせずに書き換えていた場面で、次のようになりました。
$ git stash
Saved working directory and index state WIP on main: a499836 alice: a.txt 3 lines
$ git pull
Updating a499836..dd99be3
Fast-forward
a.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git stash pop
Auto-merging a.txt
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (bd8aa9cdb71ea084f2752a8f541d094f67560876)
$ cat a.txt
l1 (bob)
l2
l3 (alice, not committed)
bob の1行目と、alice の3行目の両方が入りました。stash の使い方はgit stash の使い方の記事で説明しています。pop でコンフリクトする場合は、ここでは流していません。コンフリクトの直し方は、Git のコンフリクトの解き方の記事に、stash pop の場合も含めてまとめています。
rebase の pull の場合
rebase の pull は、コミットしていない変更があると、始まりません。手元の git 2.39.3 では、次のように出て、終了コードは 128 でした。このときは、fetch もしていません(From ... の行が出ません)。
$ git pull --rebase
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.
unstaged changes は、git add していない変更のことです。
--autostash を付けると、始める前に変更を一時的に stash して、終わったあとで戻します(git 2.39.3 の出力)。
$ git pull --rebase --autostash
From ../remote
999695b..5c94930 main -> origin/main
Created autostash: 9ab0f64
Rebasing (1/1)
Applied autostash.
Successfully rebased and updated refs/heads/main.
$ git status -sb
## main...origin/main [ahead 1]
M a.txt
$ git stash list
変更は残り、stash の一覧は空でした。ただし、公式の文書は、使うときは注意すること、終わったあとの stash の適用で、ややこしいコンフリクトになることがある、と書いています。
毎回 --autostash を付けたくないときは、設定があります。rebase の pull は rebase.autoStash(既定は false)です。pull.autoStash は Git 2.51.0 からで、この記事の 2.39.3 にはありません。
pull がコンフリクトしたら?pull を取り消すには?
merge でも rebase でも、同じ場所を両方で書き換えていると、コンフリクト(衝突)になります。解きたくないときは、公式の git pull の文書のとおり、git merge --abort か git rebase --abort で安全にやめられます。コンフリクトの直し方は、Git のコンフリクトの解き方の記事で説明しています。
merge の pull でコンフリクトしたら
git pull --no-rebase でコンフリクトすると、次のように出ます(git 2.39.3 の出力)。
$ git pull --no-rebase
From ../remote
999695b..3cddaba main -> origin/main
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
終了コードは 1 でした。このとき git status が (use "git merge --abort" to abort the merge) と案内します。git merge --abort を流すと、手元の main は pull の前のコミットに戻りました(origin/main は fetch の分だけ進んだままで、ahead 1, behind 1 の分かれた状態です)。
git merge --abort は、コンフリクトを解くのをやめて、マージの前の状態を作り直そうとするものです。マージを始めたときにコミットしていない変更があると、作り直せないことがあります。だから、merge の前には、いつもコミットか stash をしておくのがよい、と公式の文書は書いています。
rebase の pull でコンフリクトしたら
git pull --rebase でコンフリクトすると、次のように出ます(git 2.39.3 の出力)。
$ git pull --rebase
Rebasing (1/1)
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
error: could not apply f47637a... alice: edit a
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply f47637a... alice: edit a
終了コードは 1 でした。git rebase --abort を流すと、rebase をやめて、始めたときの位置に戻ります。手元の main は pull の前のコミットに戻りました(origin/main は fetch の分だけ進んだままで、ahead 1, behind 1 です)。
pull が済んだあとで、取り消すには?
公式の git reset の文書の例「merge か pull を取り消す」では、merge の pull でコンフリクトだらけになって今は解きたくないなら git reset --hard(git reset --hard HEAD と同じ)です。pull はマージコミットを作っていないので、インデックスと作業ツリーの散らかりを片づけます。ただし、--hard はコミットしていない変更も消すので、まずは上の git merge --abort を使います。取り込みが終わったあとでやめたいなら、git reset --hard ORIG_HEAD です。取り込みが終わった pull と merge は、いまのブランチの元の先端を ORIG_HEAD に残します。
手元の git 2.39.3 で、git pull --no-rebase のマージコミットを取り消した例です。
$ git reset --hard ORIG_HEAD
HEAD is now at f421b3a alice: add alice1.txt
$ git status -sb
## main...origin/main [ahead 1, behind 1]
pull の前の f421b3a に戻りました。
注意: ORIG_HEAD が使えるのは、直前の pull が取り込みまで終わったときだけです。
- 取り込み方を決めていない pull や
--ff-onlyの pull がfatal:で止まったときは、ORIG_HEADは動いていません。手元の git 2.39.3 では、止まったあともORIG_HEADはそれより前の操作が残した位置のままでした(これは手元で見ただけで、公式の文書では確かめていません)。ほかの止まり方でも、止まった pull にはORIG_HEADを使いません。 - あいだに
reset・rebase・mergeなどを流していたら、ORIG_HEADは、それらの前の位置を指します。公式の文書によると、ORIG_HEADはgit am・git merge・git rebase・git resetが、操作の前のHEADの位置を記録したものです。 git reset --hard ORIG_HEADを流す前に、git log --oneline -1 ORIG_HEADで、戻る先を確かめます。
注意: --hard は、コミットしていない変更も消します。 手元にコミットしていない変更が残っているときは、公式の文書は git reset --merge ORIG_HEAD を勧めています。--hard ORIG_HEAD は戻りたい場所へは戻るが手元の変更を捨ててしまう、--merge は手元の変更を残す、という説明です(こちらは流していません)。reset の3つのモードや、ORIG_HEAD については、Git で取り消すには?の記事で説明しています。
リモートで消したブランチが手元に残るときは?(fetch --prune)
プルリクエストがマージされると、リモートのブランチが消されることがあります(プルリクエストとは?の記事も参照)。ところが、手元には、そのブランチを指す origin/... が残ります。Git は、はっきり捨てない限りデータを残すからです。公式の文書は、たまると、ブランチの出入りが多い大きなリポジトリでは遅くなったり、git branch -a --contains <コミット> のような表示がむだに長くなったりする、と書いています。
手元の git 2.39.3 で、bob がリモートの feature ブランチを消したあとも、ふつうの git fetch では remotes/origin/feature が残りました。--prune を付けると消えます。
$ git fetch
$ git branch -a
* main
topic
remotes/origin/feature
remotes/origin/main
$ git fetch --prune
From ../remote
- [deleted] (none) -> origin/feature
$ git branch -a
* main
topic
remotes/origin/main
--prune(-p)は、fetch の前に、リモートにもう無いリモート追跡の参照を消します。消えるのは origin/... の写しだけで、手元のブランチ(上の topic)は消えません。 公式の文書は、手元のブランチを消すとは書いていません。git pull にも同じ -p・--prune があります。
1回だけ消すなら、次の2つのどちらかです。
$ git fetch --prune <リモート名> # 取りながら消す
$ git remote prune <リモート名> # 消すだけ(取らない)
手元の git 2.39.3 では、git remote prune --dry-run origin が * [would prune] origin/feature(消すことになる、という表示)と出ました。--dry-run は、流しただけです。
毎回自動で消すなら、設定 fetch.prune(全体)か remote.<名前>.prune(リモートごと。fetch.prune より優先)です。git config fetch.prune true のあと、ふつうの git fetch で消えました。
タグの注意: タグは、ふつうは --prune で消えません(自動で付いてきたタグや --tags で取ったタグ)。ただし、refspec(取ってくる対象を決める設定)に refs/tags/*:refs/tags/* があると、リモートに無い手元のタグを全部消してしまうことがある、と公式の文書は注意しています。
よくある質問
git fetch origin の「origin」とは?
origin は、リモートにつけられた名前です。clone したリモートは、ふつう origin という名前になります。手元の git 2.39.3 の git remote -v では、次のように名前と URL が出ました。
$ git remote -v
origin ../remote.git (fetch)
origin ../remote.git (push)
リモートを指定しない git fetch は origin から取り、既定では、すべてのリモートから取るには --all を付けます(くわしくは上の「fetch は、どこから取ってくる?」)。「git fetch はすべてのリモートから取る」と説明している資料もありますが、公式の文書とは合いません。
「There is no tracking information for the current branch.」と出たら?
いまのブランチに upstream(追跡するリモートのブランチ)が無いときに、引数なしの git pull をすると出ます。手元の git 2.39.3 では、git switch -c topic で作ったばかりのブランチで、次のように出て止まりました(終了コードは 1)。
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> topic
案内のとおり、2つの直し方があります。1回だけなら、git pull origin main のようにリモートとブランチを書きます。upstream が無くても取り込めて、その回は FETCH_HEAD に入ります(* branch main -> FETCH_HEAD と出ます)。この先もずっと使うなら、git branch --set-upstream-to=origin/<ブランチ名> <いまのブランチ> で upstream を設定します。git push --set-upstream <リモート> <ブランチ> でも設定できます。
git pull origin master で「couldn't find remote ref master」と出たら?
リモートに、その名前のブランチが無いときに出ます。手元の git 2.39.3 では、リモートに main しか無い状態で git pull origin master を流すと、次のように出ました(終了コードは 1)。
$ git pull origin master
fatal: couldn't find remote ref master
$ git ls-remote --heads origin
675ae8f901cd90020facb127088955608ad43b61 refs/heads/main
git ls-remote --heads origin で、リモートにあるブランチが見られます。そこにある名前で指定し直します。
「Already up to date.」と出るのは?
取り込むものが無いときの表示です。手元の git 2.39.3 では、リモートに新しいコミットが無いときも、手元が進んでいるだけ(リモートにない自分のコミットがあるだけ)のときも、Already up to date. と出ました。
リモートに新しいコミットがあるかを、取り込まずに知りたいときは、先に git fetch をしてから、git status か git log --oneline main..origin/main で見ます。手元の git 2.39.3 では、bob が push したあとでも、fetch の前の git status は up to date と出ました。
そのほかの「pull できない」は?
ユーザー名やパスワード、SSH の鍵まわりでつながらないときは、別の話です。GitHub の SSH 設定入門の記事を見てください。
まとめ
git fetchは、リモートの変更を手元にしまうだけで、いまのブランチも作業ツリーも変えない。git pullは、fetch のあとに merge か rebase まで進める- 今の Git では、手元とリモートが分かれていて取り込み方を決めていないときの pull は止まる(
Need to specify how to reconcile divergent branches.)。止まるようになったのは Git 2.33.1(2021年10月12日)から。「pull は fetch と merge」とだけ覚えていると、今の動きとは合わない - 止まったら、
--no-rebase(merge)・--rebase・--ff-onlyのどれかを付けるか、pull.rebase・pull.ffで決めておく。rebase は履歴を書き換えるので、公式の文書は注意を促している。コマンドの指定は設定より優先される - コミットしていない変更が取り込むファイルとぶつかると、merge の pull は止まる。rebase の pull は、変更があると始まらない。stash か
--autostashを使う(pull.autoStashは 2.51.0 から) - pull がコンフリクトして解きたくないときは
git merge --abortかgit rebase --abort。pull が取り込みまで終わったあとならgit reset --hard ORIG_HEADだが、コミットしていない変更も消える。止まった pull には使わない。流す前にgit log --oneline -1 ORIG_HEADで行き先を確かめる。変更が残っているときはgit reset --merge ORIG_HEADと公式の文書は書いている - リモートで消したブランチの
origin/...は、git fetch --prune(設定はfetch.prune)で消える。手元のブランチは消えない
参考資料
- gitfaq(Git 公式の文書)の「fetch と pull のどちらを使うか」
- git-pull(Git 公式の文書)
- git-pull(Git 2.36.0 の文書。手元の 2.39.3 に当たる版)
- git-fetch(Git 公式の文書)
- git-config(Git 公式の文書)の pull.rebase
- git-config(Git 公式の文書)の pull.ff
- git-config(Git 公式の文書)の rebase.autoStash
- git-config(Git 公式の文書)の fetch.prune
- git-merge(Git 公式の文書)の --abort
- git-rebase(Git 公式の文書)の --abort
- git-reset(Git 公式の文書)の「merge か pull を取り消す」
- git-stash(Git 公式の文書)の「変更が残った作業ツリーに pull する」
- Pro Git 第2版(英語)Remote Branches
- Pro Git 第2版(英語)Rebasing
- pull が止まるようになった変更のコミット(pull: abort by default when fast-forwarding is not possible)
- Git 2.33.1 の builtin/pull.c(止まる処理が入った版)
- Git 2.27.0 の Release Notes(pull.rebase の警告)
- Git 2.33.1 の Release Notes
- Git 2.35.0 の Release Notes(merge はもう既定ではない)
- Git 2.51.0 の Release Notes(pull.autostash)
- Git の公式サイト(最新の版)
※この記事は、公式の資料をもとに AI(Claude)で下書きし、2026年10月14日時点の公式の資料と照らして確かめてから公開しています。誤りに気づいたらお問い合わせからお知らせください。



