git 入門教程之本地和遠端倉庫的本質

雪之夢技術驛站發表於2019-03-25

本地倉庫遠端倉庫在本質上沒有太大區別,只不過一個是本地電腦,一個是遠端電腦.

遠端倉庫不一定非得是 github 那種專門的"中央伺服器",甚至區域網的另外一臺電腦也可以充當"中央伺服器"的角色,因為它存在的最初目的只是方便大家交換彼此的提交記錄而已!

所以本地倉庫和遠端倉庫的基本行為應該是一致的,約定俗成的規定是遠端倉庫一般不直接參與日常開發工作,主要作為專案託管中心.

某些自動化持續整合環境中也可能會直接操作遠端倉庫,這時遠端倉庫就真的和本地倉庫沒什麼區別了!

個人開發常用命令

個人開發看重的是效率,同時兼顧下版本控制的話算是是錦上添花,git 的本地倉庫是本地備份,而遠端倉庫則是網盤備份.

git init : 初始化本地專案

將本地專案初始化 git 專案,直觀表現是在該專案同級目錄下多了 .git 隱藏目錄,其儲存著 git 版本庫相關資訊.

此後當前專案便具備了本地管理的能力,可以與 git 進行互動.

git clone : 克隆遠端專案

git init 一樣的作用,也是建立本地倉庫,只不過 git init 是直接將本地專案作為本地倉庫,而git clone 是將遠端專案克隆到本地並作為本地倉庫.

由此可見,git clonegit init 多了一層遠端倉庫的概念.

git add : 新增檔案

將工作區的提交記錄新增到暫存區,暫存區是工作區和版本庫互動的橋樑,暫存區積累到一定量的提交記錄時可以批量提交到版本庫,這一點暫存區有點像快取.

git commit : 提交檔案

將暫存區的版本提交到版本庫,從而形成工作區->暫存區->版本庫的基本鏈路,本地工作區的版本控制流程大致如此.

git push : 推送檔案

如果是使用 git clone 命令克隆的本地專案,當工作到一定程度時可能需要將這部分工作成果推送到遠端倉庫,這時候使用 git push 命令完成本地版本的推送流程.

如果是使用 git init 命令初始化的本地專案,可能沒有遠端倉庫,自然也就不需要推送.如果後來建立了遠端倉庫,那麼你自然是想要將本地倉庫推送到遠端倉庫的,因此你需要準確告訴 git 你要推送到哪個遠端倉庫. 使用 git remote add origin git@github.com:username/repos.git 命令新增遠端倉庫資訊,這樣就建立了本地倉庫和遠端倉庫的關聯,以後就可以正常推送到遠端倉庫了.

團隊開發常用命令

團隊開發注重的不僅是個人效率還有團隊的整體進度,隨著企業級開發的日趨複雜化,不再是一個人能夠獨立完成的,更何況時間也不允許慢慢完成,大多數公司採用的是人力換時間的方式,團隊並行開發來縮短整個專案週期,這種複雜需求下正是 git 大展拳腳的好機會.

專案整體採用並行開發模式,拆解成不同的功能模組,每個人負責各自模組,模組之間相對獨立但也不排除存在交集的可能性.對於每一個個體開發者來說,既需要版本控制又需要團隊交流.這時候分支的作用就凸顯出來了.

根據專案的業務特點將其拆解成不同的功能模組,這些功能模組分別代表不同的分支,而這些功能模組又組成了完整的專案,這就是主幹和分支的關係.

初始時專案是一個整體,中間拆解成不同功能模組,最後再合併成一個整---"分久必分合久必分".

git branch <branch> : 建立分支

每一個獨立的功能模組被定義成一個單獨分支,建立分支的過程其實是拆解專案的過程,建立本地分支後就在分支上開發特有功能,不再關心其他功能分支.

git checkout <branch> : 切換分支

模組拆解完成並建立了相應的分支後,需要切換到既定分支上才能開展自己的工作.

git merge <branch> : 合併分支

沒有絕對的獨立,專案再怎麼拆分也是整體的一部分,肯定需要和其他功能模組發生關係,某些情況下需要其他分支的工作成果合併到自己的本地倉庫中,這樣才能完成一次小規模的組裝.

可以預期的是,當這種組裝足夠多的時候,最終便會演變成專案的終極形態,形成一個整體.

git fetch : 抓取遠端分支

合併目標分支首先需要能夠獲取到目標分支的提交記錄,既然每個功能模組都是不同的專案成員負責開發的,也就不在我們電腦上,所以我們先要將目標分支下載到我們本地電腦,然後才能合併該分支到本地分支.

git pull : 拉取遠端分支

"先下載目標分支再合併到本地分支,從而小規模組成更復雜更強大的功能",每一次的組裝過程都需要兩步操作者顯然不符合懶人思維啊,git pull 就是這兩步操作的簡化命令,先下載再合併就是這麼簡單!

本地和遠端倉庫的碰撞

不論是個人開發還是團隊開發,我們幾乎習慣慣站在主動方的角度來思考問題,有沒有想過當遠端倉庫接收到我們的git pushgit pull 請求時,遠端倉庫發什麼了什麼改變,這種改變對本地倉庫又有什麼影響?

遠端倉庫(遠端電腦上的本地倉庫)只是眾多分散式電腦上本地倉庫中的一員,說它特殊也很特殊,充當著"中央伺服器"作用,其餘人統一從這裡下載或推送;說它普通也很普通,和本地電腦上的本地倉庫沒有什麼不同,因為它隨時可被任意電腦上的本地倉庫所取代!

揭開遠端倉庫的神祕面紗後,現在我們只需要將其視為普通的本地倉庫一樣對待即可,然而我們本地電腦上已經有了本地倉庫,故而需要將遠端倉庫做一下簡單標識區分(origin)稱之為遠端分支.

  • 先說說 git push 命令做了什麼?

    1. 對於本地來說,git 將本地倉庫的指定分支推送到遠端倉庫的相應分支,同時更新了本地倉庫的遠端分支.
    2. 對於遠端來說,git 接收到本地倉庫的推送請求時應該在相應分支上合併本地分支,同時更新遠端倉庫的相應分支.

只要本地的指定分支成功推送到遠端的相應分支時,對於本地來說,不論是指定分支還是遠端分支(origin/master)都應該是最新狀態,因為已經與伺服器同步了.

而遠端接收到此次推送請求時,應該嘗試合併此次推送請求,再更新自己的相應分支,遠端合併完成後再通知本地此次推送結果,如此一來,三端同步,皆大歡喜!

git-local-remote-push.gif

  • 再講講 git pull 命令發生了什麼?

    1. 對於遠端來說,接收到本地的拉取請求時,因為沒有新版本需要處理,所以無需任何操作.
    2. 對於本地來說,當遠端倉庫的相應分支下載到本地時應該更新遠端分支狀態,再嘗試合併到本地的相應分支.

git pull 命令或者說是 git fetch 命令是本地和遠端通訊的方式,所以 origin/master 會自動更新!

git-local-remote-pull.gif

小結

本地倉庫和遠端倉庫本質上沒有太大區別, git fetch 是本地倉庫和遠端倉庫之間的通訊途徑,本地倉庫中的遠端分支(origin/master)儲存著它們之間最後一次的通訊狀態.

相關文章