fetch と pull の違い¶
GitHubとのデータのやり取りで必ず使う fetch と pull。
「なんとなく使っていたけど違いが分からない」という方向けに、図を使いながら丁寧に解説します。
登場人物の整理¶
Gitでは「ローカル(自分のPC)」と「リモート(GitHub)」の2か所にデータが存在します。
graph LR
subgraph local ["ローカル(自分のPC)"]
A["作業ディレクトリ<br/>実際のファイル"]
B["ステージング<br/>次のコミット候補"]
C["ローカルリポジトリ<br/>コミット履歴"]
D["リモート追跡ブランチ<br/>origin/develop など"]
end
subgraph remote ["リモート(GitHub)"]
E["リモートリポジトリ<br/>チームで共有"]
end
A -- git add --> B
B -- git commit --> C
C -- git push --> E
E -- git fetch --> D
D -- "git merge/rebase" --> C
E -- git pull --> C
リモート追跡ブランチとは
origin/develop のように、「GitHubのdevelopブランチの状態をローカルにキャッシュしたもの」です。
git fetch を実行したときに更新されます。
fetch とは?¶
git fetch は、GitHubの最新情報をダウンロードするだけで、
手元のファイルや作業ブランチには一切手を加えません。
sequenceDiagram
participant GitHub as リモート(GitHub)
participant Cache as リモート追跡ブランチ<br/>origin/develop
participant Local as ローカルブランチ<br/>develop
GitHub->>Cache: 最新コミットをダウンロード
Note over Cache: origin/develop が更新される
Note over Local: ← 変化なし!
fetch を使う場面¶
- 「他の人が何か変更した?」と確認したいとき
rebaseやmergeの前に、まず最新情報だけ取得したいとき
fetch 後に変更内容を確認できます:
pull とは?¶
git pull は git fetch + git merge を一度にやる操作です。
GitHubの最新を取ってきて、そのまま手元のブランチに反映します。
sequenceDiagram
participant GitHub as リモート(GitHub)
participant Cache as リモート追跡ブランチ<br/>origin/develop
participant Local as ローカルブランチ<br/>develop
GitHub->>Cache: ① fetch:最新コミットをダウンロード
Cache->>Local: ② merge:ローカルブランチに反映
Note over Local: 手元のファイルが更新される!
fetch vs pull 比較¶
git fetch |
git pull |
|
|---|---|---|
| 何をする | 情報をダウンロードするだけ | ダウンロード+手元に反映 |
| 手元のファイル | 変わらない | 変わる |
| コンフリクト | 起きない | 起きる可能性あり |
| 使いどころ | 確認してから慎重に反映したいとき | 素直に最新を取り込みたいとき |
このプロジェクトでの使い方¶
rebase 運用をしているため、git pull をそのまま使うと
マージコミットが作られてしまいます。以下のルールで使い分けてください。
developを更新するとき(自分のブランチ作業前)¶
develop は自分が直接作業しないブランチなので pull で問題ありません。
featureブランチ作業中に最新のdevelopを取り込むとき¶
pull ではなく fetch → rebase の順で実行します。
sequenceDiagram
participant GitHub
participant origin/develop as origin/develop<br/>(リモート追跡)
participant feature as feature/○○<br/>(自分のブランチ)
GitHub->>origin/develop: git fetch origin
Note over origin/develop: 最新の状態になる
origin/develop->>feature: git rebase origin/develop
Note over feature: コミットが最新地点に移植される
なぜ pull でなく fetch + rebase なのか
git pull origin develop は内部で merge を使うため、
マージコミットが作られて履歴がY字型になります。
fetch + rebase にすることで、履歴を一直線に保てます。
よく使うパターンまとめ¶
パターン1:朝イチで最新を取り込む¶
パターン2:作業中に他の人の変更を確認する(手元は変えない)¶
パターン3:featureブランチをdevelopに追いつかせる¶
パターン4:pull でマージコミットを作らずにrebaseする¶
実は pull にも --rebase オプションがあります。
これは fetch + rebase と同じ動きをします。
ただし明示的に fetch → rebase と書いた方が何をしているか分かりやすいため、
このプロジェクトでは fetch → rebase を推奨します。
動作イメージ:ビフォーアフター¶
gitGraph
commit id: "A"
commit id: "B"
branch feature
checkout feature
commit id: "C(自分の作業)"
checkout main
commit id: "D(他の人の作業)"
commit id: "E(他の人の作業)"
自分のブランチが古い B から出ている状態。
gitGraph
commit id: "A"
commit id: "B"
commit id: "D"
commit id: "E"
commit id: "C-prime(最新地点に移植)"
C が E(最新)の後ろに移植され、履歴が一直線に!
まとめ¶
| コマンド | 一言まとめ |
|---|---|
git fetch origin |
GitHubを覗き見するだけ。手元は変わらない |
git pull origin develop |
取ってきてそのまま反映。developブランチの更新に使う |
git fetch + git rebase |
取ってきて、自分のコミットを最新地点に移植。featureブランチの更新に使う |