最近不少讀者和鹿哥反饋說,能不能掃盲一下 git,無論是 github 開源項目網站還是團隊合作,都少不了 git 版本控制的使用。加上很多的在校生沒有過多接觸過 git,所以呢,鹿哥決定最基礎的講起,請大佬多多包涵我這基礎的內容。
因為 git 涉及到的內容太多,寫一篇太長,在閱讀體驗上不友好,那麼分為兩篇吧。本篇主要分享一些 git 常用的操作以及命令背後的原理。
當我們做項目的時候,少不了來回的改動項目功能和代碼,一般我們修改的會覆蓋以前的內容,但是突然有一天,老闆不要新的需求了,而是要原來的那個功能,咋辦呢,只能一點點刪了最新的代碼,然後再重新寫原來的功能。
如果當項目變的龐大,需要多個人進行開發,每個人開發的功能各不相同,合併項目時,不得不手動合併,萬一出現各種 bug,每個人都要改動整體項目,刪除或增加部分代碼,萬一合併錯誤,導致整個項目處於一個未知的狀態,此時項目代碼變得異常混亂。
版本控制就是來解決以上這兩種情況的,你改動了哪些地方,都會被版本控制系統所記錄,對於以上第一種情況,我寫的新功能老闆不要了,我可以通過版本控制回退到未修改之前的狀態,對於上邊團隊合作,可以通過版本控制直接合併,無需手動一點點的複製粘貼。
說起 Git 的崛起特別有意思,最早的版本控制是出於 BitKeeper 公司的。而且應用於最大的開源系統 Linux,Linux 的作者Linus 早就把 Linux 作為全世界的開源項目,Linux 的誕生少不了世界很多開源貢獻者的參與。
因為貢獻的開發者來自世界各地,就會出現上述出現的問題,前期只能靠 Linus 手動合併代碼,後來系統變的原來越龐大,不得不使用 BitKeeper 公司的版本控制,但是 BitKeeper 公司呢,看了他們這麼熱愛開源,就免費讓 Linux 的開發者們使用。
面對來自世界各地 Linux 的開發者,更何況這些人都是牛人,風雲四起,不得不打算搞點事情。於是對 BitKeeper 公司版本控制下手了,對公司內部的協議進行了逆向工程(反編譯),但是很不幸運,被人家知道了。
這下可好了,本來人家公司讓你免費試用,你非要破解人家東西,還讓人家知道了,弄得 Linux 的作者 Linus 不得不去道歉,但是 Linux 道歉沒有妥協,最後人家 BitKeeper 公司收回了免費使用權。
兄弟們,既然人家不讓用了,那就自己動手豐衣足食唄。牛人 Linus 僅僅花費了十天的時間用 C 編寫出了 git 的第一個版本。我和我的小夥伴們驚呆了!
git 經過幾年火了起來,不愧是玩 Linux 的牛人,git 不僅性能極大的得到提升,而且開源免費,這就使得 git 在 2008 年入住全球最大的開源社區,為開源項目免費提供存儲,導致了很多開發者喜歡上了 git,現如今 git 也稱為最流行的分布式版本控制系統。
git 之前的版本控制是 SVN 和 CVS,但是這兩者有很明顯的缺點,它是集中式的版本控制,什麼是集中式的?就是必須提供一臺伺服器,團隊合作都圍繞著這個伺服器進行合併。它是基於區域網的,比如現在有些公司還在使用 SVN,一旦到了家裡辦公,所寫的代碼就不能提交到這個伺服器。
但是 git 就不同了,任何地方,任何地點,不同區域網下,想什麼時候提交就什麼時候提交,而且提交的速度非常的快,到底有多快,一會體驗一下就知道了。
以上 git 的歷史和特點就暫時介紹這些,感興趣童鞋可以去網上多多查閱相關 git 內容。
對於 git 的安裝不在過多的費口舌,直接去官網下載即可。
下面直接在本地版本倉庫講起吧。我們通過下邊的命令創建一個本地 git 版本倉庫。
這個命令執行後,發生了什麼?我們可以理解為初始化當前所在項目,創建一個空的倉庫,我們稱為 1 號倉庫,我們對這個倉庫可以進行一系列的各種增加、移除等操作。
此時會在當前目錄下生成一個 .git 文件,那麼這個文件就是來記錄當前版本庫裡內容變化的。
我們完全可以把這個倉庫當成現實中的存儲貨物的倉庫,當然,倉庫肯定要有個管理員的,這個管理員就是上邊的 .git 同學。
然後我在此目錄下創建一個項目文件,叫做「project.md」,然後執行下邊命令。
以上過程就相當於,此時鹿哥開著拖拉機拉著一批貨物來了,要在倉庫中存一批貨物。但是管理員說必須老闆同意了之後才讓我存,那麼這批貨就先暫時存放 2 號倉庫中。
2 號倉庫又稱臨時倉庫,只能存放臨時貨物,等老闆籤字畫押了,才能將 2 號臨時倉庫的內容正式存入大倉庫中,那麼 add 就是添加到 2 號臨時倉庫中。
我們可以通過讓倉庫管理員輸入以下命令,看看鹿哥的貨物是否存入了 2 號暫存倉庫中。
對,沒錯,是鹿哥的那批貨物。
這時,老闆同意可以把暫存在 2 號倉庫的貨物放到 1 號正式倉庫中了,那麼管理員開始輸入命令,將暫存倉庫的貨物進行錄入正式倉庫。
1git commit -m '2020 3/24 鹿哥的貨物 10噸'
commit 就是正式提交的意思,-m 是提交的內容的信息。在正式開發中,你每提交一次代碼肯定是要說明提交的那些內容,是修改了還是增加了功能,這東西都要寫上說明,因為萬一項目出現問題,會通過提交的信息進行回退。
是的,這些提交記錄都是由管理員記錄的,我們通過以下命令看一下管理員的記錄本。
這個記錄中,包括是誰提交了代碼,什麼時間提交的,提交的信息是什麼,都會在管理員這個小本本上記錄著。
有時候我們的程式設計師可能喝了酒去提交代碼,不小心把沒有做完的功能代碼提交上去了。第二天,酒醒了,突然發現自己手賤,咋辦?
不慌,我們可以撤銷(也叫做回滾)喝醉酒前的代碼狀態。還是拿貨物的例子去說明,比如鹿哥不想存入那 20 噸了,我應該咋辦?執行下面命令。
該命令的意思是回滾當上次提交代碼之前,也就是喝醉酒之前代碼的狀態。此時鹿哥的 20 噸就相當於沒有在存在倉庫中。我們在看一下管理員的記錄。
那麼問題來了,鹿哥,萬一遇到一個能喝的程式設計師,喝的大醉,一下提交了好幾次代碼,需要回滾好幾次,你這一次次的太慢了吧。
也是哈,如果我們想回滾哪一次就回滾哪一次,應該怎麼做?我們先可以通過一個命令,查看一下我們管理員執行命令的記錄。
每個命令前邊都有一個提交的 id,我們通過這個 id,執行下面命令,想回滾到哪一次就回滾到哪一次。
1git reset --hard 3cc34bb(提交 ID)
除此之外,我們在寫代碼時,還會經常出現一下兩種情況。
如果我們提交完成了,老闆讓我增加一個功能,這時,我寫了一天,在沒有提交(git add)之前老闆告訴我,不想要這個功能了,那麼此時我們咋辦?不怕,我們執行下面命令,直接丟棄工作區(目前項目)的修改。
1git checkout -- project.md(文件名)
但是我們已經提交到了暫存庫中,然後又修改了內容,老闆才告訴我這個功能不要了,我們就用以上回滾的方式,丟棄緩存區的添加。
1git reset HEAD project.md(文件名)
如果我們不小心刪除了我們項目的部分代碼,此時本地項目和倉庫中項目不一致,應該咋辦?
要麼將倉庫的項目也進行刪除,就是正常的進行提交修改就行了。要麼就恢復本地項目誤刪除的文件,也是使用上邊我們說到的命令。
1git checkout -- project.md(文件名)
上邊只是你自己在本地玩耍,提交代碼,以後到了公司一個大項目肯定是很多人一塊完成的,那麼就必須有一個統一的遠程倉庫用來存儲各個開發者由本地倉庫提交的代碼進行合併。等到項目開發完成,我們直接用遠程倉庫的代碼上線就可以了。
是的,想必你已經想到了,Github 可以創建一個遠程的倉庫,倉庫可以任何人都可以提交,也可以規定某些開發者可見(私有倉庫與公有倉庫)。
在 Github 上創建遠程倉庫:
我們創建完成之後,必須讓本地倉庫和遠程倉庫進行關聯,關聯之後才能夠將本地的代碼進行提交。
本地倉庫和遠程的倉庫通信需要 SSH 加密的,需要設計一樣的秘鑰才可以進行通信。
創建秘鑰:
本地倉庫設置密鑰需要和遠程倉庫及逆行加密通信。在 window 下創建 SSH Key,一路回車。在用戶主目錄裡找到.ssh目錄,裡面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的秘鑰對,id_rsa是私鑰,不能洩露出去,id_rsa.pub是公鑰,可以放心地告訴任何人。
1ssh-keygen -t rsa -C "youremail@example.com"
Github設置 key:
在遠程倉庫設置一個或多個公鑰知道有哪裡的本地倉庫要通信。
登陸GitHub,打開「Account settings」,「SSH Keys」頁面。然後,點「Add SSH Key」,填上任意Title,在Key文本框裡粘貼id_rsa.pub文件的內容,點「Add Key」,你就應該看到已經添加的Key 。
我們通過上邊設置好之後,就可以將本地倉庫關聯遠程倉庫了。
1git remote add origin 遠程倉庫地址
通過這一條命令就可以關聯遠程倉庫,遠程倉庫的地址在這。
我們現在只是關聯上遠程倉庫,而沒有將本地的分支推上去,對於分支的概念涉及到挺多內容,暫時不在這一節展開講。
1git push -u origin master
通過上邊的命令,將本地倉庫的主分支和遠程的主分支關聯(可以理解為當前版本代碼會有一個指針指向當前版本)。這樣本地有什麼改動的,通過提交到遠程倉庫,遠程倉庫的分支內容也會進行改變。
有時候,你可能沒有參與項目的創建,而是老闆把你臨時派到了其他項目組協助一起做項目。
此時你本地是沒有項目的,所以要在遠程倉庫把其他組的項目拉下來,然後再進行快速開發。我們把遠程倉庫項目拉下來的過程稱為克隆倉庫。通過以下命令來進行。
此時我們可以進行愉快的開發了。
本篇主要涉及到的一些 git 基礎操作,後續還會有如何解決代碼衝突以及分支的各種概念,以及遇到項目 bug 如果暫存手頭的工作等。
今天文章到這裡結束了,雖然這篇內容接近基礎,但是寫起來真是費勁,本想著周一發表,看到文章涉及到的太少,然後第二天又補充了很多,全文 4230 字,如果對大家有幫助,歡迎點讚和留言,鹿哥唯一剩下的動力靠你們啦!