Git那些事兒

Panda發表於2016-06-08

Git是目前世界上最先進的分散式版本控制系統,適合多人協作開發的大型專案。我平常也經常使用git,來管理自己的幾個小專案。簡單說說git的原理和git的特點!(只有知道了一個工具的執行原理,設計思路,才能更好的使用這個工具)

1. 自己對SVN和Git的體驗

在公司一直用SVN,自己折騰的業餘專案用Git我的Github。個人認為SVN用起來比較快捷,方便,提交程式碼只需要 commit一下就行了,適合小團隊的程式碼版本管理。但是一個大型的開源專案,可能有幾百或者上千個開發者提交程式碼,SVN就顯得力不從心了!SO Git大法橫空出世了!

2. Git的誕生背景

自2002年開始,林納斯·託瓦茲決定使用BitKeeper作為Linux核心主要的版本控制系統用以維護程式碼。因為BitKeeper為專有軟體,這個決定在社群中長期遭受質疑。在Linux社群中,特別是理查德·斯托曼與自由軟體基金會的成員,主張應該使用開放原始碼的軟體來作為Linux核心的版本控制系統。林納斯·託瓦茲曾考慮過採用現成軟體作為版本控制系統(例如Monotone),但這些軟體都存在一些問題,特別是效能不佳。現成的方案,如CVS的架構,受到林納斯·託瓦茲的批評

2005年,安德魯·垂鳩寫了一個簡單程式,可以連線BitKeeper的儲存庫,BitKeeper著作權擁有者拉里·麥沃伊認為安德魯·垂鳩對BitKeeper內部使用的協議進行逆向工程,決定收回無償使用BitKeeper的授權。Linux核心開發團隊與BitMover公司進行蹉商,但無法解決他們之間的歧見。林納斯·託瓦茲決定自行開發版本控制系統替代BitKeeper,以十天的時間,編寫出第一個git版本

資料來自維基百科Git-維基百科

3. Git於SVN的主要區別

SVN是集中式版本控制系統,版本庫是集中放在中央伺服器的,而幹活的時候,用的都是自己的電腦,所以首先要從中央伺服器哪裡得到最新的版本,然後幹活,幹完後,需要把自己做完的活推送到中央伺服器。集中式版本控制系統是必須聯網才能工作,如果在區域網還可以,頻寬夠大,速度夠快,如果在網際網路下,如果網速慢的話,就納悶了。

Git是分散式版本控制系統,那麼它就沒有中央伺服器的,每個人的電腦就是一個完整的版本庫,這樣,工作的時候就不需要聯網了,因為版本都是在自己的電腦上。既然每個人的電腦都有一個完整的版本庫,那多個人如何協作呢?比如說自己在電腦上改了檔案A,其他人也在電腦上改了檔案A,這時,你們兩之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。

4. 淺析Git原理

git的底層從其本質上講是一個內容定址檔案系統,然後基於這個內容定址檔案系統實現了一套vcs(版本控制系統)的高層介面,方便我們使用.當然git也提供了底層介面,便於我們使用之做出符合自己需求的系統.

我們把檔案內容交給git進行管理,總得有一個地方來存放這些內容是吧!
是的,在git中,所有的檔案內容都儲存在git倉庫的objects目錄中.

初始化git庫

我們初始化一個git倉庫有兩種方式,git init和git –bare init
這兩者的區別是,前者會在當前目錄下生成一個.git目錄(此目錄即為git庫的目錄),而當前目錄為我們的工作目錄,一般是checkout後的檔案,我們程式設計時所讀寫的內容都在此目錄下.
後者的bare的意思就是裸的意思,也就是直接把當前目錄當作git庫的目錄,這個一般用在遠端git庫上,因為我們在遠端git庫上沒有checkout的需求,只是用作單純的git庫
git庫還有個優點就是直接拷貝到另一個地方就可以直接用了,只要你的相應的機器上安裝了git即可.

git物件

