1. Git 看這一篇就夠了

        共 4832字,需瀏覽 10分鐘

         ·

        2020-08-02 00:43


        點(diǎn)擊「閱讀原文」查看良許原創(chuàng)精品視頻。

        今天簡(jiǎn)單講下 Git 的實(shí)現(xiàn)原理,知其所以然才能知其然;并且梳理了日常最常用的 12 個(gè)命令,分為三大類分享給你。

        本文的結(jié)構(gòu)如下:

        1. 作者和開(kāi)發(fā)原由

        2. Git 的數(shù)據(jù)模型

        3. 常用命令

        4. 資源推薦

        作者和開(kāi)發(fā)原由

        Talk is cheap. Show me the code.

        這句話就出自 Linux 和 Git 的作者
        Linus Torvalds。

        原本 Linux 內(nèi)核的版本控制系統(tǒng)是用的 BitKeeper,然而 2005 年,BitMover 公司不再讓 Linux 開(kāi)發(fā)團(tuán)隊(duì)免費(fèi)使用了。。

        Linus 一聽(tīng),不給用了?老子自己寫!

        于是,大佬十天之內(nèi)完成了 Git 的第一個(gè)版本。

        所以 Git 是一個(gè)免費(fèi)的、開(kāi)源的版本控制系統(tǒng)。

        版本控制系統(tǒng)

        版本控制其實(shí)每個(gè)人都用過(guò),那些年修改過(guò)的簡(jiǎn)歷:

        小齊簡(jiǎn)歷 2012 版
        小齊簡(jiǎn)歷 2013 版
        小齊簡(jiǎn)歷 2014 版
        小齊簡(jiǎn)歷 2015 版
        小齊簡(jiǎn)歷 2016 版
        小齊簡(jiǎn)歷 2017 版
        小齊簡(jiǎn)歷 2018 版
        小齊簡(jiǎn)歷 2019 版
        ...

        還有那些年打死都不再改的畢業(yè)論文:

        畢業(yè)論文最終版
        畢業(yè)論文最最終版
        畢業(yè)論文最最最終版
        畢業(yè)論文最最最最終版
        畢業(yè)論文最終不改版
        畢業(yè)論文最終真不改版
        畢業(yè)論文最終真真不改版
        畢業(yè)論文最終打死不改版
        畢業(yè)論文最終打死不改版 2
        ...

        沒(méi)錯(cuò),這就是本地版本控制系統(tǒng)。

        很明顯,好處是簡(jiǎn)單,但是只能一個(gè)人在這改,無(wú)法和他人完成合作。那么以下兩種主流的版本控制系統(tǒng)應(yīng)運(yùn)而生。

        1. 集中化版本控制系統(tǒng)

        Centralized Version Control Systems (CVCS)

        比如:CVS, Subversion, Perforce, etc.

        這種版本控制系統(tǒng)有一個(gè)單一的集中管理的服務(wù)器,保存所有文件的最新版本,大家可以通過(guò)連接到這臺(tái)服務(wù)器上來(lái)獲取或者提交文件。

        這種模式相對(duì)本地版本控制系統(tǒng)是有所改進(jìn)的,但是缺點(diǎn)也很明顯,如果服務(wù)器宕機(jī),那么輕則耽誤工作、重則數(shù)據(jù)丟失。于是分布式版本控制系統(tǒng)應(yīng)運(yùn)而生。

        2. 分布式版本控制系統(tǒng)

        Distributed Version Control Systems (DVCS)

        比如:Git, Mercurial, Bazaar, etc.

        分布式的版本控制系統(tǒng)會(huì)把代碼倉(cāng)庫(kù)完整地鏡像下來(lái),這樣任何一個(gè)服務(wù)器發(fā)生故障,都可以用其他的倉(cāng)庫(kù)來(lái)修復(fù)。

        更進(jìn)一步,這種模式可以更方便的和不同公司的人進(jìn)行同一項(xiàng)目的開(kāi)發(fā),因?yàn)閮蓚€(gè)遠(yuǎn)程代碼倉(cāng)庫(kù)可以交互,這在之前的集中式系統(tǒng)中是無(wú)法做到的。

        那么什么叫“把代碼倉(cāng)庫(kù)完整地鏡像下來(lái)”呢?

        CVCS 每個(gè)版本存放的是當(dāng)前版本與前一個(gè)版本的差異,因此也被稱作基于差異的版本控制 (delta-based);

        Git 存儲(chǔ)的是所有文件的一個(gè)快照 (snapshot),如果有的文件沒(méi)有修改,那就只保留一個(gè) reference 指向之前存儲(chǔ)的文件。

        不是很好理解?那接著看吧~

        Git 的數(shù)據(jù)模型

        1. 什么是快照 (snapshot) 呢?

        首先我們來(lái)學(xué)兩個(gè) Git 中的術(shù)語(yǔ):

        • blob, 就是單個(gè)的文件;
        • tree, 就是一個(gè)文件夾。

        快照則是被追蹤的最頂層的樹。

        比如我的“公眾號(hào)”文件夾的這么一個(gè)結(jié)構(gòu):

        那么一個(gè)快照就是追蹤的“公眾號(hào)”這顆樹。

        2. 本地庫(kù)的數(shù)據(jù)模型

        Git 記錄了每個(gè)快照的 parent,也就是當(dāng)前這個(gè)文件夾的上一個(gè)版本。

        那么快照的迭代更新的過(guò)程就可以表示為一個(gè)有向無(wú)環(huán)圖

        每個(gè)快照其實(shí)都對(duì)應(yīng)了一次 commit,我們用代碼來(lái)表示一下:

        class commit {
        array parents
        String author
        String message
        Tree snapshot
        }

        這就是 Git 的數(shù)據(jù)模型。

        blob, tree, snapshot 其實(shí)都一樣,它們?cè)?Git 中都是對(duì)象,都可以被引用或者被搜索,會(huì)基于它們的 SHA-1 hash 進(jìn)行尋址。

        git cat-file -t: 查看每個(gè) SHA-1 的類型;
        git cat-file -p: 查看每個(gè)對(duì)象的內(nèi)容和簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)。

        但是通過(guò)這個(gè)哈希值來(lái)搜索也太不方便了,畢竟這是一串 40 位的十六進(jìn)制字符,就是第二部分 git log 里輸出的那個(gè)編碼。

        因此,Git 還給了一個(gè)引用 reference。

        比如,我們常見(jiàn)的 HEAD 就是一個(gè)特殊的引用。

        本地庫(kù)就是由 對(duì)象引用 構(gòu)成的,或者叫 Repositories.

        在硬盤上,Git 只存儲(chǔ) 對(duì)象引用,所有的 Git 命令都對(duì)應(yīng)提交一個(gè)快照。

        那有哪些常用命令呢?

        常用命令

        本章分三大部分介紹日常常用命令:

        • 本地操作
        • 和遠(yuǎn)程庫(kù)的交互
        • 團(tuán)隊(duì)協(xié)作 - 分支

        本地操作

        在學(xué)習(xí)常用命令之前,你首先需要知道的 Git 的「三個(gè)分區(qū)」和對(duì)應(yīng)的文件的「三種狀態(tài)」:

        • 工作區(qū):就是你本地實(shí)際寫代碼的地方,無(wú)論你是用 vim 直接改也好,還是在 IDE 里寫,都無(wú)所謂。

          • 對(duì)應(yīng)的文件狀態(tài)是:modified,已修改,但還沒(méi)保存到數(shù)據(jù)庫(kù)中。
        • 暫存區(qū):就是臨時(shí)存放的地方。

          • 對(duì)應(yīng)的文件狀態(tài)是:staged,Git 已經(jīng)對(duì)該文件做了標(biāo)記,下次提交知道要包含它。
        • 本地庫(kù):存放本地歷史版本信息。

          • 對(duì)應(yīng)的文件狀態(tài)是:committed,文件已經(jīng)安全的保存在本地?cái)?shù)據(jù)庫(kù)中。

        1. $ git add

        工作區(qū)改完了代碼,就用 git add 提交到暫存區(qū)。

        這里如果文件改動(dòng)的比較多,但又不是每個(gè)都需要提交,我會(huì)設(shè)置 git ignore file,就表示這些文件不要提交,比如在 build project 的時(shí)候會(huì)自動(dòng)生成的那些文件等等。

        2. $ git commit -m "comment"

        從暫存區(qū)提交到本地庫(kù),就需要用 commit。

        一般后面都會(huì)跟個(gè) -m 加句 comment,簡(jiǎn)單說(shuō)下改動(dòng)的內(nèi)容或者原因,我們公司大家默認(rèn)也會(huì)把 Jira鏈接附上,這樣就知道這個(gè)改動(dòng)對(duì)應(yīng)哪個(gè)任務(wù)。

        那如果想再改,再重新 git add 即可,但是 commit 這句需要改成

        $ git commit --amend

        這樣就還是一條 git log 信息。

        3. $ git log

        git log 可以查看到提交過(guò)的信息,從近到遠(yuǎn)顯示每次 commit 的 comment 還有作者、日期等信息,比如大概長(zhǎng)這個(gè)樣子:

        commit 5abcd17dggs9s0a7a91nfsagd8ay76875afs7d6
        Author: Xiaoqi
        Date: xxx xxx xxx
        改了 Test 文件

        commit 后面的這個(gè)編號(hào),是每次歷史記錄的一個(gè)索引。比如如果需要對(duì)版本進(jìn)行前進(jìn)或者后退的時(shí)候,就需要用到它。

        這樣打印的 log 太多,更簡(jiǎn)潔的打印方式是:

        $ git log --oneline

        就一行打印出來(lái)了。

        或者:

        $ git reflog

        更常用一些。

        4. $ git reset

        那我們剛剛說(shuō)過(guò),如果需要前進(jìn)或退回到某個(gè)版本,就用

        $ git reset --hard <編號(hào)>

        這樣就直接跳到了這個(gè)編號(hào)對(duì)應(yīng)的那個(gè)版本。

        那么這個(gè) hard 是什么意思呢?

        這里有 3 個(gè)參數(shù):hard, soft, mixed,我們一一來(lái)說(shuō)一下。

        回到我們最重要的這張圖上來(lái):

        我們剛剛說(shuō)的前進(jìn)或后退到某一版本,是對(duì)本地庫(kù)進(jìn)行的操作。

        那有個(gè)問(wèn)題:
        本地庫(kù)的代碼跳到那個(gè)版本之后,工作區(qū)和暫存區(qū)的代碼就和本地庫(kù)的不同步了呀!

        那這些參數(shù)就是用來(lái)控制這些是否同步的。

        $ git reset --hard xxx

        三個(gè)區(qū)都同步,都跳到這個(gè) xxx 的版本上。

        $ git reset --soft xxx

        前面兩個(gè)區(qū)不同步,就只有本地庫(kù)跳到這個(gè)版本。

        $ git reset --mixed xxx

        暫存區(qū)同步,工作區(qū)不動(dòng)。

        所以呢,用的多的就是 hard.

        遠(yuǎn)程交互

        和遠(yuǎn)程庫(kù)的交互主要是,也就是寫入和讀取。

        5. $ git push

        小齊寫完了代碼,要提交到公司的代碼庫(kù)里,這個(gè)過(guò)程要用 git push.

        當(dāng)然了,這么用會(huì)被打的。。畢竟還要 cr 呢。

        5. $ git clone

        新來(lái)的實(shí)習(xí)生首先要 clone 整個(gè)項(xiàng)目到本地來(lái),然后才能增刪改查。

        當(dāng)然了實(shí)際工作中也沒(méi)人這么用。。因?yàn)槊考夜径紩?huì)有自己包裝的工具。不過(guò)如果是做 Github 上的開(kāi)源項(xiàng)目,就用得上了。

        6. $ git pull

        小齊提交了新的代碼之后,領(lǐng)導(dǎo)要審查呀,所以用 git pull 把最新的代碼拉取下來(lái)瞅瞅。

        實(shí)際上呢,

        git pull = fetch + merge

        7. $ git fetch

        git fetch 這個(gè)操作是將遠(yuǎn)程庫(kù)的數(shù)據(jù)下載到本地庫(kù),但是工作區(qū)中的文件沒(méi)有更新。

        而要談 get merge,我們還需要先講下分支。

        mergegit pull 默認(rèn)的選項(xiàng),合并其實(shí)還有另外一種方法:rebase,中文叫做變基。

        8. $ git rebase

        rebase 的作用更多的是來(lái)整合分叉的歷史,可以將某個(gè)分支上的所有修改都移到另一分支上,就像是變了基底。

        分支與合并

        首先我們來(lái)看幾個(gè)關(guān)于分支的基本操作:

        9. 查看分支:

        $ git branch

        類似于ls,能夠列出當(dāng)前所有分支。

        git branch -v 能夠顯示更多信息。

        10. 創(chuàng)建分支:

        $ git branch

        11. 切換分支:

        $ git checkout

        有了分支之后必然會(huì)有合并:

        12. 合并分支:

        $ git merge

        而合并時(shí)就可能會(huì)有沖突,什么時(shí)候會(huì)有沖突呢?

        在同一個(gè)文件的同一個(gè)位置修改時(shí)。

        因?yàn)?Git 會(huì)努力的把你們改動(dòng)不同的地方合并在一起,但如果實(shí)在是在同一個(gè)地方改的,那它也沒(méi)辦法了,只能留給程序員去手動(dòng)處理了。

        當(dāng)然了,每個(gè)命令延伸下去還有無(wú)限多個(gè),本文不可能涵蓋全部,所以在此重磅推薦齊姐精心挑選的三大學(xué)習(xí)資源,大家可以自行享用~

        學(xué)習(xí)資源

        git help

        其實(shí)我個(gè)人使用最多的是git help

        真心方便又好用??!

        比如 git help pull:

        先介紹了有哪些參數(shù),然后 description 詳細(xì)解釋了它的工作原理,下面還有圖解,有木有太香??!

        不過(guò)這種方式更像是 cheatsheet,當(dāng)你已經(jīng)知道了這個(gè)命令、只是忘了它的用法的時(shí)候去查。

        如果你想系統(tǒng)的學(xué)習(xí),那么下面 ? 的更適合你。

        Pro Git

        這本書是強(qiáng)烈推薦了?。?/span>

        Pro Git 這本書不僅講了 Git 的基礎(chǔ)用法、高級(jí)用法,以及最后還深入講解了 Git 的原理,非常細(xì)致全面。

        書的電子版也能在網(wǎng)站上直接下載。

        英文版:

        • https://git-scm.com/book/en/v2

        中文版:

        • https://git-scm.com/book/zh/v2

        玩游戲

        Practice makes perfect!

        推薦一個(gè)寶藏資源:玩游戲來(lái)練 Git

        項(xiàng)目:https://github.com/pcottle/learnGitBranching

        網(wǎng)址:https://learngitbranching.js.org/

        我熟悉很多工具都是通過(guò)小游戲來(lái)練習(xí)的,比如 vim 的操作,還是蠻推薦這種方式的。就不劇透啦,大家自己去探索吧~

        良許個(gè)人微信


        添加良許個(gè)人微信即送3套程序員必讀資料


        → 精選技術(shù)資料共享

        → 高手如云交流社群





        本公眾號(hào)全部博文已整理成一個(gè)目錄,請(qǐng)?jiān)诠娞?hào)里回復(fù)「m」獲?。?/span>

        推薦閱讀:

        “kill -9”一時(shí)爽,秋后算賬淚兩行

        這個(gè)只有1.5M的軟件,能讓你的網(wǎng)速快3倍

        在Linux系統(tǒng)中使用Vim讀寫遠(yuǎn)程文件


        5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機(jī),樹莓派,等等。在公眾號(hào)內(nèi)回復(fù)「1024」,即可免費(fèi)獲?。?!


        瀏覽 51
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 亂伦丰满欧美日韩 | 淫色淫色免费视频 | 人人澡人人添人人爽一区二区 | 国产精品调教视频 | 国产成人精品免费 |