:從remote配置到?jīng)_突解決)
真正讓人頭疼的往往不是寫代碼而是 Git 遠程倉庫操作。我在某團隊帶新人時A同學一臉懵地跑過來明明本地 commit 都成功了git push 卻被拒絕而且報錯信息里全是 detached HEAD、non-fast-forward 這種看似懂又不懂的詞。他問我的第一句話是“遠程倉庫到底是個啥為什么我這一套跟單機版 Git 完全不是一個畫風”。這個問題幾乎每個剛開始協(xié)作的人都會遇到。Git 遠程倉庫操作說白了就是解決一件事讓不同電腦上的 Git 歷史保持同步。但同步這件事背后牽扯到 remote 配置、fetch、pull、push、分支跟蹤、沖突處理、權(quán)限管理任何一環(huán)沒搞明白協(xié)作就會變成災(zāi)難。這篇文章我打算把日常實戰(zhàn)中最常用的遠程操作完整捋一遍包括每一條命令在底層到底做了什么、為什么有些操作要按特定順序來、以及我這些年踩過的真實坑。適合剛學會 commit 還不太敢碰遠程的新人也適合想讓自己的協(xié)作流程更規(guī)范的開發(fā)者。1. 別再背命令了先搞懂 remote 到底是什么1.1 遠程倉庫不是網(wǎng)盤是另一份完整歷史很多人第一次 clone 完項目以為遠程倉庫就是一個存儲代碼的網(wǎng)盤push 就是把文件傳上去pull 就是把文件拉下來。這個理解在簡單場景下勉強能用但一旦遇到分支、沖突、回滾就徹底失靈了。從本質(zhì)上說遠程倉庫是獨立存在于另一臺機器上的一個完整 Git 倉庫。它和你本地倉庫一樣包含對象數(shù)據(jù)庫、引用分支、標簽、HEAD 指針這些東西。你 clone 下來的不是“一份代碼快照”而是那個倉庫的全部提交歷史。這也是為什么 Git 遠程倉庫操作的核心不是文件同步而是提交歷史的同步。我用一個生活類比解釋給 A同學聽本地倉庫像你的工作臺遠程倉庫是另一個同事的工作臺。你們不是通過互相發(fā)文件來協(xié)作而是通過交換“記事本”——每一頁記錄一個變更。只要雙方記事本上的頁碼對得上協(xié)作就順暢對不上就需要先對齊頁碼fetch/pull再把自己新寫的頁面貼上去push。1.2 origin 這個名字是從哪冒出來的剛開始用 Git 的人總會疑惑為什么大家都把遠程倉庫叫 origin是自己起的嗎其實 origin 只是當你執(zhí)行 git clone 時Git 默認給唯一那個遠程倉庫起的名字。它沒有任何魔法含義就是個默認別名。remote 的真實身份是一串 URL加上一組遠程跟蹤分支引用。你運行 git remote -v 時看到的兩行地址fetch 和 push 地址才是遠程倉庫的真實位置。如果 push 地址和 fetch 地址不同還可能出現(xiàn)“能拉不能推”的怪事。這里有個關(guān)鍵點需要理解remote 的名字和分支名沒有關(guān)系。origin 只是指代“那臺機器”至于那臺機器上叫 master、main、develop 還是 release/v1完全看對方倉庫自己的分支結(jié)構(gòu)。你甚至可以給同一個 URL 起多個名字或者給同一個倉庫配置兩個不同名字的 remote這是合法的。1.3 配置多遠程你需要先有拓撲意識真實協(xié)作里單人單倉庫的“origin 一條路”遠遠不夠。開源項目的標準場景是 fork 后配置兩個 remote一個是上游主倉庫一個是你自己的倉庫。這時候很多人就會犯迷糊哪個是 origin該往哪個 push我的習慣是把 fork 出來的自己的倉庫保持叫 origin把官方上游倉庫叫 upstream。這樣語義清晰origin 是我能 push 的地方upstream 是我要跟蹤和同步的地方。添加 upstream 只需要一條命令git remote add upstream gitgit.example.com:team/project.git多 remote 的難點不在于添加而在于你要時刻清楚當前分支在跟哪個遠程的哪個分支對應(yīng)。否則就可能發(fā)生“我明明推的是自己的分支怎么跑到別人倉庫里了”的慘案。所以每次操作前先花十秒想清楚拓撲本地有哪幾個遠程、當前分支跟蹤的是誰、這次提交希望進入哪個歷史。2. Clone 之后的第一件事盤一盤你的遠程倉庫2.1 git remote -v這是你的第一張地圖我接手任何項目的第一件事永遠是在項目根目錄執(zhí)行 git remote -v。這條命令會列出當前倉庫配置的所有遠程名稱與地址。如果輸出為空說明這個目錄雖然是個 Git 倉庫但還沒有和任何遠程倉庫建立關(guān)系。這時候 git push / git pull 都會報“No configured push destination”或類似錯誤。輸出非空后我會再執(zhí)行 git branch -vv查看本地分支和遠程跟蹤分支之間的對應(yīng)關(guān)系。兩行輸出合起來就能拼出項目協(xié)作的基本拓撲。很多莫名其妙的 push 失敗其實在第一張“地圖”上就能發(fā)現(xiàn)端倪比如本地分支根本沒有設(shè)置上游比如 remote 的 push 地址寫錯了。養(yǎng)成先看 remote -v 再加 branch -vv 的習慣能幫你省掉后面大量的排查時間。2.2 添加、改名、換地址三個高頻操作遠程地址不是一成不變的。公司搬家換 Git 服務(wù)器、項目從一套協(xié)作平臺遷到另一套都會導(dǎo)致遠程 URL 失效。這時候不要刪掉倉庫重新 clone改地址就行g(shù)it remote set-url origin https://git.example.com/team/project.gitgit remote rename 用于給遠程改名。比如一開始默認 origin后來團隊想統(tǒng)一叫 central可以執(zhí)行g(shù)it remote rename origin central注意 rename 會自動更新已配置的跟蹤分支引用這個動作比手動刪了再加更安全。添加遠程是另一種高頻場景前面提到的 upstream 就是典型。git remote add 的完整語法是git remote add name url高頻率操作里最容易出錯的不是命令本身而是“是否要添加 remote 還是直接 clone”。如果你本地已經(jīng)有一份完整代碼目錄但又想從某個遠程倉庫拉取東西git remote add 是對的如果你是想在一臺新電腦上獲取項目副本git clone 遠勝于先建空倉庫再 add remote。2.3 HTTPS、SSH以及一個容易被忽略的配置點選 HTTPS 還是 SSH 這個問題幾乎每周都有人問。我的答案很直接優(yōu)先 SSH。原因不是 HTTPS 不安全而是 SSH 密鑰可以避免你每一次 push/pull 都輸密碼。尤其是當你使用 commit 簽名、頻繁推送時HTTPS 的憑證交互會打斷思路。和 SSH 相關(guān)的實操細節(jié)經(jīng)常被忽略ssh-keygen 生成密鑰后你配置的 remote URL 必須是 SSH 格式如 gitgit.example.com:team/project.git而不是 https:// 開頭??珊芏嗳嗣髅髋浜昧嗣荑€remote 地址還是 HTTPS結(jié)果 SSH 協(xié)議根本沒被用到。另外說一個容易踩坑的配置項url. .insteadOf。這個配置可以讓你在 clone 時寫 HTTPS但實際走 SSH或者反過來。比如git config --global url.gitgit.example.com:.insteadOf https://git.example.com/這個配置的妙處在于你從文檔里復(fù)制下來的 HTTPS 地址不用改Git 會自動替換成 SSH。但它也會帶來困擾某些托管平臺對 SSH 和 HTTPS 的權(quán)限校驗不同一旦全局配置了 insteadOf可能出現(xiàn)“明明賬號有權(quán)限卻 push 失敗”的詭異問題。排查遠程問題時記得用 git config --list 看看是不是被這個配置影響了。3. fetch、pull、push遠程協(xié)作的三駕馬車但方向千萬別搞反3.1 fetch把遠程狀態(tài)“搬”到本地的隱藏區(qū)域git fetch 是我個人用得非常頻繁的命令但新手往往不太理解它到底干了什么。fetch 會把遠程倉庫的分支狀態(tài)、提交對象、標簽都下載到本地然后保存在“遠程跟蹤分支”里。這些分支不會出現(xiàn)在你正常的工作區(qū)而是以 origin/main、origin/feature/x 這樣的形式存在于引用命名空間中。很多人以為 fetch 之后本地代碼就變成遠程最新了這是錯誤理解。fetch 只是更新了“遠程在某一時刻長什么樣”的本地記錄你的工作區(qū)、當前分支、暫存區(qū)完全不受影響。這是 fetch 最安全的地方你可以隨時查看遠程別人提交了什么而不必擔心自己的半成品代碼被打斷。在我負責的流程里fetch 通常作為 pull 的前置步驟單獨執(zhí)行或者用 git fetch --prune 來同步清理遠程已刪除分支的本地記錄。--prune 參數(shù)很實用下面講幽靈分支時會細說。3.2 pull一條命令背后的合并動作git pull 是 fetch 加上合并兩個動作的合體。它先執(zhí)行 fetch然后把遠程跟蹤分支合并到當前分支。這里的“合并”默認是 merge不是 rebase。這個默認行為導(dǎo)致了很多“git pull 之后突然多了一個 Merge commit”的現(xiàn)象尤其在多人長期共用一個分支時。理解 pull 的兩個動作很重要。假設(shè)你在 main 分支上git pull 實際做了git fetch origin git merge origin/main因為你當前的 main 跟 origin/main 有共同祖先但也有各自的新提交merge 會把兩邊歷史縫合起來生成一個新的合并提交。如果你想讓本地歷史更線性可以配置git config --global pull.rebase true這樣 git pull 就成了 fetch rebase。關(guān)于 merge 和 rebase 的取舍我會在第 5 章展開這里先記住一個結(jié)論沒有永遠正確的策略只有適不適合團隊協(xié)作習慣的策略。3.3 push不是上傳是請求合并git push 是最直觀但也是風險最大的遠程操作。它的語義是把本地分支的新提交推送到遠程對應(yīng)分支讓遠程分支指針前進到本地分支的位置。但遠程倉庫不是一定接受你的推進它有一個校驗規(guī)則非 fast-forward 的更新會被拒絕。所謂 non-fast-forward簡單說就是“你要推進的遠程分支基于的歷史已經(jīng)不再是遠程當前歷史”。這通常意味著遠程分支上陸續(xù)有了別人的新提交而你的本地分支還停留在舊位置。Git 拒絕你是為了防止你覆蓋掉別人的提交。這是保護機制不是 Bug。理解了 push 的真實語義你就明白為什么 push 之前最好先 pull/rebase你的分支歷史如果和遠程歷史完全對齊push 就是一次快速前進如果沒對齊你需要先整合遠程的新提交再推送自己這部分。3.4 跟蹤分支與 upstream讓命令少打一半每次 push 都要寫git push origin main太啰嗦跟蹤分支就是來解決這個問題的。當你用git push -u origin main推送過一次后本地 main 分支就記錄了它的 upstream 是 origin/main。之后你再執(zhí)行 git pull 或 git pushGit 會自動識別該往哪里推、從哪里拉。upstream 的信息存在本地分支配置里你可以用 git branch -vv 查看。每次新建分支時我建議第一時間明確它的 upstream尤其在多人協(xié)作項目中。有幾種情況容易讓 upstream 變得混亂本地分支名跟遠程分支名不一樣、同一個本地分支跟蹤了另一個本地分支、遠程分支被刪除但本地配置還指向它。遇到這些情況可以用 git branch --unset-upstream 清掉跟蹤關(guān)系再用 git push -u 設(shè)置新的。3.5 為什么我堅持 pull 之前先看一眼 fetch 結(jié)果雖然 git pull 一條命令很方便但我自己在處理關(guān)鍵分支時還是習慣先 fetch 再手動處理。原因很簡單pull 的合并是“自動的”而自動合并失敗時你已經(jīng)處在合并中間狀態(tài)有些人會驚慌失措。fetch 之后的信息非常明確。git fetch 會打印出哪些分支有新提交、提交作者是誰。這時候你可以冷靜判斷要不要馬上拉取會不會跟我的改動沖突能不能先讓我本地提交整理完再說這種“先搞清楚情況再動手”的節(jié)奏對多人同時改一個文件的高壓場景特別重要。它能讓你在沖突發(fā)生之前就有了心理準備和應(yīng)對預(yù)案。4. 遠程分支之間那些繞不開的規(guī)則4.1 遠程分支的完整引用名本地分支的引用名形態(tài)是 refs/heads/main遠程跟蹤分支則是 refs/remotes/origin/main。你在終端里能看到的 origin/main其實是后者的縮寫。這個完整名字解釋了為什么你在本地創(chuàng)建一個叫 origin/main 的分支時會報錯它和遠程跟蹤引用的命名空間沖突。理解引用名還有一個實際幫助你可以直接查看遠程分支指向的提交比如 git log origin/feature/login 和 git log feature/login 對比就能看到“遠程已有哪些提交”和“我本地還有哪些提交”之間的差異。這種對比在需要確認“我的分支是不是落后了”時非常高效。4.2 為什么你 push 的分支在別人那里叫別的名字git push origin feature/login 這條命令的完整語義是把本地 feature/login 分支推送到遠程的 feature/login 分支。如果你想推送到遠程不同名字的分支可以寫成git push origin feature/login:feature/authentication左邊是本地分支右邊是遠程分支。這個語法很冷門但在一些特殊情況比如遠程分支命名規(guī)范臨時調(diào)整很有用。真正讓新人困惑的是另一種情況明明我 push 了但同事說在遠程看不到。多半原因是你的 push 只是把分支上傳到了遠程倉庫但遠程倉庫的默認合并請求頁面只會顯示那些跟默認分支有差異的分支名稱。如果你推送后沒人提合并請求分支自然不會被別人注意到。這是協(xié)作流程問題不是 Git 命令問題。4.3 刪除遠程分支和本地分支要分開刪除本地分支用 git branch -d feature/login刪除遠程分支則是git push origin --delete feature/login這兩個動作互不相關(guān)。我見過很多團隊負責人只刪了遠程分支沒提醒大家清理本地分支結(jié)果一段時間后每個人本地都堆了一大堆已經(jīng)合并過的舊分支。反過來也有只刪本地不刪遠程的遠程倉庫成了垃圾場。在多人協(xié)作項目中刪除分支前最好確認這個分支的改動是否已經(jīng)合并到主分支。強制刪除用 -D但請想清楚一旦別人已經(jīng)基于這個分支開發(fā)強刪會破壞他們的歷史。4.4 分支名撞車與大小寫帶來的坑Git 分支名是區(qū)分大小寫的但某些操作系統(tǒng)文件系統(tǒng)不區(qū)分。比如本地有 Feature/Login 和 feature/login 兩個分支在 macOS 默認文件系統(tǒng)上就可能出現(xiàn) checkout 錯亂。遠程倉庫通常也區(qū)分大小寫但如果托管平臺對分支名規(guī)范有限制大小寫混用會在 push 時產(chǎn)生詭異報錯。我的建議很簡單全團隊統(tǒng)一分支命名規(guī)范全部小寫用斜杠做目錄層級。比如 feature/用戶端-登錄雖然不規(guī)范但至少統(tǒng)一。更通用的是 feature/login、bugfix/payment-timeout 這種。別小看命名遠程協(xié)作一半的混亂都來自名字。5. 多人協(xié)作現(xiàn)場從提交沖突到代碼評審5.1 一個標準的提交流程長什么樣我推薦團隊新人先按這個順序走完一輪再談優(yōu)化git fetch origin git checkout -b feature/xxx origin/main git add . git commit -m feat: ... git push -u origin feature/xxx這里的關(guān)鍵動作是git checkout -b feature/xxx origin/main它從遠程最新的 main 創(chuàng)建新分支而不是從你自己可能已經(jīng)落后的本地 main 創(chuàng)建。這一步能減少大量不必要的沖突。提交后用 git push -u 推送然后到遠程平臺創(chuàng)建合并請求。代碼評審?fù)ㄟ^后再合并。這套流程里的每一步都有明確目標fetch 是為了獲取最新狀態(tài)基于 origin/main 是為了確保起點干凈合并請求是為了讓代碼在進入主分支前有人審閱。別省略任何一個環(huán)節(jié)。5.2 沖突產(chǎn)生的根本原因很多新人把沖突當成“事故”其實沖突是 Git 正常工作的證明。沖突只發(fā)生在“兩個人基于同一個歷史分別修改了同一處內(nèi)容而 Git 無法自動決定該保留哪份”的時候。舉個例子你和同事都是從 main 的提交 A 拉出的分支。你在自己分支上修改了登錄函數(shù)第 10 行同事在另一個分支上也修改了第 10 行。當你們倆的分支先后合并回 main 時Git 發(fā)現(xiàn)同一行有兩個不同的新版本不知道聽誰的于是把決定權(quán)交給你。從遠程操作的角度看沖突更多發(fā)生在 pull 和 merge/rebase 階段。比如本地 main 落后遠程你執(zhí)行 git pull而遠程的改動恰好撞上你本地未提交的改動。這就是為什么我強烈建議pull 之前先提交或者 stash不要帶著半成品去拉取。5.3 merge vs rebase我的選擇邏輯關(guān)于 merge 和 rebase 的爭論每個團隊都能吵三天。我的原則是在對外共享分支上堅決用 merge在還沒推送過的個人分支上可以用 rebase。merge 的優(yōu)點是不改寫歷史保留所有真實發(fā)生的分叉和合并適合多人協(xié)作的主分支。缺點是會產(chǎn)生大量合并提交歷史圖看起來很亂。rebase 的優(yōu)點是把我的提交“重放”到目標分支頂端歷史是線性的、干凈的缺點是改寫提交對象如果這些提交已經(jīng)被別人使用就可能造成他們的歷史錯亂。具體到遠程協(xié)作我最常用的組合是個人功能分支上git pull --rebase origin main保持線性合并到主分支時用 merge生成一個明確的合并點。不要在已經(jīng)推送到遠程的分支上隨意 rebase這是底線。5.4 解決沖突的實操步驟與心態(tài)真到?jīng)_突發(fā)生時不要慌。Git 會把你標記為沖突的文件同時保留雙方內(nèi)容并在文件里用 、、 標出沖突區(qū)域。你需要做的是打開文件、逐段決定保留誰、刪除標記、git add 該文件然后繼續(xù)合并或完成 rebase。merge 沖突和 rebase 沖突的解決流程稍有不同。merge 中常用git add 沖突已解決的文件 git commitrebase 中每一步?jīng)_突解決后需要git add 沖突已解決的文件 git rebase --continue如果中途想放棄可以分別用 git merge --abort 或 git rebase --abort 回到操作前狀態(tài)。這個命令是很多人的救命稻草我建議每個拿到 Git 的人都先記住它出錯時不是趕忙改文件而是先想清楚能不能回到安全狀態(tài)。5.5 何時才能用強推git push --force 是遠程操作中風險最高的命令。它的本質(zhì)是讓遠程分支指針直接指向你指定的提交無視遠程當前的歷史。一旦強推別人的提交可能被徹底抹掉。強推的唯一合理場景是你明確知道遠程分支上那些多余的提交已經(jīng)沒有任何價值而且團隊達成共識。比如某些自動化流程把錯誤提交推到臨時分支你想重置這個分支。即便如此也更推薦 --force-with-lease這個選項會在遠端狀態(tài)和你上次看到的狀態(tài)一致時才允許強推能避免誤傷別人新推的提交。我在團隊里定了一條規(guī)矩任何情況下不要把帶 -u 的強推用到共享主分支上。主分支的修復(fù)可以新開分支可以 revert就是不能 force push。這條規(guī)矩救過團隊很多次。6. 遠程倉庫的衛(wèi)生與安全tags、大文件、幽靈引用6.1 tag 不是普通分支推送方式也不同標簽在遠程協(xié)作里經(jīng)常被忽略但它承擔著版本發(fā)布的重要作用。tag 是某個提交的固定別名它不像分支那樣會移動。本地打的標簽不會自動推送到遠程需要顯式操作git push origin v1.0.0批量推送所有標簽用 git push origin --tags。刪除遠程標簽git push origin --delete v1.0.0這里容易踩坑的是如果本地標簽名和遠程已有標簽重名但指向的提交不同push 會被拒絕。發(fā)布流程里建議先拉取遠程標簽最新狀態(tài)再打新標簽。打錯標簽后也要及時同步到遠程否則后續(xù)部署系統(tǒng)會讀取到錯誤版本。6.2 遠程分支刪除后本地還能看到“幽靈分支”前文提過 git fetch --prune。當你或同事刪除了遠程分支后如果你只在本地執(zhí)行 git fetchGit 并不會自動清理本地緩存的遠程跟蹤分支。于是你執(zhí)行 git branch -r 時還能看到已經(jīng)不存在于遠程的 origin/feature/old。清理方法是git fetch --prune origin這條命令會刪除本地對應(yīng)已消失的遠程跟蹤分支引用并打印出刪除了哪些分支。我建議把它加入日常習慣尤其是團隊分支生命周期很短、合并后立即刪除的場景。否則半個月后你本地的遠程分支列表可能比遠程倉庫還厚。6.3 大文件是怎么把遠程倉庫堵死的Git 的設(shè)計初衷是文本代碼而不是二進制大文件。當有人不小心把幾百 MB 的視頻、壓縮包提交進倉庫所有同事 clone、fetch 時都要把這份歷史下載下來倉庫體積很快膨脹到幾個 GB。這種問題的麻煩在于即使后來刪除了大文件它仍然存在于歷史提交里每次 clone 還是要下載。解決思路是git filter-repo這類歷史重寫工具但歷史重寫意味著所有協(xié)作者的遠程倉庫都要重新同步屬于大型手術(shù)。最有效的辦法是預(yù)防加入 .gitignore安裝大文件檢查工具在代碼評審時留意二進制文件已經(jīng)需要存儲大文件的場景改用大文件存儲擴展而不是直接進 Git 倉庫。遠程倉庫操作不能只考慮“能不能提交”還要考慮“提交之后別人承受什么成本”。6.4 權(quán)限與密鑰最容易被忽視的協(xié)作風險遠程操作的安全問題繞不開 SSH 密鑰和部署密鑰。很多團隊習慣把所有開發(fā)者都加到同一個倉庫管理員組省事但風險極大。合理做法是給不同角色分配不同權(quán)限等級能直接 push 主分支的人越少越好普通開發(fā)者通過合并請求進入代碼。另一個隱蔽風險是個人機器上配置了錯誤的 remote 地址導(dǎo)致代碼被推到錯誤的倉庫。我見過因為 URL 復(fù)制錯把內(nèi)部項目推到一個公共倉庫的案例雖然及時刪除但已經(jīng)造成了不可控傳播。所以 git remote -v 不只是新手要看的命令老手同樣要在 push 敏感項目前會看一眼。7. 三個真實翻車現(xiàn)場和一張保命檢查清單7.1 案例手滑把改動推到了錯誤分支某次我從本地 feature/a 切到 main忘了切回來就把實驗性改動 commit 了然后又順手 git push。結(jié)果實驗代碼直接推到了遠程 main?,F(xiàn)場同事跑過來指著倉庫大喊“main 上怎么多了一個亂七八糟的提交”。那次修復(fù)用 git revert 生成一個反向提交把 main 恢復(fù)到正常狀態(tài)。這里我選擇 revert 而不是 reset force push是因為 main 是共享分支reset 會改寫歷史影響所有同事revert 是向前增加一個提交遠程歷史不會被重寫是最安全的修復(fù)路徑。這類事故給我的教訓是push 真正屬于共享分支前必須確認當前分支名。7.2 案例同事的分支被“清理”了有次團隊做一次大范圍分支清理用了git push origin --delete刪除了一批看起來已經(jīng)合并的分支。結(jié)果后來發(fā)現(xiàn)其中一條分支其實只合并了一部分另一位同事還在那條分支上繼續(xù)開發(fā)。因為遠程分支被刪他本地 push 時關(guān)聯(lián)失敗現(xiàn)場一片混亂。最后只能從同事本地找到那條分支的完整歷史重新推回遠程。這件事讓我意識到刪除遠程分支前要核對合并狀態(tài)不能只看列表。后來我們改用腳本列出所有已合并分支人工二次確認后才刪除。7.3 案例clone 速度慢到懷疑人生團隊加入一位新同學第一次 clone 項目花了快一個小時。排查時發(fā)現(xiàn)倉庫里面有幾份幾百 MB 的設(shè)計稿壓縮包這些文件躺在歷史提交里即使后來刪了每次 clone 都要重新下載整份 Git 歷史。我們用歷史重寫工具徹底清理了那些大文件并讓所有同事重新同步遠程倉庫clone 時間才恢復(fù)正常。這個案例給我的經(jīng)驗是遠程倉庫操作不只是你自己機器上的命令它關(guān)乎團隊每個成員的身心健康。提交大文件之前多想幾秒比事后清理容易一萬倍。7.4 我每次 push 前會過的檢查項最后分享一張我自己的保命檢查清單。不是每次 push 都逐條執(zhí)行但凡是推送到共享主分支、發(fā)布分支或者推送涉及敏感項目時我一定會快速過一遍git status看清楚當前分支名和未提交改動。git branch --show-current確認自己在哪個分支。git remote -v確認遠程地址沒有串。git log --oneline -3確認要推的東西確實是我想推的。git pull --rebase先把遠程新提交整合進本地再 push。如果是合并請求場景確認目標分支沒有選錯。這套清單不復(fù)雜但能過濾掉九成以上的低級事故。協(xié)作這件事慢幾秒是為了后面不浪費幾個小時。我最后再補充一句個人的體會遠程倉庫操作練到后來拼的并不是命令記得多熟而是你對自己正在改哪份歷史、打算讓它進入哪條主線有沒有清晰的判斷。每次操作前多想一步比任何花哨技巧都管用。