git中一個非常重要的概念就是git物件,我們可以把git系統想象成一個強大的key-value儲存,每一個物件都對應著一個40位的雜湊值.通過這個雜湊值我們便可以很容易的取得物件(當然我們可以為這些雜湊值取一些有意義的別名,方便我們使用).我們可以把這個雜湊值看作指標.而對應的物件就是指標所指向的實體.物件和物件之間還可以通過通過指標進行一些關聯的操作.
git物件可分為四種型別:

  • blob物件 用來存放檔案資料

  • tree物件 對應著目錄,tree的內容為blob物件的指標或者其他tree物件的指標

  • commit物件 每一次commit都會產生一個新的commit物件,其包含了一個指向tree物件的指標,指向前一次commit物件的指標,還包含了commit的時間,作者和註釋等資訊,就相當於為專案做了一次snapshot,通過commit物件我們可以跟蹤到前一次commit物件,這樣就可以實現log功能了

  • tag物件 一種特殊的commit物件

git庫目錄
接下來分析git庫目錄中各個檔案的作用

Wujunze-MacBook:test.git Junze$ ls -al
total 32
drwxr-xr-x  11 Luke  staff   374 Jun  4 20:21 .
drwxr-xr-x  24 Luke  staff   816 Jun  4 20:21 ..
-rw-r--r--   1 Luke  staff    23 Jun  4 20:21 HEAD (當前分支的指標)
drwxr-xr-x   2 Luke  staff    68 Jun  4 20:21 branches
-rw-r--r--   1 Luke  staff    85 Jun  4 20:21 config
-rw-r--r--   1 Luke  staff    73 Jun  4 20:21 description
drwxr-xr-x  12 Luke  staff   408 Jun  4 20:21 hooks (可以實現在特定操作的前或者後觸發一些動作)
drwxr-xr-x   3 Luke  staff   102 Jun  4 20:21 info
drwxr-xr-x  64 Luke  staff  2176 Jun  4 20:21 objects (blob,tree,commit,tag 物件)
-rw-r--r--   1 Luke  staff    85 Jun  4 20:21 packed-refs
drwxr-xr-x   4 Luke  staff   136 Jun  4 20:21 refs (指向各個分支的指標)

objects儲存的時候,以40位雜湊值的前兩位作為子目錄的名稱,後38位作為物件的檔名
git系統會定期對所有的objects進行打包操作,這樣可以減少磁碟佔用空間
git中最新版本的都是直接儲存的,以前版本是通過引用最新的檔案以及差異進行獲取的,這是因為大都數時候我們對最新的分支程式碼更為關注

5.Git的學習

先熟悉Git的執行原理和設計思路,然後把自己的專案遷移到Git。自己動手用Git,才能真正的熟練使用Git!
推薦一個不錯的Git教程,廖雪峰的Git教程!最淺顯易懂的Git教程
也歡迎大家加QQ群213470752一起學習交流Git的使用!

6.Git常用命令

PS: 一些Git命令使用了別名 co=checkout ci=commit br=branch
檢視、新增、提交、刪除、找回,重置修改檔案

git help <command> # 顯示command的help

git show # 顯示某次提交的內容 git show $id

git co — <file> # 拋棄工作區修改

git co . # 拋棄工作區修改

git add <file> # 將工作檔案修改提交到本地暫存區

git add . # 將所有修改過的工作檔案提交暫存區

git rm <file> # 從版本庫中刪除檔案

git rm <file> –cached # 從版本庫中刪除檔案,但不刪除檔案

git reset <file> # 從暫存區恢復到工作檔案

git reset — . # 從暫存區恢復到工作檔案

git reset –hard # 恢復最近一次提交過的狀態,即放棄上次提交後的所有本次修改

git ci <file> git ci . git ci -a # 將git add, git rm和git ci等操作都合併在一起做 git ci -am “some comments”

git ci –amend # 修改最後一次提交記錄

git revert <$id> # 恢復某次提交的狀態,恢復動作本身也建立次提交物件

git revert HEAD # 恢復最後一次提交的狀態

檢視檔案diff

git diff <file> # 比較當前檔案和暫存區檔案差異 git diff

git diff <id1><id1><id2> # 比較兩次提交之間的差異

git diff <branch1>..<branch2> # 在兩個分支之間比較

git diff –staged # 比較暫存區和版本庫差異

git diff –cached # 比較暫存區和版本庫差異

git diff –stat # 僅僅比較統計資訊

檢視提交記錄

git log git log <file> # 檢視該檔案每次提交記錄

git log -p <file> # 檢視每次詳細修改內容的diff

git log -p -2 # 檢視最近兩次詳細修改內容的diff

git log –stat #檢視提交統計資訊

tig

