前言
今天是五一假期的第一天,突然想起來應該對最近工作中遇到的一個非常讓我頭痛的問題進行一下深入的學習和探索。這個問題是什麼呢?就是git的使用。雖然以前自己做項目的時候也用過git,但是那時候對git的使用很淺,只要是push successfully就完事了,沒有注意到git有那麼多的使用細節。現在參與到團隊開發中以後,我發現個人開發和團隊開發是完全不一樣的,相較於單人開發項目時的隨意和鬆散,團隊協作構建出來的複雜的代碼工程是不容許任何一個開發者大意和馬虎的,你的任何一個小錯誤都有可能對整個工程帶來巨大的影響。所以學會如何使用團隊協作工具是非常重要的。
在我看來,使用任何一個工具,首先去了解它的設計理念和基本結構肯定會在使用過程中產生事半功倍的效果,所以就先從Git的基礎概念學起。
不積跬步無以至千里,不積小流無以成江海。
目錄
1.1、什麼是VCS(Version Controller System)?
1.4、什麼是提交對象(git commit object)?
1、Git介紹
1.1、什麼是VCS(Version Controller System)?
要弄明白什麼是git,就要先弄明白什麼是VCS,Version Controller System的字面意思很好理解,翻譯過來就是指“版本控制系統”。難以理解的是我們爲什麼要使用這個VCS?它的作用是什麼?
在阿里巴巴研發效能部的一篇文章中,我覺得他們很好的回答了這個問題:
當你在工作中面對的是一些經常變化的文檔、代碼等交付物的時候,考慮如何去追蹤和記錄這些changes就變得非常重要,原因可能如下:
- 對於頻繁改動和改進的交付物,非常有必要去記錄下每次變更的內容,每次記錄的內容匯成了一段修改的歷史,有了歷史我們才能知道我們曾經做了什麼
- 記錄的歷史中必須要包含一些重要的信息,這樣追溯才變得有意義,比如:
- Who:是誰執行的變更?
- When:什麼時候做出的變更?
- What:這次變更做了什麼事情?
- 最好可以支持撤銷變更,不讓某一個提交的嚴重問題,去污染整個提交歷史
VCS正是爲我們在開發工作中提供了這種記錄和追溯變更的能力。
1.2、什麼是Git?
git是一個開源的分佈式版本控制系統,是VCS的一種。它的發明者是Linux之父Linus Torvalds,git一開始是Linus爲了管理Linux內核開發而開發的一個版本控制軟件,後來因爲其高度易用,速度快等特性才慢慢流行於軟件開發項目中。
git既然是一個分佈式版本控制系統,那麼它的分佈式體現在哪裏呢?具體內容請參見Git Documentation ---分佈式工作流程。
1.3、Git存儲變更數據的理念
Git對待數據的方法與SVN不同。SVN是以文件變更列表的方式來存儲信息,它是將保存的信息看做是一組基本文件和每個文件隨時間逐步累積的差異delta,如下圖所示:
File A即基本文件(最原始版本),SVN保存了不同版本與基礎文件之間的差異(三角符號即差異變量delta)。
而Git保存信息的方式是把數據看做是對小型文件系統的一組快照(什麼是快照?我理解的快照大概意思就是系統把某一個狀態下的各種數據記錄在一個文件中,就像是人類照相一樣,照出來的相片其實就是對你當時某一個狀態的記錄),每次你提交更新,或者在Git中保存項目時,它對當時全部文件製作一個快照並保存一個對此快照的索引(爲了實現高效率,如果某一個文件沒有進行更改,那麼Git不再重新存儲此文件,而是保存一個鏈接指向之前存儲的文件),如下圖所示:
1.4、什麼是提交對象(git commit object)?
- 提交對象(git commit object):即提交對象。每一個提交在git中都通過git commit object存儲,這個對象具有一個全局唯一的名稱,叫做revision hash,它的名字是由SHA-1算法(安全哈希算法)生成,形成如“998273647a8b67f89994ec2”這樣的一串字符串(它由40個16進制字符組成),我們通常會取其縮寫方便使用,如“9982736”。
- 對象構成:git commit object對象包含了author (提交者)+ commit message(提交信息)的基本信息。
- 對象存儲:git commit object對象中保存了一次變更提交內的所有變更內容,而不是增量變化的數據delta,所以git對於每次改動存儲的都是全部狀態的數據。
- 提交樹:多個commit對象會組成一個提交樹,它讓我們可以輕鬆的追溯commit歷史,也能比對樹上commit與commit之間的變更差異,例如下圖:
1.5、Git的三個工作區域
一個文件從修改到提交要經歷三個狀態,分別是
- modified(已修改):表示修改了文件還沒有保存到數據庫中;
- staged(已暫存):表示對一個已修改的文件的當前版本做標記,使之包含在下次提交的快照中;
- committed(已提交):表示數據已經安全的保存到了本地數據庫中。
這三種狀態又對應着不同的工作區:
- 工作區(Working Directory):工作區是指我們本地工作的目錄,比如我們在項目中創建一個test文件夾,並在test文件夾中新增一個readme文件,這時這個readme文件還只是本地文件系統上的修改,還沒有存儲到git。
- 暫存區(Staging Area):暫存實際上是將我們本地文件系統的改動轉化爲git的對象存儲的過程,暫存區其實是一個文件,保存了下次將要提交的文件列表信息,一般在git倉庫目錄中。
- 倉庫(Repository):是git用來保存項目元數據和對象數據庫的地方,是git最重要的部分。git commit後將提交對象存儲到git倉庫。
另外!!!工作區中的任何文件都無外乎處於以下兩種狀態中的一種:
- 已跟蹤(tracked):這是指那些已經被納入版本控制的文件,在上一次快照中有它們的記錄,在工作一段時間後,它們可能處於未修改、已修改或已放入暫存區(初次從遠程倉庫中clone下來的文件都屬於已跟蹤未修改狀態)。
- 未跟蹤(untracked):工作區中除了已跟蹤外的所有文件都屬於未跟蹤文件,它們即不存在於上次快照記錄中,也沒有放入暫存區。
(要查看一個文件屬於哪種狀態,使用git status命令;將未跟蹤狀態變更爲已跟蹤狀態,使用git add命令。git add命令是一個多功能命令,可參照Git Documentation。)
參考文章: