作全流程指南)
從一個小白到能正常把代碼放到GitHub上這個過程中的坑比想象中多。很多教程默認你熟悉命令行直接甩給你一串 git 命令讓你復制粘貼結(jié)果頁面刷新后什么都沒有發(fā)生既不知道錯在哪也不知道下一步該干嘛。這篇文章試圖換一種方式不堆砌命令列表而是把GitHub最核心的邏輯拆開講清楚再一步步帶你完成從安裝、建倉庫、提交代碼到發(fā)起 Pull Request 的完整流程順帶還會講幾個日常開發(fā)中必踩的坑。1. 先搞清楚GitHub到底在解決什么問題1.1 版本管理為什么不是多存幾個文件不少新手第一次接觸GitHub時最大的困惑是我明明可以用項目_最終版_v3.zip這種命名方式來管理代碼為什么要用一個看起來這么復雜的工具你可以先做一個很簡單的實驗分別在兩個文件里保存同一段代碼的不同版本然后試圖回憶起為什么第二個版本刪掉了一個函數(shù)為什么第三個版本改了變量名。這種回憶往往以失敗告終因為你沒有記錄改動的原因、改動的時間以及每處改動的上下文。GitHub的核心價值是給整個項目的變化過程建立一個完整的、可追溯的記錄。它不僅保存了每個文件的最新內(nèi)容還保存了歷史中的每一次修改、誰改的、什么時候改的、改之前是什么樣、為什么改通過提交說明。這套機制的專業(yè)名稱是版本控制但你可以把它理解成一個不會丟失任何歷史痕跡的存檔點系統(tǒng)。1.2 本地Git和云端GitHub的分工這里還有一對經(jīng)常被混淆的概念Git 和 GitHub 不是同一個東西。Git 是一個運行在你電腦本地的版本管理工具負責跟蹤文件變化、創(chuàng)建提交記錄、管理分支。它不依賴網(wǎng)絡也不依賴任何網(wǎng)站。你在本地做的一切操作包括 commit、branch、merge都是在自己電腦上完成的。GitHub 則是建立在 Git 之上的一個云端協(xié)作平臺。你本地的 Git 倉庫需要推送到遠程端其他人才能看到、協(xié)作和同步。以一個實際項目為例。你在本地用 Git 初始化一個倉庫每寫一段穩(wěn)定的代碼就git commit一次形成一個存檔點。如果你想把這個項目和別人共享或者希望自己在另一臺電腦上繼續(xù)寫就需要把倉庫推送到 GitHub 上。遠程倉庫的存在使多人協(xié)作成為可能——每個人在各自的本地倉庫上工作通過 push 和 pull 同步修改。很多教程一上來就讓新手安裝 Git 然后立刻開始敲命令但省略了對這套基本邏輯的鋪墊。結(jié)果就是新手在操作時根本不知道自己在和本地組件交互還是在和云端組件交互出錯后更沒法定位問題出在哪一層。2. 新手上路第一步創(chuàng)建倉庫、克隆代碼與第一次提交2.1 前置準備安裝Git與配置用戶信息工欲善其事必先利其器。不管你是哪個操作系統(tǒng)第一步都是把 Git 裝上。Windows 用戶可以從官方渠道下載安裝包安裝時建議保持默認選項注意選擇能夠在右鍵菜單中使用 Git Bash這類選項后面操作會更順手。macOS 用戶如果裝有系統(tǒng)自帶的 command line tools通常自帶 Git不確定的話可以先在終端里輸入git --version看一眼。安裝完成后你需要做的第一件事不是創(chuàng)建倉庫而是配置身份信息git config --global user.name 你的名字 git config --global user.email 你的郵箱這段配置的用途是給每一次提交記錄打上標簽告訴無論你還是協(xié)作者這次改動出自誰手。如果跳過這步你第一次 commit 時大概率會看到一個提示信息告訴你需要先設置 user.name 和 user.email。這里有一個小技巧既然是全局配置建議你認真考慮用哪個郵箱。如果打算長期參與開源項目可以專門用一個不含太多隱私信息的郵箱或者使用平臺提供的隱私郵箱功能避免個人郵箱暴露在公開倉庫的歷史記錄里。2.2 創(chuàng)建倉庫的兩種路徑路徑一先在 GitHub 云端創(chuàng)建倉庫然后克隆到本地。登錄 GitHub 后點擊右上角的New repository會看到一個表單要你填倉庫名、描述、可見性public / private以及是否要自動添加 README 文件。完成之后你會進入一個空倉庫頁面上面顯示了幾條推薦命令。最常見的方式是復制倉庫的 HTTPS 地址然后在終端里執(zhí)行g(shù)it clone https://github.com/用戶名/倉庫名.git這條命令會把遠程倉庫完整復制到當前目錄下包含所有歷史記錄和分支。所謂克隆本質(zhì)上就是一次完整的下載。路徑二在本地先用 Git 初始化再把內(nèi)容和云端做關(guān)聯(lián)。這在你有現(xiàn)成代碼、但還沒創(chuàng)建遠程倉庫時使用。操作順序是先在 GitHub 上創(chuàng)建一個空倉庫不勾選任何初始化選項然后回到項目目錄cd 你的項目目錄 git init git add . git commit -m first commit git remote add origin https://github.com/用戶名/倉庫名.git git push -u origin main這兩種路徑?jīng)]有本質(zhì)優(yōu)劣。如果是一個全新項目我其實更推薦路徑一也就是先建倉庫再克隆因為它會自動幫你處理 README、分支名等基礎(chǔ)設置減少很多新手最容易踩的分支名不一致的問題。2.3 第一次提交的完整操作假設你已經(jīng)通過克隆或初始化獲得了一個本地 Git 倉庫接下來要做的就是把文件裝進存檔點。整個流程由幾個固定步驟組成查看倉庫狀態(tài)。將改動加入暫存區(qū)。提交改動并附上說明。推送到遠程倉庫。具體命令git status git add . git commit -m 添加了項目初始代碼 git push對新手來說理解暫存區(qū)staging area是理解 Git 的一個關(guān)鍵點。你可以把暫存區(qū)想象成一個購物車。你從貨架上拿下商品修改文件后它們并不會自動進入購物車而是需要先git add把它們放進去。git commit相當于結(jié)賬明確記錄這一單買的是什么。而git push才是把這批商品從本地快遞到云端倉庫。為什么設計這個中間環(huán)節(jié)因為有時候你在一個下午改了很多文件但這些文件不一定都屬于同一個邏輯單元。比如一個文件修了登錄框的 bug另一個文件加了一個新頁面你可能希望它們分成兩次提交便于以后回查歷史。如果所有改動混作一團直接提交以后的排查成本會很大。實際開發(fā)中我?guī)缀趺看蝕it change的文件都不止一個。合理的拆分邏輯是一次提交只做一件事。修改了接口文檔就不要夾帶私貨改了一行跟接口無關(guān)的代碼。這類習慣越是早期養(yǎng)成后面對你審視項目和排查問題的幫助就越大。3. 分支操作是協(xié)作的核心從本地實驗到Pull Request全流程3.1 分支的本質(zhì)平行時空新手一開始接觸 Git 時很容易認為所有的改動都在一條線上依次排隊。但這個模型很快就會被團隊協(xié)作打破——兩個人同時修改同一個文件該怎么辦答案就是分支。分支的本質(zhì)是讓一份代碼同時存在多個平行時空。在每個時空中代碼可以從同一個起點開始朝不同的方向演化互不干擾。完成后再把不同時空中的改動合并回主線。以最常見的工作流為例main分支是項目的正式版本要求時刻處于可運行狀態(tài)。當你開始開發(fā)一個新功能時從main拉一個功能分支在這個分支上做實驗。功能開發(fā)完畢后通過合并操作把改動帶回main。這樣做的好處很明顯主線永遠穩(wěn)定你的實驗和潛在 bug 不會污染正式版本主線的維護者也有機會在合并前至少看一遍改動。3.2 本地分支操作基礎(chǔ)從當前分支新建并切換到一個新分支最常用的命令是git checkout -b feature/login-page這條命令等價于兩條命令的組合git branch feature/login-page創(chuàng)建分支git checkout feature/login-page切換分支。在新版 Git 中也可以使用git switch -c feature/login-page效果一致。完成開發(fā)后把當前分支的改動提交并推送git add . git commit -m 完成登錄頁面布局 git push -u origin feature/login-page這里的-u參數(shù)設置了一次性關(guān)聯(lián)關(guān)系告訴 Git當前分支和遠程分支建立了跟蹤關(guān)系。之后你再在這個分支上繼續(xù) push就不用每次帶上完整參數(shù)了。3.3 Pull Request不是直接合并而是發(fā)起請求分支合并之間有一個非常重要、也非常體現(xiàn) GitHub 價值的概念Pull Request簡稱 PR在有些平臺上也叫 Merge Request。要理解 Pull Request可以先區(qū)分合并和請求合并這兩件事。在本地命令行里你可以直接執(zhí)行g(shù)it merge把兩個分支合并不會經(jīng)過任何審批流程。但如果是多人協(xié)作尤其是團隊規(guī)模較大時沒有人希望誰都可以一聲不吭地把代碼改到主分支上。這時 Pull Request 就登場了——它不是一個 Git 命令而是 GitHub 提供的一種協(xié)作機制。工作流程是你在本地完成功能開發(fā)推送分支到遠程倉庫。在 GitHub 網(wǎng)頁上發(fā)起 Pull Request申請把這個分支合并到另一個目標分支。Pull Request 頁面會清楚展示改動內(nèi)容——哪些文件變了、每個文件對應哪幾行代碼被增刪。團隊成員可以在這個頁面里逐行評論、討論。倉庫維護者審核完畢后點擊合并按鈕代碼才真正進入目標分支。相比直接合并Pull Request 的意義不只是審批流程。更重要的是它把代碼審查這個動作沉淀成了一種可見的工作流而不是靠團隊口頭溝通把關(guān)。對于開源項目來說Pull Request 還是外部貢獻進入項目的主要入口——陌生人不能直接改動你的倉庫但可以 fork 一份后在這個原倉庫上發(fā)起合并請求。有經(jīng)驗的開源維護者審閱一份 Pull Request通常會看三件事改動是否解決了問題描述、它會不會引入回歸、是否有遺漏的測試場景。你要知道的是寫清楚 PR 描述是減少協(xié)作摩擦的極高性價比操作。好的描述里至少應該包含改動目的、改動內(nèi)容、測試方式、關(guān)聯(lián)的 issue 編號。我見過無數(shù)人 PR 標題只寫fix bug或update這等于把應該由自己承擔的上下文轉(zhuǎn)嫁給每個看 PR 的人大大降低協(xié)作效率。4. 實際協(xié)作中的高頻場景沖突、回滾、忽略文件的處理4.1 合并沖突不是洪水猛獸而是正常機制如果你參與過團隊項目遲早會撞上合并沖突merge conflict。沖突的本質(zhì)是兩個分支修改了文件的同一行并且都認為自己才是正確版本Git 無法自行判斷應該保留哪個只能把決定權(quán)交給你。觸發(fā)沖突時Git 會在沖突文件里插入特殊標記告訴你在哪個位置出現(xiàn)了分歧。打開文件后你會看到類似這樣的內(nèi)容 HEAD 這里是當前分支的改動 這里是對方分支的改動 feature/branch-name你需要做的就是手動決定保留哪一邊的內(nèi)容或者融合兩者然后刪掉這些標記行保存文件再執(zhí)行一次提交。解決沖突時我有一條幾乎不會出錯的建議絕不只憑直覺亂改??吹?jīng)_突后先確認這兩處改動的意圖分別是什么。很多情況下沖突并不可怕只需要把兩邊的改動都保留下來放在不同的位置就行——它們只是恰好出現(xiàn)在了同一行上而已。一個降低沖突頻率的實用習慣是頻繁地同步遠程改動。你 fork 一個功能分支出來前應該先git pull一下main分支的最新內(nèi)容。開發(fā)過程中每次覺得到了一個小節(jié)點也建議再 pull 一次。你的分支存活時間越長沖突的概率就越高。越早暴露沖突解決起來代價就越小。4.2 沒救回來的操作撤銷、回退與后悔藥開發(fā)中經(jīng)常遇到的一種慌神場景是提交了不該提交的東西或者發(fā)現(xiàn)自己的代碼寫錯了想回退。Git 提供了好幾種后悔藥但每種藥的適用場景完全不同。如果你只是最近一次提交想改掉比如提交信息寫錯了git commit --amend這條命令會把暫存區(qū)里新的改動加入上一次提交同時允許你重新修改提交說明。前提是這次提交還沒有被推送到遠程或者推送后還沒有被別人拉走。如果改動已經(jīng)推送到公共分支且被人引用了用--amend就會造成歷史不一致帶來更大的麻煩。如果是想回退某次已經(jīng)推送到遠程的提交用得最多的是git revertgit revert commit-idrevert的邏輯不是刪除那次提交而是創(chuàng)建一個新的提交把之前的改動反向翻轉(zhuǎn)回來。這聽起來有點繞但它的好處是歷史不會被改寫等于在時間線上加了一個取消記錄。這對于協(xié)作分支來說更安全。如果你還沒有把改動推送到遠程只是想徹底抹掉最近的幾次提交git reset --hard HEAD~2這條命令會直接把 HEAD 指針退回到兩個提交之前被重置掉的那些改動會徹底消失。注意--hard是很強的操作執(zhí)行后未提交的工作區(qū)改動也會一并丟棄。我第一次實踐 reset 后就吃過一次虧把一整天的工作內(nèi)容全部沖掉了當時心里非常崩潰。所以新手在自己不熟悉的命令前多留個心眼先用--soft或者--mixed這些溫和模式試試看或者先做一次 branch backup給自己留退路。4.3 .gitignore讓倉庫只保留該保留的東西新建項目時有一個文件幾乎是必需品.gitignore。這個文件的作用是告訴 Git 忽略哪些文件或目錄。在使用 Git 的過程中一開始會覺得理所當然——所有文件都被跟蹤不是挺好嗎但很快就會出現(xiàn)下面的情況本地項目目錄里多了node_modules依賴包目錄、編譯輸出目錄、IDE 自動生成的配置文件、日志文件、本地環(huán)境變量文件。如果這些都被提交到倉庫就會出現(xiàn)幾個問題。首先是大倉庫膨脹。一個node_modules目錄動輒幾百兆每次提交、拉取都會變得很慢。其次是噪音每次增減依賴都會讓倉庫的 diff 變得不可讀卷進大量無關(guān)文件的改動。最后是安全風險本地環(huán)境變量文件里往往存著密鑰、口令等敏感信息。因此一個好的.gitignore至少要覆蓋下面幾類內(nèi)容依賴目錄如node_modules/編譯輸出目錄如dist/、build/系統(tǒng)文件與 IDE 配置環(huán)境變量與密鑰文件如.env、*.pem日志文件如*.logGitHub 官方對此維護了一套常用模板你可以在項目初始化時選擇對應語言的標準忽略文件。但模板是通用配置實際項目應根據(jù)自身情況手動補充特殊情況。有一點要特別注意.gitignore只能對尚未被 Git 追蹤的文件生效。如果你之前已經(jīng)把某個文件提交過了再在.gitignore里加一行忽略規(guī)則Git 并不會停止追蹤它的變化。這時候需要用git rm --cached 文件名先把文件從追蹤列表中移除再配合忽略規(guī)則才有效果。5. HTTPS還是SSH連接認證方式的選擇5.1 Token認證現(xiàn)代GitHub推薦的方式把代碼推送到 GitHub 需要身份驗證。早些年這個環(huán)節(jié)最簡單的方式是輸密碼但出于安全考慮GitHub 很早就取消了賬戶密碼直接用于 Git 操作的方式取而代之的是個人訪問令牌Personal Access Token簡稱 PAT。這個令牌相當于一張限權(quán)門禁卡可以設定權(quán)限范圍和有效期限。創(chuàng)建方式很直接在 GitHub 設置頁面中選擇生成新令牌勾選需要的權(quán)限范圍至少需要repo權(quán)限才能對代碼倉庫進行推送生成后復制并保存好這段字符串。它只會在生成的那一刻完整顯示一次之后你無法再查看原值只能重新生成。拿到 Token 后HTTPS 協(xié)議下的 push 操作會自動提示你輸入用戶名和密碼。用戶名填你的 GitHub 用戶名密碼處不要填密碼粘貼 Token 進去即可。為了防止每次操作都輸入一次你還可以配置系統(tǒng)憑證管理器讓系統(tǒng)記住這部分憑據(jù)后續(xù)自動攜帶。使用 Token 的最大優(yōu)勢是權(quán)限精細可控。即使某個 Token 不幸泄露你可以在設置頁面直接吊銷它而不需要改動任何其他東西。5.2 SSH Key免密的長期選擇如果你需要在多臺設備上頻繁操作倉庫SSH 方式是體驗更好的選擇。SSH 的認證思路是我認鑰匙不認人。你在本地生成一對密鑰——一把私鑰自己留好、一把公鑰放置到 GitHub 賬號設置里。之后本地 Git 向 GitHub 發(fā)起連接時GitHub 通過密鑰匹配完成身份確認不再需要每次輸入賬號和 Token。生成過程ssh-keygen -t ed25519 -C 你的郵箱一路回車即可生成默認位置的一對密鑰。然后查看公鑰內(nèi)容cat ~/.ssh/id_ed25519.pub復制輸出的一大段字符串粘貼到 GitHub 設置里的SSH and GPG keys頁面即可。之后把倉庫的遠程地址改成 SSH 形式即可。事項HTTPSSSH首次配置需要生成 Token需要生成密鑰對后續(xù) push憑據(jù)管理后可記住免密安全粒度可單獨吊銷 Token私鑰泄露需重新生成適合場景臨時設備、共享設備個人長期設備對新手我的建議是如果只是偶爾使用或使用場景在公共電腦上選擇 HTTPS Token 更省心。如果是自己日常使用的固定設備值得花幾分鐘配好 SSH后面每次 push 都節(jié)省幾秒操作。不要兩種混著用選擇一個認定后保持專注避免把遠程地址反復改來改去造成多余的心理負擔。5.3 常用命令一覽與查詢技巧很多新手遇到的實際問題是命令一多就亂套。其實日常開發(fā)需要熟練敲入的命令不超過二十條。這里我做了一份高頻命令清單可以當成速查卡# 查看倉庫狀態(tài)推薦頻繁執(zhí)行 git status # 查看提交歷史 git log --oneline # 把改動放進暫存區(qū) git add 文件名 # 提交改動 git commit -m 說明信息 # 推送本地提交到遠程 git push # 拉取遠程最新改動 git pull # 新建并切換分支 git checkout -b 分支名 # 切換分支 git checkout 分支名 # 合并分支到當前分支 git merge 分支名比忘命令更讓人沮喪的是忘了一堆參數(shù)的含義。我的經(jīng)驗是不需要把所有命令都背下來Git 的幫助系統(tǒng)就是最好的記憶輔助遇到想不起來的參數(shù)用git help 命令名或者git 命令名 --help調(diào)出完整說明文檔即可。6. 新手起步階段最容易忽略的操作習慣6.1 提交信息要寫得像一封短備忘錄而不是一堆隨機字符如果你去翻一些知名開源項目的提交歷史會發(fā)現(xiàn)一個普遍規(guī)律幾乎每條提交信息都在回答兩個問題——這次改了什么和為什么這么改。相比之下新手常見的提交信息是這樣的update、add files、fix、coding、修改。假設三個月后你再也想不起來自己在做什么拉到一條fix你會獲得多少線索幾乎沒有。這里分享一個簡單好上手的提交信息模板類型(范圍): 簡短描述 詳細說明可選類型通常有 fix修 bug、feat新功能、docs文檔改動、refactor重構(gòu)、style格式調(diào)整等。范圍指這次改動影響到的模塊。描述則用一句話說清楚核心內(nèi)容比如fix(auth): 修復登錄后token未刷新導致接口401。我不是說必需嚴格按某個規(guī)范書寫。關(guān)鍵是讓描述帶有足夠上下文別人接手時不需要重新閱讀全量 diff 也能大概理解這次的改動目標。這個習慣帶來的長期收益遠比看起來大得多——你最終讀歷史記錄的時間和寫代碼的時間可能是等量齊觀的。6.2 什么時候該提交什么時候不該提交新手還有兩個相鄰的困惑一是改動多大才值得提交二是代碼沒寫完要不要提交。先說不值得提交的類型。幾百個文件里有一半是系統(tǒng)自動生成的臨時文件不該進提交。代碼里有調(diào)試用的臨時打印、試運行后的廢棄函數(shù)也不建議提交。再說說提交節(jié)奏。經(jīng)驗法則是只要當前狀態(tài)下代碼可以正常結(jié)束、不會有編譯錯誤且你清楚這次提交的目標就值得提交。提交得越頻繁歷史里能表達的信息就越多未來定位問題的切分點也越細。大量不成為提交沒有價值也沒有意義。有一種做法強烈不推薦一口氣寫了幾千行然后一次性提交。這會讓代碼審查幾乎不可行——沒人能在一頁幾百個文件里注意到局部的小問題。正確姿勢是每完成一個小功能點即提交一次盡量讓每次提交足夠原子化。6.3 README與License讓倉庫從代碼片段變成完整項目一個完整的 GitHub 倉庫代碼以外通常還有兩個標配文件。README 是用來承載項目說明的入口文件。它的核心內(nèi)容通常包括這個項目解決了什么問題、環(huán)境要求、如何安裝、如何調(diào)用、如何測試。對開源項目而言優(yōu)秀的 README 還能起到說明書營銷頁的作用讓訪問者一眼就知道這個倉庫值得不值得點 star 或者提交 issue。License 則決定了別人能不能合法地使用、修改、分發(fā)你的代碼。很多人以為只要我把代碼公開在 GitHub 上別人就默認可以用這是一個常見誤解。從版權(quán)角度說公開代碼不代表放棄版權(quán)。如果倉庫里沒有 License那么法律意義上其他人仍然不能隨意使用你的代碼來做商業(yè)項目等。GitHub 有標準化的選許可證流程如果你不關(guān)心細節(jié)MIT License是自由度較高且最常見的選擇之一。7. 從入門到日常使用一些過來人的體會寫到這里基礎(chǔ)的 Git 操作和 GitHub 業(yè)務流程其實已經(jīng)串起來了。最后再分享幾條我踩過不少坑之后覺得比學會命令更重要的心得。第一先學會看報錯信息。新手遇到 push 失敗時經(jīng)常會慌把一大段紅色報錯粘貼到搜索引擎里然后照著別人給的命令亂七八糟敲。但實際上多數(shù)報錯信息本身已經(jīng)把問題說得很清楚了。最典型的比如failed to push some refs通常在報錯提示上方就已經(jīng)解釋了原因——遠端有本機沒有提交的數(shù)據(jù)。這時候執(zhí)行g(shù)it pull同步一次通常問題就解決了。第二養(yǎng)成git status和git log的好習慣。它們不單單能告訴你倉庫當前狀態(tài)還能幫你觀察我當前到底在哪個分支我的上一次提交到底是什么。尤其在操作了幾個倉庫之后大腦很容易記混不同項目的分支狀態(tài)而命令給出的信息是最可信的。第三不要畏懼沖突和你確認不了的操作。Git 設計得非常嚴密的一點在于幾乎每個危險操作都留了至少一條退路。只要你的代碼推送到遠端或者有了備份副本本地即使全部擼掉也可以搶救回來。我本人的經(jīng)歷是手滑執(zhí)行過 reset、誤刪過分支也在別人的主導下被迫解決過一次跨文件的沖突。遇到這類情況時最重要的反而是耐心——逐個文件、逐行信息確認而不是靠直覺和運氣。如今打開任何成熟的軟件項目主頁第一眼看到的都是 README、分支、貢獻指南、Pull Request 流程等信息。這套基礎(chǔ)設施相當深入人心。作為入門者花幾個小時搞懂背后的原理遠比你背下二十個命令更有長期價值。上手之后你會發(fā)現(xiàn)GitHub 非但不復雜反而是那種越用越順手、一旦用慣了再也不想回到文件命名管理法的工具。我很認真地希望你邊讀邊打開電腦試試而不是收藏完就放在那里。畢竟 Git 類的工具讀再多的經(jīng)驗文章也不如親手推送一次來得直觀。