git pull と git fetch の違い|pull が止まる理由と --rebase・--ff-only

PR
git pull と git fetch の違い|pull が止まる理由と --rebase・--ff-only
この記事は約33分で読めます。

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 fetchgit 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.02020年6月1日警告が出る(止まらない)
2.33.0 まで警告を出したうえで、merge していた
2.33.12021年10月12日止まる
2.34.02021年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つです。コマンドで、その回だけ選ぶこともできますし、設定で決めておくこともできます。

取り込み方コマンド(その回だけ)設定分かれているとき
mergegit pull --no-rebasegit config pull.rebase falseマージコミット(2つの履歴をつなぐコミット)ができる
rebasegit pull --rebasegit config pull.rebase true手元にしかないコミットを、リモートの先端の上に載せ直す
fast-forward だけgit pull --ff-onlygit 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)で消える。手元のブランチは消えない

参考資料

※この記事は、公式の資料をもとに AI(Claude)で下書きし、2026年10月14日時点の公式の資料と照らして確かめてから公開しています。誤りに気づいたらお問い合わせからお知らせください。

PR
PR
タイトルとURLをコピーしました