本文面向初次接觸版本控制系統的Git用戶,旨在介紹一些關於版本控制和Git的簡單概念。css
文中並不涉及過多的Git實際操做,文末推薦更多的Git學習資源。git
Git是目前最早進的版本控制系統,擁有最多的用戶數量並管理着數量龐大的實際軟件項目。風靡全球的Github更是讓Git版本控制系統名聲大震。本文以「版本控制系統」爲切入點,介紹相關概念和簡單的Git用法。github
若是對「版本控制」沒有概念,那真是無法用Git。緩存
因此咱們來看一個例子:假設大四畢業生小張在寫畢業論文,寫好初稿後常常刪改,甚至還會在次日把前一天刪掉的東西找回來。若是他動點腦子,就不會只在一個文檔中改來改去,而會在文件夾中有:安全
畢業論文_初稿.doc 畢業論文_修改1.doc 畢業論文_修改2.doc 畢業論文_修改3.doc 畢業論文_完整版1.doc 畢業論文_完整版2.doc 畢業論文_完整版3.doc 畢業論文_最終版1.doc 畢業論文_最終版2.doc ……
看起來是否是很鬱悶啊?小張固然也鬱悶了,由於本身老是改很差,因此他把本身的論文發給女友(是學霸),求幫忙;與此同時他本身也在繼續修改。次日就有了:服務器
畢業論文_最終版3.doc 畢業論文_女朋友版1.doc
他女朋友畢竟是學霸,固然給他的論文作了比較大的修改,此時小張雖然看到了但願,但還要糾結着作一件事情:把上面兩個版本的論文合併成:分佈式
畢業論文_死也不改版.doc
等合併好,已經是凌晨三點半。小張無比怨念:這樣子真是無法和女朋友開心的玩耍了呢!ide
怎麼辦?學習
小張想,若是能有個什麼東西來幫忙控制一下這該死的版本,那真是謝天謝地了!就像這樣:ui
版本 | 修改人 | 說明 | 日期 |
---|---|---|---|
初稿 | 小張 | 這是初稿 | Day1 |
修改1 | 小張 | 修改目錄 | Day2 |
修改2 | 小張 | 合併段落 | Day3 |
…… | …… | …… | …… |
最終版2 | 小張 | xxx | Day7 |
死也不改版 | 女朋友 | balabala | Day8 |
這樣就不用手動控制那麼多版本啦!
因此,所謂「版本控制系統」,就是來解決這類問題的。
沒錯,Git就是一個版本控制軟件。在進行軟件開發時,一個團隊的人靠使用Git,就能輕鬆管理好項目版本,作好項目的追蹤和輔助進度控制。確切的講,Git是一款分佈式版本控制系統。這個「分佈式」,要和「集中式」放在一塊兒理解。
所謂「集中式版本控制」,就比如這一個團隊中,版本庫都集中在一臺服務器上,每一個開發者都要從服務器上獲取最新的版本庫後才能進行開發,開發完了再把新的版本提交回去。
而「分佈式版本控制」,則是這個團隊中每一個人的電腦上都會有一份完整的版本庫,這樣,你工做的時候,就不須要聯網了,由於版本庫就在你本身的電腦上。既然每一個人電腦上都有一個完整的版本庫,那多我的如何協做呢?比方說你在本身電腦上改了文件A,你的同事也在他的電腦上改了文件A,這時,大家倆之間只需把各自的修改推送給對方,就能夠互相看到對方的修改了。
和集中式版本控制系統相比,分佈式版本控制系統的安全性要高不少,由於每一個人電腦裏都有完整的版本庫,某一我的的電腦壞掉了沒關係,隨便從其餘人那裏複製一個就能夠了。而集中式版本控制系統的中央服務器要是出了問題,全部人都無法幹活了。
在實際使用分佈式版本控制系統的時候,其實不多在兩人之間的電腦上推送版本庫的修改,由於可能大家倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。所以,分佈式版本控制系統一般也有一臺充當「中央服務器」的電腦,但這個服務器的做用僅僅是用來方便「交換」你們的修改,沒有它你們也同樣幹活,只是交換修改不方便而已。
版本,不是文件的版本麼?這個版本庫是什麼意思?
若是能意識到控制的是文件的版本,那就離理解版本庫只差一步了(最關鍵的一步)。
程序要記錄項目的版本號,最簡單的方法就是把版本相關的信息放在某文件裏,持續寫入文件便視爲版本更新。因此,當咱們在一個目錄中運行命令:
$ git init # Git初始化的命令,用於新建版本庫
這個目錄中就會默認產生一個新目錄:
.git/
沒錯,這就是咱們剛剛新建的版本庫,它將默認記錄當前目錄(直接包含.git
的這個目錄,下文中叫作「項目目錄」)中任何文件的改動。若是把這個版本庫刪除了,這裏面記錄的文件版本就都沒有了,項目目錄中的文件當前是什麼樣子,那就一直是什麼樣子,無法恢復到之前的版本了。若是想讓Git忽視項目目錄中的什麼文件(好比程序緩存等),能夠在.gitignore
中寫清楚那些文件。
在實際應用中,Git有很是多的用法,而本文是面向Git徹底初學者,因此咱們要從最基本的開始作。
好比,在剛纔建好的版本庫中,A新建了README文件,並在裏面寫了東西。寫好後他想給項目作個版本,就須要這樣:
$ git add README $ git commit -m "add README"
第一個命令是告訴Git要追蹤什麼文件,第二個命令是進行提交,並對這次提交作個簡答說明。固然,從此他再對README作什麼修改,均可以這樣作。Git會自動爲這次提交生成一個16進制的版本號。
若是此時他查看本地的版本庫,就會發現最新的一次提交是在剛纔,提交說明爲:add README
。
而後,他要把項目的版本庫更新到Github上,固然這時候項目自己已經在Github上創建好了。他只須要:
$ git push origin master
這行命令應該這樣理解:A已經在本地把項目最新的版本作好了,他要發到Github上,以便團隊裏其餘人都能收到這個新的版本,因而他運行git push
;push的目的地是origin
,這實際上是個名字,意義爲該項目在Github上的地址;推送的是本地的master
分支。
這個時候,Github上項目的版本號與A本地的最新版本號一致。
分支是版本控制裏面的一個概念:在項目作大了以後,若是要在原基礎上進行擴展開發,最好新建一個分支,以避免影響原項目的正常維護,新的分支開發結束後再與原來的項目分支合併;而在一個項目剛開始的時候,你們通常會在同一個分支下進行開發.這是一種相對安全便捷的開發方式。
此時,小組裏成員B對項目其餘文件作了一些更改,一樣也在本地作了一次提交,而後也想推到Github上面。他運行了git push origin master
命令,結果發現提交被拒絕。這要作如何解釋?
仔細想一想,最開始的時候,A和B是在同一個版本號上作不一樣的更改,這就會分別衍生出兩個不一樣的版本號。A先把本身的版本推到Github上,此時Github上的版本庫與B本地版本庫相比,差別很大,主要在於B這裏沒有A的版本記錄,若是B這時把本身的版本強制同步到Github上,就會把A的版本覆蓋掉,這就出問題了。
因此B進行了以下操做:
$ git pull
這樣子,B先把Github上的版本庫和本身的版本庫作一個合併,這個合併的意義在於:B經過Github,把A剛纔添加的版本加了進來,此時B本地的版本庫是整個項目最新的,包括項目以前的版本、剛剛A添加的版本和B本身添加的版本。
這以後,B再次運行git push origin master
,成功地把本身的版本推到了Github上。若是A想要推送新的版本,也要像B以前這樣折騰一番才行。
固然能夠!
這裏有兩個在線代碼託管平臺:
還有一些優秀的Git在線資料:
最後還有一本不錯的中文書籍:
不過,本文就要到此爲止了,由於再往下寫就會涉及更多更深的Git操做實踐,而這些內容在上面給出的資料中已經整理好。
本文的目的在於解決身邊乃至更多開發者同時入門版本控制和Git時候遇到的困惑,但願能對各位初學者起到積極的做用。
若是您有更好的意見或建議,歡迎與我討論:)