Mac上可以使用tig代替diff和log,brew install tig

Git 本地分支管理

檢視、切換、建立和刪除分支

git br -r # 檢視遠端分支

git br <new_branch> # 建立新的分支

git br -v # 檢視各個分支最後提交資訊

git br –merged # 檢視已經被合併到當前分支的分支

git br –no-merged # 檢視尚未被合併到當前分支的分支

git co <branch> # 切換到某個分支

git co -b <new_branch> # 建立新的分支,並且切換過去

git co -b <new_branch> <branch> # 基於branch建立新的new_branch

git co $id # 把某次歷史提交記錄checkout出來,但無分支資訊,切換到其他分支會自動刪除

git co $id -b <new_branch> # 把某次歷史提交記錄checkout出來,建立成一個分支

git br -d <branch> # 刪除某個分支

git br -D <branch> # 強制刪除某個分支 (未被合併的分支被刪除的時候需要強制)

分支合併和rebase

git merge <branch> # 將branch分支合併到當前分支

git merge origin/master –no-ff # 不要Fast-Foward合併,這樣可以生成merge提交

git rebase master <branch> # 將master rebase到branch,相當於: git co <branch> && git rebase master && git co master && git merge <branch>

Git補丁管理(方便在多臺機器上開發同步時用)

git diff > ../sync.patch # 生成補丁

git apply ../sync.patch # 打補丁

git apply –check ../sync.patch #測試補丁能否成功

Git暫存管理

git stash # 暫存

git stash list # 列所有stash

git stash apply # 恢復暫存的內容

git stash drop # 刪除暫存區

Git遠端分支管理

git pull # 抓取遠端倉庫所有分支更新併合併到本地

git pull –no-ff # 抓取遠端倉庫所有分支更新併合併到本地,不要快進合併

git fetch origin # 抓取遠端倉庫更新

git merge origin/master # 將遠端主分支合併到本地當前分支

git co –track origin/branch # 跟蹤某個遠端分支建立相應的本地分支

git co -b <local_branch> origin/<remote_branch> # 基於遠端分支建立本地分支,功能同上

git push # push所有分支

git push origin master # 將本地主分支推到遠端主分支

git push -u origin master # 將本地主分支推到遠端(如無遠端主分支則建立,用於初始化遠端倉庫)

git push origin <local_branch> # 建立遠端分支, origin是遠端倉庫名

git push origin <local_branch>:<remote_branch> # 建立遠端分支

git push origin :<remote_branch> #先刪除本地分支(git br -d <branch>),然後再push刪除遠端分支

Git遠端倉庫管理

GitHub

git remote -v # 檢視遠端伺服器地址和倉庫名稱

git remote show origin # 檢視遠端伺服器倉庫狀態

git remote add origin git@ github:robbin/robbin_site.git # 新增遠端倉庫地址

git remote set-url origin git@ github.com:robbin/robbin_site.git # 設定遠端倉庫地址(用於修改遠端倉庫地址) git remote rm <repository> # 刪除遠端倉庫

建立遠端倉庫

git clone –bare robbin_site robbin_site.git # 用帶版本的專案建立純版本倉庫

scp -r my_project.git git@ git.csdn.net:~ # 將純倉庫上傳到伺服器上

mkdir robbin_site.git && cd robbin_site.git && git –bare init # 在伺服器建立純倉庫

git remote add origin git@ github.com:robbin/robbin_site.git # 設定遠端倉庫地址

git push -u origin master # 客戶端首次提交

git push -u origin develop # 首次將本地develop分支提交到遠端develop分支,並且track

git remote set-head origin master # 設定遠端倉庫的HEAD指向master分支

也可以命令設定跟蹤遠端庫和本地庫

git branch –set-upstream master origin/master

git branch –set-upstream develop origin/develop

總結

Git是工具,是開發者用工具,開發者利用工具讓專案的管理更加方便!開發者不要被Git所限制,不能被工具牽著走!
使用Git,可以自己搭建Git服務,可以可以使用第三方提供的免費服務!例如:GitHub OSC Coding
大家有什麼好的學習Git學習心得或者方法的可以郵件1017109588@qq.com一起交流學習哦!
原文連結https://wujunze.com/git_something.jsp轉載文章請保留原文連結

參考
Git官方文件
Git原理淺析
廖雪峰Git教程

等技術文件

相關文章