Git 遠端操作 (Remote)

Git 的分散式特性讓你可以和遠端 repository 同步,實現團隊協作和程式碼備份。

遠端 Repository

Remote 是你的程式碼在網路上的副本,通常託管在:

  • GitHub
  • GitLab
  • Bitbucket
  • 自架的 Git server

git remote - 管理遠端

查看遠端

# 列出遠端名稱
git remote

# 列出遠端名稱和 URL
git remote -v

輸出:

origin  https://github.com/username/repo.git (fetch)
origin  https://github.com/username/repo.git (push)

origin 是預設的遠端名稱,當你 git clone 時會自動設定。

新增遠端

git remote add origin https://github.com/username/repo.git

你也可以新增多個遠端:

git remote add upstream https://github.com/original/repo.git
git remote add backup git@backup-server.com:repo.git

修改遠端 URL

git remote set-url origin https://github.com/newusername/repo.git

重新命名遠端

git remote rename origin github

移除遠端

git remote remove upstream

查看遠端詳細資訊

git remote show origin

git fetch - 取得更新

git fetch 從遠端下載最新的 commit,但不會改變你的工作目錄。

# 取得 origin 的所有更新
git fetch origin

# 取得特定分支
git fetch origin main

# 取得所有遠端的更新
git fetch --all

Fetch 後,你可以檢查遠端有什麼變化:

# 查看遠端分支
git branch -r

# 比較本地和遠端的差異
git log main..origin/main
git diff main origin/main

git pull - 取得並合併

git pull = git fetch + git merge

# 取得並合併 origin/main 到當前分支
git pull origin main

# 如果有設定追蹤,可以省略參數
git pull

Pull 加上 Rebase

git pull --rebase origin main

這樣會用 rebase 而不是 merge 來整合變更。

設定預設使用 Rebase

git config --global pull.rebase true

git push - 推送變更

git push 把本地的 commit 推送到遠端。

基本用法

# 推送到 origin 的 main 分支
git push origin main

第一次推送新分支

# 推送並設定追蹤
git push -u origin feature
# 或
git push --set-upstream origin feature

設定追蹤後,之後只要 git push 就好,不需要指定遠端和分支。

推送所有分支

git push --all origin

推送標籤

# 推送單一標籤
git push origin v1.0.0

# 推送所有標籤
git push --tags

強制推送

git push --force origin main
# 或
git push -f origin main
強制推送會覆蓋遠端的歷史,在團隊協作時要非常小心,可能會覆蓋別人的工作。

比較安全的強制推送:

git push --force-with-lease origin main

--force-with-lease 會檢查遠端是否有你沒看過的 commit,如果有就會拒絕推送。

刪除遠端分支

git push origin --delete feature
# 或
git push origin :feature

追蹤遠端分支

設定追蹤關係

# 設定當前分支追蹤遠端分支
git branch --set-upstream-to=origin/main

# 新建分支並追蹤
git checkout --track origin/feature

查看追蹤狀態

git branch -vv

輸出:

* main    a1b2c3d [origin/main] Latest commit
  feature b2c3d4e [origin/feature: ahead 2, behind 1] WIP
  • ahead 2:本地比遠端多 2 個 commit
  • behind 1:遠端比本地多 1 個 commit

常見工作流程

開始工作前同步

git checkout main
git pull

推送新功能

# 1. 建立分支
git checkout -b feature/new-feature

# 2. 開發並 commit
git add .
git commit -m "Add new feature"

# 3. 推送到遠端
git push -u origin feature/new-feature

# 4. 在 GitHub 開 Pull Request

同步遠端的更新

# 在 feature 分支上同步 main 的更新
git fetch origin
git rebase origin/main

# 或者
git checkout main
git pull
git checkout feature
git rebase main

Fork 的工作流程

當你 fork 別人的專案:

# 1. clone 你的 fork
git clone https://github.com/yourname/repo.git

# 2. 新增原始 repo 為 upstream
git remote add upstream https://github.com/original/repo.git

# 3. 取得 upstream 的更新
git fetch upstream

# 4. 合併 upstream 的變更到你的 main
git checkout main
git merge upstream/main

# 5. 推送到你的 fork
git push origin main

HTTPS vs SSH

Git 支援兩種連線方式:

HTTPS

git clone https://github.com/username/repo.git
  • 需要輸入帳號密碼(或 Personal Access Token)
  • 設定 credential helper 可以記住密碼
git config --global credential.helper cache

SSH

git clone git@github.com:username/repo.git
  • 需要先設定 SSH key
  • 不需要每次輸入密碼

設定 SSH key:

# 產生 SSH key
ssh-keygen -t ed25519 -C "your@email.com"

# 複製公鑰
cat ~/.ssh/id_ed25519.pub

# 把公鑰加到 GitHub Settings > SSH Keys

切換 URL

# 從 HTTPS 切換到 SSH
git remote set-url origin git@github.com:username/repo.git

# 從 SSH 切換到 HTTPS
git remote set-url origin https://github.com/username/repo.git

常見問題

推送被拒絕

! [rejected]        main -> main (non-fast-forward)

這表示遠端有你沒有的 commit。解決方式:

# 先取得遠端的更新
git pull --rebase

# 解決衝突(如果有)
git add .
git rebase --continue

# 再推送
git push

清理已刪除的遠端分支

# 清理本地追蹤的遠端分支(遠端已刪除)
git remote prune origin

# 或在 fetch 時自動清理
git fetch --prune