Git與SVN的差別
存儲方式不同
Git把内容按中繼資料方式存儲類似k/v資料庫,而SVN是按檔案(新版SVN已改成中繼資料存儲)
這裡,我們給出一個簡單的Git使用示例。
cd .git/objects/df/
git cat-file -p df70460b4b4aece5915caf5c68d12f560a9de56e
echo 'version1' > text.txt
git hash-object -w text.txt
使用方式不同
從本地把檔案推送遠端服務,SVN隻需要commint 而Git需要 add、commint、push 三個步驟。
比如,我們使用下圖來模拟SVN的使用過程。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicGcq5SZ5kDNiFWOwEjN5ITOxMjYlBTY0IGN2MmNmVjMlhjMh9CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.jpg)
我們可以使用下圖來模拟Git的使用過程。
版本的管理模式不同
Git是一個分布式的版本管理系統,而要SVN是一個遠端集中式的管理系統。
例如,我們可以使用下圖來表示SVN的集中式管理。
我們可以使用下圖來表示Git的分布式管理。
Git核心命
為什麼網際網路巨頭們紛紛使用Git而放棄SVN?(内含Git核心指令與原理總結) 令總結
Git用戶端安裝
官方用戶端下載下傳:
https://git-scm.com/downloads其他用戶端下載下傳:
https://tortoisegit.org/download/Git指令的使用
(1)基于遠端倉庫克隆至本地
git clone <remote_url>
(2)目前目錄初始化為git 本地倉庫
git init <directory>
(3)基于mvn 模闆建立項目
mvn archetype:generate
本地添加
(1)添加指定檔案至暫存區
git add <fileName>
(2)添加指定目錄至暫存區
git add <directory>
(3)添加所有
git add -A
(4)将指定目錄及子目錄移除出暫存區
git rm --cached target -r
(5)添加忽略配置檔案 .gitignore
本地送出
(1)送出至本地倉庫
git commit file -m '送出的注釋資訊'
(2)快捷送出至本地倉庫
git commit -am '快捷添加與送出'
分支管理
(1)檢視目前分支
git branch [-avv]
(2)基于目前分支建立分支
git branch <branch name>
(3)基于送出建立分支
git branch <branch name> <commit id>
$ git branch -d {dev}
(4)切換分支
git checkout <branch name>
(5)合并分支
git merge <merge target>
(6)解決沖突
如果因沖突導緻自動合并失敗,此時 status 為mergeing 狀态。需要手動修改後重新送出(commit)
遠端倉庫管理
(1)檢視遠端配置
git remote [-v]
(2)添加遠端位址
git remote add origin http:xxx.xxx
(3)删除遠端位址
git remote remove origin
(4)上傳新分支至遠端
git push --set-upstream origin master
(5)将本地分支與遠端建立關聯
git branch --track --set-upstream-to=origin/test test
Tag管理
(1)檢視目前
git tag
(2)建立分支
git tag <tag name> <branch name>
(3)删除分支
git tag -d <tag name>
日志管理
(1)檢視目前分支下所有送出日志
git log
(2)檢視目前分支下所有送出日志
git log {branch}
(3)單行顯示日志
git log --oneline
(4)比較兩個版本的差別
git log master..experiment
(5)以圖表的方式顯示送出合并網絡
git log --pretty=format:'%h %s' --graph
Git底層原理
GIT存儲對像(hashMap)
Git 是一個内容尋址檔案系統,其核心部分是一個簡單的鍵值對資料庫(key-value data store),你可以向資料庫中插入任意内容,它會傳回一個用于取回該值的hash 鍵。
(1) Git 鍵值庫中插入資料
echo 'binghe' | git hash-object -w --stdin 79362d07cf264f8078b489a47132afbc73f87b9a
(2)基于鍵擷取指定内容
git cat-file -p 79362d07cf264f8078b489a47132afbc73f87b9a
Git基于該功能 把每個檔案的版本中内容都儲存在資料庫中,當要進行版本復原的時候就通過其中一個鍵将其取回并替換。
Git版本寫入與復原過程
(1)查找所有的git 對像
find .git/objects/ -type f
(2)寫入版本1
echo 'version1' > README.MF; git hash-object -w README.MF;
(3)寫入版本2
echo 'version2' > README.MF; git hash-object -w README.MF;
(4)寫入版本3
echo 'version3' > README.MF; git hash-object -w README.MF;
(5)復原指定版本
git cat-file -p c11e96db44f7f3bc4c608aa7d7cd9ba4ab25066e > README.MF
是以我們平常用的 git add 其實就是把修改之後的内容 插入到鍵值庫中。當我們執行 git add README.MF 等同于執行了 git hash-object -w README.MF 把檔案寫到資料庫中。
我們解決了存儲的問題,但其隻能存儲内容同并沒有存儲檔案名,如果要進行復原 怎麼知道哪個内容對應哪個檔案呢?接下要我們就看下樹對象,它解決了檔案名存儲的問題 。
Git樹對象
樹對像解決了檔案名的問題,它的目的将多個檔案名組織在一起,其内包含多個檔案名稱與其對應的Key和其它樹對像的用引用,可以了解成作業系統當中的檔案夾,一個檔案夾包含多個檔案和多個其它檔案夾。
每一個分支當中都關聯了一個樹對像,他存儲了目前分支下所有的檔案名及對應的 key。通過以下指令即可檢視
git cat-file -p master^{tree}
Git送出對象
一次送出即為目前版本的一個快照,該快照就是通過送出對像儲存,其存儲的内容為:一個頂級樹對象、上一次送出的對像啥希、送出者使用者名及郵箱、送出時間戳、送出評論。
$ git cat-file -p b2395925b5f1c12bf8cb9602f05fc8d580311836
tree 002adb8152f7cd49f400a0480ef2d4c09b060c07
parent 8be903f5e1046b851117a21cdc3c80bdcaf97570
author binghe <[email protected]> 1532959457 +0800
committer binghe <[email protected]> 1532959457 +0800
綜上,我們可以推測出從修改一個檔案到送出的過程總共生成了三個對象:
- 一個内容對象:存儲了檔案内容
- 一個樹對像:存儲了檔案名及内容對像的key
- 一個送出對像:存儲了樹對像的key 及送出評論。
Git引用
當我們執行 git branch {branchName} 時建立了一個分支,其本質就是在git 基于指定送出建立了一個引用檔案,儲存在 .git\refs\heads\ 下。
(1)建立分支
git branch dev
cat.git\refs\heads\dev
Git總共 有三種類型的引用:
- 分支引用
- 遠端分支引用
- 标簽引用
(2)查詢比較兩個版本
git log master..experiment
(3)版本送出曆史網絡
git log --pretty=format:'%h %s' --graph
(4)檢視分支樹
git cat-file -p master^{tree}