當前位置:
首頁 > 知識 > 大白話解釋 Git和GitHub

大白話解釋 Git和GitHub

編譯:伯樂在線/聽風


本文旨在使用通俗易懂的文字,講解版本控制背後的理論,以便你能對程序員們如何工作有個全局概念。本文不涉及代碼,不用下載啥東西,循序漸進,不關注繁複細節,只有文字和一些不怎麼漂亮的手繪塗鴉。

大白話解釋 Git和GitHub 點擊播放 GIF/21K



寫本文的動機

學習任何東西都能在網路上找到如此之多的指導教程,這一直令我驚訝不已。Git 和 Github 也不例外,網路上有大量優秀資源,這些資源要麼只對其中一個,要麼兼顧二者引導你開始學習。以下是我特別喜歡的一些資源:


Treehouse – 寫給設計師的 Git 入門介紹


Roger Dudler – Git 簡易教程


Pluralsight – Github:初學者指南


然而,我發現這些教程總是跳過許多理論知識,直接解釋如何通過命令行或 Github 桌面應用程序使用 Git 。坦白說,如果你只是想知道你的開發團隊談論的到底是什麼,這些指導教程也綽綽有餘了。如上所述,我的目標是對版本控制的整體概念進行簡明扼要地講解,同時希望能讓你了解到版本控制是如此酷。


讓我們從最基礎的開始:版本控制

大白話解釋 Git和GitHub



Image credit: weebletheringskite, WordPress


版本控制(Version control):學習它,愛上它,享受它。顧名思義,版本控制系統是任何能讓你了解到一個文件的歷史,以及它的發展過程的系統。之前作為平面設計師時,我常常會遇到這種文件:

大白話解釋 Git和GitHub



看起來眼熟?儘管上述系統不是一個好用的系統 ,但它確實是一個版本控制系統。更複雜點的例子就像,Google 文檔的 「修訂歷史」或 Photoshop 的「歷史」工具。


開始 Git


Git是一種專為處理文本文件而設計的版本控制系統。因為,歸根到底,這就是代碼的本質:一堆堆以某種方式聯合在一起的文本文件。Git 是一個可安裝應用,它允許你對你自己所做的更改進行注釋,用以創建易於導航的系統歷史。


(附: 「Git」 也是工程師取的名字,我們對市場部同仁感到抱歉)


那麼,Git做了什麼,是簡單地保存文件所做不到的呢?從根本上講,文件保存就是一個簡化的版本控制系統,但坦率地說,它並不是一個好用的系統,因為它只能前進。當然,你也許會爭論「撤消」按鈕可以讓你的文件回滾到以前的狀態。但我們都清楚,「撤消」按鈕有其局限性,最明顯示的是,在關閉文件時,文件的過去也隨之丟失。


另外,文件保存是非常個人化的。它不能夠顯示整個系統的歷史,只能夠顯示該文件的。針對這一點,你可能會想,「嗯,我不是一個工程師,我不需要為系統煩惱」。我願意花些時間來解釋一下,很多事情你認為不是「系統」,而實際上它們就是。


以 Sally為例,她是一個正在寫下一個大冒險奇幻小說系列的作家。Sally 已經寫完該系列小說中的第一本,並把它傳給了她的編輯。此外,由於她才華出眾,在等待編輯的反饋的同時,她還寫了第二本書的前三章。每本書都建立了獨立的 World 文件。

大白話解釋 Git和GitHub


在某個快樂的日子,Sally 等來了她的編輯關於第一本書的反饋。他擔心年輕的讀者不想讀一系列專寫獸人故事的書,希望她在這個故事中引入一些精靈。關於這點,Sally 嘆了口氣,但很快意識到,她的精靈新角色將帶來始料未及的衝突和曲折的情節。然後,她做了以下事情:


在第一本書中加入新角色,並修改故事情節。


完成第一本書之後,對第二本書的故事情節,進行必要的修改。


所有的這些修改,導致她需要引入某個地理位置到第一本書中,而不是第二本書。


重新編輯第一本書,讓它包含新的地理位置。


終於,她推開了她的鍵盤,確信已經把精靈融入到了她的奇幻世界之中。

大白話解釋 Git和GitHub



