那今天齊姐簡單講下 Git 的實現原理,知其因此然才能知其然;而且梳理了平常最經常使用的 12 個命令,分爲三大類分享給你。git
本文的結構以下:程序員
做者和開發起因github
Git 的數據模型數據庫
經常使用命令vim
資源推薦安全
Talk is cheap. Show me the code.服務器
這句話就出自 Linux 和 Git 的做者
Linus Torvalds。網絡
本來 Linux 內核的版本控制系統是用的 BitKeeper,然而 2005 年,BitMover 公司再也不讓 Linux 開發團隊無償使用了。。數據結構
Linus 一聽,不給用了?老子本身寫!分佈式
因而,大佬十天以內完成了 Git 的第一個版本。
因此 Git 是一個免費的、開源的版本控制系統。
版本控制其實每一個人都用過,那些年修改過的簡歷:
小齊簡歷 2012 版
小齊簡歷 2013 版
小齊簡歷 2014 版
小齊簡歷 2015 版
小齊簡歷 2016 版
小齊簡歷 2017 版
小齊簡歷 2018 版
小齊簡歷 2019 版
...
還有那些年打死都再也不改的畢業論文:
畢業論文最終版
畢業論文最最終版
畢業論文最最最終版
畢業論文最最最最終版
畢業論文最終不改版
畢業論文最終真不改版
畢業論文最終真真不改版
畢業論文最終打死不改版
畢業論文最終打死不改版 2
...
沒錯,這就是本地版本控制系統。
很明顯,好處是簡單,可是隻能一我的在這改,沒法和他人完成合做。那麼如下兩種主流的版本控制系統應運而生。
Centralized Version Control Systems (CVCS)
好比:CVS, Subversion, Perforce, etc.
這種版本控制系統有一個單一的集中管理的服務器,保存全部文件的最新版本,你們能夠經過鏈接到這臺服務器上來獲取或者提交文件。
這種模式相對本地版本控制系統是有所改進的,可是缺點也很明顯,若是服務器宕機,那麼輕則耽誤工做、重則數據丟失。因而分佈式版本控制系統應運而生。
Distributed Version Control Systems (DVCS)
好比:Git, Mercurial, Bazaar, etc.
分佈式的版本控制系統會把代碼倉庫完整地鏡像下來,這樣任何一個服務器發生故障,均可以用其餘的倉庫來修復。
更進一步,這種模式能夠更方便的和不一樣公司的人進行同一項目的開發,由於兩個遠程代碼倉庫能夠交互,這在以前的集中式系統中是沒法作到的。
CVCS 每一個版本存放的是當前版本與前一個版本的差別,所以也被稱做基於差別的版本控制 (delta-based);
Git 存儲的是全部文件的一個快照 (snapshot),若是有的文件沒有修改,那就只保留一個 reference 指向以前存儲的文件。
不是很好理解?那接着看吧~
首先咱們來學兩個 Git 中的術語:
快照則是被追蹤的最頂層的樹。
好比個人「公衆號」文件夾的這麼一個結構:
那麼一個快照就是追蹤的「公衆號」這顆樹。
Git 記錄了每一個快照的 parent,也就是當前這個文件夾的上一個版本。
那麼快照的迭代更新的過程就能夠表示爲一個有向無環圖,是否是很熟悉?咱們在「拓撲」那篇文章裏講過,忘了的小夥伴快去公衆號內回覆「拓撲」獲取拓撲的入門文章吧~
每一個快照其實都對應了一次 commit,咱們用代碼來表示一下:
class commit {
array<commit> parents
String author
String message
Tree snapshot
}
這就是 Git 的數據模型。
blob, tree, snapshot 其實都同樣,它們在 Git 中都是對象,均可以被引用或者被搜索,會基於它們的 SHA-1 hash 進行尋址。
git cat-file -t: 查看每一個 SHA-1 的類型;
git cat-file -p: 查看每一個對象的內容和簡單的數據結構。
可是經過這個哈希值來搜索也太不方便了,畢竟這是一串 40 位的十六進制字符,就是第二部分 git log 裏輸出的那個編碼。
所以,Git 還給了一個引用 reference。
好比,咱們常見的 HEAD 就是一個特殊的引用。
本地庫就是由 對象 和 引用 構成的,或者叫 Repositories.
在硬盤上,Git 只存儲 對象 和 引用,全部的 Git 命令都對應提交一個快照。
那有哪些經常使用命令呢?
本章分三大部分介紹平常經常使用命令:
在學習經常使用命令以前,你首先須要知道的 Git 的「三個分區」和對應的文件的「三種狀態」:
工做區:就是你本地實際寫代碼的地方,不管你是用 vim 直接改也好,仍是在 IDE 裏寫,都無所謂。
暫存區:就是臨時存放的地方。
本地庫:存放本地歷史版本信息。
工做區改完了代碼,就用 git add 提交到暫存區。
這裏若是文件改動的比較多,但又不是每一個都須要提交,我會設置 git ignore file,就表示這些文件不要提交,好比在 build project 的時候會自動生成的那些文件等等。
從暫存區提交到本地庫,就須要用 commit。
通常後面都會跟個 -m 加句 comment,簡單說下改動的內容或者緣由,咱們公司你們默認也會把 Jira連接附上,這樣就知道這個改動對應哪一個任務。
那若是想再改,再從新 git add 便可,可是 commit 這句須要改爲
$ git commit --amend
這樣就仍是一條 git log 信息。
git log 能夠查看到提交過的信息,從近到遠顯示每次 commit 的 comment 還有做者、日期等信息,好比大概長這個樣子:
commit 5abcd17dggs9s0a7a91nfsagd8ay76875afs7d6
Author: Xiaoqi<xiaoqi@163.com>
Date: xxx xxx xxx
改了 Test 文件
commit 後面的這個編號,是每次歷史記錄的一個索引。好比若是須要對版本進行前進或者後退的時候,就須要用到它。
這樣打印的 log 太多,更簡潔的打印方式是:
$ git log --oneline
就一行打印出來了。
或者:
$ git reflog
更經常使用一些。
那咱們剛剛說過,若是須要前進或退回到某個版本,就用
$ git reset --hard <編號>
這樣就直接跳到了這個編號對應的那個版本。
那麼這個 hard 是什麼意思呢?
這裏有 3 個參數:hard, soft, mixed,咱們一一來講一下。
回到咱們最重要的這張圖上來:
咱們剛剛說的前進或後退到某一版本,是對本地庫進行的操做。
那有個問題:
本地庫的代碼跳到那個版本以後,工做區和暫存區的代碼就和本地庫的不一樣步了呀!
那這些參數就是用來控制這些是否同步的。
三個區都同步,都跳到這個 xxx 的版本上。
前面兩個區不一樣步,就只有本地庫跳到這個版本。
暫存區同步,工做區不動。
因此呢,用的多的就是 hard.
和遠程庫的交互主要是推、拉,也就是寫入和讀取。
小齊寫完了代碼,要提交到公司的代碼庫裏,這個過程要用 git push.
固然了,這麼用會被打的。。畢竟還要 cr 呢。
新來的實習生首先要 clone 整個項目到本地來,而後才能增刪改查。
固然了實際工做中也沒人這麼用。。由於每家公司都會有本身包裝的工具。不過若是是作 Github 上的開源項目,就用得上了。
小齊提交了新的代碼以後,領導要審查呀,因此用 git pull 把最新的代碼拉取下來瞅瞅。
實際上呢,
git pull = fetch + merge
git fetch 這個操做是將遠程庫的數據下載到本地庫,可是工做區中的文件沒有更新。
而要談 get merge,咱們還須要先講下分支。
merge 是 git pull 默認的選項,合併其實還有另一種方法:rebase,中文叫作變基。
rebase 的做用更多的是來整合分叉的歷史,能夠將某個分支上的全部修改都移到另外一分支上,就像是變了基底。
首先咱們來看幾個關於分支的基本操做:
$ git branch
相似於ls,可以列出當前全部分支。
git branch -v 可以顯示更多信息。
$ git branch <branchName>
$ git checkout <branchName>
有了分支以後必然會有合併:
$ git merge <branchName>
而合併時就可能會有衝突,何時會有衝突呢?:
在同一個文件的同一個位置修改時。
由於 Git 會努力的把大家改動不一樣的地方合併在一塊兒,但若是實在是在同一個地方改的,那它也沒辦法了,只能留給程序員去手動處理了。
固然了,每一個命令延伸下去還有無限多個,本文不可能涵蓋所有,因此在此重磅推薦齊姐精心挑選的三大學習資源,你們能夠自行享用~
其實我我的使用最多的是git help
真心方便又好用啊!
好比 git help pull:
先介紹了有哪些參數,而後 description 詳細解釋了它的工做原理,下面還有圖解,有木有太香!!
不過這種方式更像是 cheatsheet,當你已經知道了這個命令、只是忘了它的用法的時候去查。
若是你想系統的學習,那麼下面 ???? 的更適合你。
這本書是強烈推薦了!!
Pro Git 這本書不只講了 Git 的基礎用法、高級用法,以及最後還深刻講解了 Git 的原理,很是細緻全面。
書的電子版也能在網站上直接下載。
英文版:
中文版:
Practice makes perfect!
推薦一個寶藏資源:玩遊戲來練 Git
項目:https://github.com/pcottle/learnGitBranching
網址:https://learngitbranching.js.org/
我熟悉不少工具都是經過小遊戲來練習的,好比 vim 的操做,仍是蠻推薦這種方式的。就不劇透啦,你們本身去探索吧~
*版權聲明:轉載文章和圖片均來自公開網絡,版權歸做者本人全部,推送文章除非沒法確認,咱們都會註明做者和來源。若是出處有誤或侵犯到原做者權益,請與咱們聯繫刪除或受權事宜。