git pull 更新已存在分支但不 switch 或 checkout 到該 branch

最近工作上有一個開發已久終於要正式上線的專案,該專案我是採用 GitHub flow,就代表不管什麼變更都會直接切出一支分支處理最後合併。
但那個 main 分支我一直停留在初始化那顆 commit,其實開發階段應該是只要在測試環境上機就要算 main 了齁?總之,在切來切去的過程中,我偶然發現有一項功能在切換到還沒有這項功能的分支上時,資料夾會消失,連帶裏頭的檔案也跟著不見了(上 .gitignore 的)這問題非常大,因為當時急急忙忙的,也不確定到底是不是我哪裡操作錯誤,還是真的 git 真的在切換時放掉檔案了,不管哪個,正式上線時千萬不能出這個包。這就是我會要找這個功能的起因。

指令

此方式只能用在 fast-forward 的情況

廢話不多說,如果懶得看的人可以直接看下方這行指令:

1
git fetch <remote> <來源分支>:<目標分支>

例如我現在在 dev 上,想要 FF 更新 main,而 remote 是預設的 origin,就可以下:

1
git fetch origin main:main

這時就可以切換去 main 會發現分支已經和 remote 同步的(up to date)

怎麼做到的?

在開始說之前,相信大家應該都知道 git pull 其實就是 git fetch + git merge。例如:

1
2
3
4
5
6
7
8
9
# 現在在 main 分支上
git pull

# 上面的指令會等於下面(把省略的參數拿出來)
git pull origin main

# 也等於下面(git pull 打包起來的過程)
git fetch origin
git merge origin/main

好的,那之後?其實這只是讓大家知道 git-fetch 指令在做什麼、是怎樣的角色而已。重點在於如果是非快進合併,就不能使用這種方式,因為有可能需要一份工作區的副本解決潛在衝突(This is because a working copy is needed to resolve any potential conflicts.);可是 ff 不會有這問題(都能 ff 了還可以有什麼衝突呢)所以可以這樣玩。

題外話,merge 其實也有不同方式,比較常見的叫做 Three-way merge(三方合併)或剛剛有提過的 fast-forward merge(快進合併);但如果你想一次合併兩個以上的分支,就會用 Octopus merge(章魚式合併)。

結語

以前就覺得 Git 真的是易學難精的工具,簡單的指令可以快速學會怎麼做版本控制,但要做很多進階技巧時才會發現 Git 的強大。最近看到了 git-rereregit-wroktree,還有之前就知道但一直沒用上的 git-bisect(感謝沒機會用XD有空或許也會再寫一篇這個指令的筆記),就佩服當初花十天就做出來的 Linus 大神。

這篇說實話其實也沒解釋什麼,只是說明了指令怎麼用。想看比較完整的話,結尾參考資料上有一個 Stackoverflow 的連結,我就是從那邊學到這招的,歡迎願意看英文的高手連去看看。

你問我封面圖?這是可愛的雪未來(雪ミク,常見譯名是雪初音),大圖更多圖歡迎到之前發表在巴哈的文章〈黏土人 雪未來/雪初音 Snow Parade Ver. No.1250 開箱〉查看。你說不是問這個,是問為什麼放她?沒為什麼,聽說放一張不相干的圖才是這類文章的慣例不是嗎

參考資料