你瞧,Sally 實際上在處理一個系統。她的兩本書互相影響。角色、地理位置和故事情節在兩本書中流動交織。然而,遺憾的是,一個月後,她的文件系統里什麼都沒有了。Word 的 「文檔歷史」工具,或她曾經粘貼在顯示屏邊緣用於記錄修改過程的便簽紙,將把所有的變化過程都揉合在一起。

大白話解釋 Git和GitHub



這正是Git 大放光芒之處。如果 Sally 一直結合 Git 使用Word,她就能對所有這些相關的變化做一個關於「將精靈引入到系列」的簡潔小結。她可以看到所有穿插在頁、章節、文件,以及每本書中的修改記錄,讓她真正地了解引入精靈對她的奇幻系列產生的影響。這個「簡潔的小結」就是我們在 Git 領域中所講的提交(commit


回顧一下。 Git 是一個軟體,它允許你通過提交對一個系統(或一組)文件的歷史進行注釋。這些提交便是在給定時間點對系統做出的差異「快照」。


那麼,如果我是Sally,我的提交歷史看起來是這樣子的:


Github

大白話解釋 Git和GitHub



到目前為止,一切都還不錯。但是,如果 Sally 同時用到兩台電腦工作,將會發生什麼呢?問得好。這時,就該用到 Github了。注意,不要和 Git 混淆了。Github 獲取 Git 中的提交歷史,並將其存儲在互聯網上,因此你可以從任一一台電腦訪問它。你在本機(例如:你當前正在使用的電腦)推送(pushing提交到 Github,然後,從另一台新的或不同的電腦上拉取(pulling這些提交。

大白話解釋 Git和GitHub


讓我們假設上圖為 Sally 的工作流程。她在家裡的台式電腦(左邊,橘黃色的)上開啟她一天的工作。接下來,她完成了幾個章節的寫作,又做了一些編輯工作,等等。整個過程中,她對工作總共進行了三次策略性的「快照」(Git 提交)。


下午,Sally 常常喜歡帶著她的筆記本電腦(上圖中的右側,藍色的)去咖啡館寫作。今天也不例外。因此,在關閉家裡的台式電腦之前,她需要確認當前的Git 提交歷史已推送(push到了在線Github。一旦被上傳到 Github,這些提交記錄就被存儲在遠程倉庫(remote repository中。


我們先來分析一下幾個計算機術語:遠程(remote)僅僅意味著聯網(與「本地」的意思相反,和之前我們理解到的意思一樣的,代表當前正在使用的電腦)。而倉庫(repository,經常簡寫為「repo」),就是一個具備 Git 超級許可權的文件夾。


因此,Github 就是讓你把工作(通過Git提交進行註解)存儲在了一個指定的在線文件夾(repo)。明白了吧?簡單。


午餐之後,在當地的一家咖啡館中,Sally 拿出了她的筆記本電腦。很明顯,她想接著家裡的工作進度繼續。因些,她從 Github 倉庫上獲取到最新進度的工作。「從 Github 上獲取她的工作」,這一過程就叫拉取(pulling。再看一下上面這幅圖片,你將看到 Sally 拉取了之前她在家時進行的三個提交。


現在,在她的筆記本電腦上,Sally 有整個系統(包含她的幻想系列的所有文本文件)的最新的完整副本,並能夠基於上次的進度,繼續工作。她寫了更多的章節,對工作進行了兩次以上的策略「快照」(提交)。最後,Sally 把這些提交推送push)到 Github 上,結束了這一天的工作。這樣第二天上午的時候,在家裡的台式電腦上就可以取得這些最新進度的工作。


協同工作


好吧,這一切都能說得通。但是, Sally再如何酷,整個項目也只有她一人而已。工程團隊要如何確保他們的工作不會重疊?


簡而言之,創建分支。將你的 Git 提交歷史想像成一棵樹。樹的主幹就是我們談到的主分支。為了讓團隊成員避免彼此牽扯,他們在獨立於他人的隔離區(在一個功能分支)進行工作,然而最終,每個人的工作成果都會被提交到主代碼庫 (主分支)。

現在,回到 Sally 的例子。她加入了奇幻作家協會,在這裡每個人都與他人合作完成這本書——《奇幻系列生物辭典》。這本辭典更像一本教材,由多個作者共同完成:Sally、Tom 和 Adam。


讓我們來看看《奇幻系列生物辭典》項目的在線 Github 倉庫,現在的情況是:

大白話解釋 Git和GitHub



如上圖所示,樹的類比完全適用於奇幻作家協會在這個項目上的合作情況,倉庫歷史沿主分支向上移動。常規工作流始於每個作者為完成一個工作任務(例如編寫章節內容,或排版章節)而在主分支上創建分支。只有當更改得到其他合作作家的批準時,分支才會被合并到主分支上(請謹記,主分支上的內容,才是最終要發布的內容)。


當一個分支的內容合并(merged到主分支時,意味著該分支的內容會覆蓋主分支上的。因此,現有內容的任何更改都將會替代之前的。當然,任何新添加的內容也會添加到主分支。實際上,當分支合并到主分支時,該分支的提交歷史被添加到主分支提交歷史的頂部。


然而,你可能正在思考:人們在本機的工作和之後才推送到 Github 的工作變更是如何連接到一起的呢?


關於這個問題,重點在於:你在 Github 的遠程倉庫是你本機工作項目的一個鏡像。這意味著,你在自己的電腦里存儲了該項目(例如:一個已設置可進行 Git 提交的文件夾)的本地 Git 倉庫。在這個本地的 Git 倉庫(再次,這是一個特定術語,指你的電腦里某個啟用了 Git 功能的文件夾)中,你擁有與該項目相關的所有文件,在本文的例子中,即《奇幻系列生物辭典》。


它的工作原理很像 Dropbox :你在不同的設備(你的家庭電腦、辦公室電腦,等等)上創建本地文件夾,進行工作並更新這些文件。最後,這些操作被同步到網路上。然而,我們知道,Git/Github 工作流還包含了一些額外的步驟。首先,你必須有意識地對某一時刻的工作執行「快照」(即執行一次提交)。然後,你必須特意地推送這些提交(push) 到 Github。只有這樣,你的工作才被同步到網路上的位置(Github 版本庫)。


既然如此,為什麼不自動化該工作流呢?為什麼不讓它像 Dropbox一樣,當你更新本地文件時,同時自動更新 Github 上的文件?有很多理由讓我們不這麼做。最主要的理由是——bugs 。同出版界一樣,軟體工程中也不是所有寫過的東西都要保留。有時,你希望實驗一下你的想法,如果實驗失敗,你希望有一種簡單的方式能讓工作快速回滾到之前的正確狀態上。這也是為什麼我們提倡這個經驗法則,即在你試圖用不同的方法編輯或實驗之前,先對當前你希望保留的修改進行提交。頻繁地提交小塊工作有益無害,事實上,許多工程師為自己能做到這一點而感到自豪。

現在,回到《奇幻系列生物辭典》。由於 Sally 對獸族有較深的了解,她被挑選為寫獸族章節。但她不想在沒有經過其它合作人員允許的情況下去修改這本書,於是,她創建了一個本地分支,並在該分支上進行寫作和提交。然後,她將本地分支推送到 Github。像往常一樣,Github 的遠程倉庫是本地庫的一個鏡像,最新進展顯示 Sally 已創建了一個包含部分提交的分支(如下圖所示)。

大白話解釋 Git和GitHub



隨著她對本章節的持續寫作,Sally 進行了更多的提交,並將它們推送到 Github 的在線鏡像分支。終於,她準備請 Tom 和 Adam 一起對她的工作進行評審。因此,她在 Github 上發布了一個Pull Request(發布請求),這是一個 Github 功能,允許她解釋該分支相對於主分支做了哪些修改。Github 還提供了一個簡易平台,合作人員可以在該平台上針對分支的修改內容進行討論,並要求 Sally 在分支合并到主分支之前對一些有異議的內容進行修改。

大白話解釋 Git和GitHub



在對部分內容請求修改後,如上圖所示,Tom 和 Adam 對 Sally 的分支內容很滿意,並決定將她的工作成果合并到 Github 的主分支上。此時,他們所要做的就是將 Sally 之前獨立提交的內容,添加到主分支的提交歷史頂部:

大白話解釋 Git和GitHub



此時,Sally可以切換(或「check out」)到本地計算機上的主分支,並將先前在功能分支(獸人章節分支)中的獨立提交拉取下來。現在她又要在新的主分支上重新開始了:以該主分支為基礎為她的下一步工作創建一個新的本地分支,幫助湯姆編輯有關妖精的章節。因此,這一過程又將重複:

創建本地分支


在本地分支上編輯修改,然後提交


推送提交(Push)到 Github


創建發布請求(Pull Request),說明該分支包含了哪些更改


合并(Merge)分支內容到主分支


將主分支上的最新提交拉取(pull)到本地


重複上述步驟


正如你所看到的,這是一個非常流暢的工作流,完美地結合了獨立工作與團隊協作。你本機的 Git 提供了一個絕妙的方法,即通過由你自己控制和策劃的豐富的歷史提交,來創建你工作的各種版本。Github 是一個非常棒的在線版本控制工具,不僅存儲和提供了清晰的可視化歷史記錄,而且還能進行協同工作和質量控制。


總而言之,我希望我已經說服你去嘗試使用 Git 和 Github 進行任何項目。沒有理由只有工程師能從這個很棒的工具中受益。畢竟,我們也想看到更多有關獸人的故事。


致謝:

非常感謝 Common Craft 對本文的塗鴉和解釋風格的啟發。還要感謝這個視頻《 saving me from the horror of having to explain Twitter to my mum 》。


本文涉及的術語


Version Control(版本控制):任何一個能夠讓你了解文件的歷史,以及該文件的發展進程的系統。


Git一個版本控制程序,通過對變更進行注釋,以創建一個易於遍歷的系統歷史。


Commit(提交)在指定時間點對系統差異進行的注釋 「快照」。


Local(本地)指任意時刻工作時正在使用的電腦。


Remote(遠程)指某個聯網的位置。


Repository (倉庫,簡稱 repo)配置了Git超級許可權的特定文件夾,包含了你的項目或系統相關的所有文件。


Github獲取本地提交歷史記錄,並進行遠程存儲,以便你可以從任何計算機訪問這些記錄。


Pushing(推送)取得本地Git提交(以及相關的所有工作),然後將其上傳到在線Github。


Pulling(拉取)從在線的Github上獲取最新的提交記錄,然後合并到本地電腦上。


Master (branch):主分支,提交歷史 「樹」的 「樹榦」,包含所有已審核的內容/代碼。


Feature branch(功能分支/特性分支):一個基於主分支的獨立的位置,在再次併入到主分支之前,你可以在這裡安全地寫工作中的新任務。


Pull Request(發布請求)一個 Github 工具,允許用戶輕鬆地查看某功能分支的更改 (the difference或 「diff」),同時允許用戶在該分支合并到主分支之前對其進行討論和調整。


Merging(合并)該操作獲取功能分支的提交,加入到主分支提交歷史的頂部。


Checking out(切換)該操作指從一個分支切換到另一個分支。


看完本文有收穫?請分享給更多人


關注「伯樂在線」,看更多精選 IT 職場文章


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 優才學院 的精彩文章:

AI取代人類前孩子的教育需要什麼改變?
UI設計師需要具備8個能力
獨家翻譯:谷歌官方發布:安卓全力支持Kotlin
如果安卓這樣對抗蘋果Swift……
AI向左生態向右,谷歌I/O大會第十年突破了什麼?

TAG:優才學院 |

您可能感興趣

Joe Russo 簡單解釋 Thanos 是何時擁有 Infinity Gauntlet
Panos Panay解釋為何Surface Pro 6/Laptop 2沒有USB-C埠
「美國隊長」Chris Evans 解釋早前 Twitter 的道別訊息
自然數簡化到素數:黎曼猜想RiemannHypothesis及其解釋
Zare GM安德烈Pasquali解釋為什麼鋁是未來的AM主要材料
關於利用 information bottleneck 來解釋深度學習
RPM命令的——nodeps 和——force參數解釋
什麼是python的全局解釋鎖(GIL)?
用 Python 編寫的 Python 解釋器
漫話:如何給女朋友解釋什麼是Git和GitHub?
一文解釋清楚面試常客:final、finally、finalize
Russo 兄弟導演解釋為何不承認《Avengers: Endgame》電影標題
Gearbox CEO解釋《無主之地3》登陸Epic商店原因
Facebook高管解釋:為何Rift S上有太多聯想的影子
How to給直男解釋What is少女心
JVM和Python解釋器的硬碟夜話
庫克解釋為什麼iPhone比Android手機安全
iFixit解釋,原來他們拆的是iPhone9!
【吳恩達Deeplearning.ai筆記一】直觀解釋邏輯回歸
JR Smith這次解釋了在身上紋Supreme的原因!