1. 程式人生 > >【Git】Git指令學習與其原理探究(一)

【Git】Git指令學習與其原理探究(一)

這篇文章記錄我學習Git的過程中遇到的問題及對於某些問題的看法,如有錯誤,還望不吝賜教! ps:這篇文章介紹本地庫,下篇將介紹與遠端庫的互動。 Git是什麼 & 為什麼要有Git?     既然您能看到這篇文章,相信你對Git也有了一點點的瞭解,或者您本來就是大神,來觀望下博主而已。     言歸正傳,那麼到底什麼是Git呢!

  Git是目前世界上最先進的分散式版本控制系統(沒有之一)。

    Git有什麼特點?簡單來說就是:高階大氣上檔次!

    那麼什麼是版本控制系統呢?:所謂的版本控制系統呢,簡單來說就是你寫的一個小專案,經過多次修改,你發現這和你原本的意願越走越遠,此時就想退回原來未修改前版本程式碼,但是你發現這可不是一件簡單的事,然後你想有沒有一種工具能讓我在寫的各個版本的原始碼之間隨意切換,滿足我的要求,那豈不是太爽了。這個需求linus幫你完成了,沒錯還是這個人
。兩週時間自己用C寫了一個分散式版本控制系統,這就是Git!一個月之內,Linux系統的原始碼已經由Git管理了!牛是怎麼定義的呢?大家可以體會一下。

    Git迅速成為最流行的分散式版本控制系統,尤其是2008年,GitHub網站上線了,它為開源專案免費提供Git儲存,無數開源專案開始遷移至GitHub,包括jQuery,PHP,Ruby等等。

SVN與Git的最主要的區別?

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

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

Git是如何工作的?

首先看張圖吧


圖中是我們經常使用的幾個命令,接下來我將根據圖中的命令詳細介紹各個部分。遠端倉庫,本地倉庫,工作區和暫存區的功能以及他們如何協調工作的。

Git本地倉庫:

git的本地倉庫主要有兩部分:


工作區(WorkSpace)就是存放你實際檔案的地方,主要儲存些你的程式碼,資料夾等,你在這個目錄下操作自己的檔案,這些檔案都是最後你要上傳到遠端倉庫的。

      版本庫(.git): 這個資料夾是你自己建立的目錄,具體操作請自行百度。版本庫又名倉庫,英文名repository,你可以簡單的理解一個目錄,這個目錄裡面的所有檔案都可以被Git管理起來,每個檔案的修改,刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻還可以將檔案”還原”,滿足你的需求。當我們通過git init命令將一個目錄程式設計git可以管理的倉庫時,這個目錄下就會生成一個隱藏的.git資料夾,這就是git的根本,git就是通過這個資料夾來完成我們的指令操作。.git目錄下還存在好多目錄,下面我們將介紹下上圖中的幾個比較重要的目錄,有的是檔案。

1.objects目錄存放的是實際的檔案,當git add命令執行的時候,檔案已經被存到了objects目錄下。

.git/objects目錄下的物件都有一個40位的id,前兩位作為目錄名,後38位作為檔名,您可以自行檢視下,這些物件主要是commit物件和tree物件(目錄樹)。

2.index是一個索引檔案。存放的是暫存區的整個目錄樹的資訊,並且為目錄樹中的每個檔案都儲存了時間戳和長度。

當git add 將某個檔案新增到暫存區的時候,index檔案中添加了這個檔案的基本資訊。

當我們修改了工作區的某個檔案(比如用touch config.js修改時間戳資訊),這會導致該檔案的時間戳發生變化,而index裡面存放的仍然是舊的資訊。

此時當我們執行git status命令來檢查版本庫的狀況:

a. git status就會用config.js的時間戳和長度和index檔案裡面儲存的config.js的時間戳和長度進行比較。

b. 如果相同,則認為沒有改變。

c. 如果發現不同。git status會繼續用config.js的檔案現在的內容和舊版本的config.js(儲存在.git/objects中)的內容進行比較。

d. 如果內容沒有改變,就簡單的將最新的config.js的時間戳資訊更新到index檔案中

e. 如果內容改變,則提示內容發生改變。但是並不更新index檔案中的config.js的時間戳資訊。

由於優先比較時間戳和長度,避免了當時間戳相同時的檔案內容的比較,因此效能比較高。

因此,git add命令會做兩件事情:

a.新增檔案到暫存區(.git/objects)

b.新增檔案索引到(.git/index)

3.當git commit被成功執行後,會產生一系列物件表示該commit的結果,都儲存在.git/objects目錄下。主要分成三部分:

a.tree物件表示當前commit時候的暫存區的目錄樹,tree物件的內容來自於.git/index檔案。

b.blob物件

tree物件目錄樹中的檔案總是以blob的物件被儲存。如果tree中有三個檔案,那麼就有對應的三個blob物件,它們都能通過tree物件儲存的這些blob物件的摘要資訊(id,檔名,型別等)找到

c.commit物件

該物件記錄了屬於哪個tree物件,上一次commit的物件id,自己的id,作者等等。

因此,當git commit操作執行的時候,會:

a. 用.git/index檔案儲存的目錄樹建立tree物件,

b. 因此tree物件裡面自然就指向了已經被git add新增到.git/objects中的blob檔案。

c. .git/refs/heads/master檔案儲存了這次commit的id

4.HEAD檔案儲存了當前的branch,也就是說HEAD指向了master分支,如果存在多個分支,HEAD也可指向別的分支。

5. .git/refs 目錄稱為引用目錄

引用就是一個檔案,裡面包含了一個commit id。.git/refs儲存了所有的引用。

.git/refs/heads目錄下儲存的是分支引用,比如./git/refs/heads/master檔案就是master分支的引用。

.git/refs/tags目錄儲存了tag引用。    

下面介紹一下上面所說的三個屬於git的物件,它們的組成如圖所示


如上是三個git的物件,那麼他們是如何組織的呢,如下圖:


下面我們將更具一次具體的操作來分析一下,常用指令的工作原理。

還是先上圖:


當我們通過git add命令將檔案新增到暫且區的時候,git add會做兩件事

    1,新增檔案到暫存區(.git/objects),儲存實際檔案的內容(修改後)

    2,index儲存檔案索引。

然後git commit將暫存區的檔案提交時會存在上面說過的情況,

    a. 用.git/index檔案儲存的目錄樹建立tree物件,

    b. 因此tree物件裡面自然就指向了已經被git add新增到.git/objects中的blob檔案。然後就可以直接提交。

    c. .git/refs/heads/master檔案儲存了這次commit的id。

這就是add,commit命令的工作原理。上述c選項儲存的id就是提供以後返回某個版本的根據。

下面我們學習常用的命令:

    git add 用於提交檔案從working directory到index area

    git commit用於提交檔案從stage area到history(版本庫)

    git commit -a用於提交檔案直接從working directory到history

    git reset用於撤銷檔案與git commit過程相反

    git checkout用於撤銷檔案與git add過程相反

    git status:可以列出當前目錄所有還沒有被git管理的檔案和被git管理且被修改但還未提交(git commit)的檔案。

    git diff命令:


git diff用於區別某一檔案在working directory與stage area的區別

    git diff --cached用於區別某一檔案在stage area與history的區別

    git diff HEAD用於區別某一檔案在working directory與history的區別

     git log命令顯示從最近到最遠的顯示日誌。      git reset  –hard HEAD^返回上個版本。      git reflog 獲得版本號。      git reset  –hard 版本號 :會退到此版本之後的版本。
     git checkout  — file 可以丟棄工作區的修改。 git commit -m "程式碼提交資訊"

相關推薦

GitGit指令學習與其原理探究

這篇文章記錄我學習Git的過程中遇到的問題及對於某些問題的看法,如有錯誤,還望不吝賜教! ps:這篇文章介紹本地庫,下篇將介紹與遠端庫的互動。 Git是什麼 & 為什麼要有Git?    

NLP基於機器學習角度談談CRF

作者:白寧超 2016年8月3日08:39:14 【摘要】:條件隨機場用於序列標註,資料分割等自然語言處理中,表現出很好的效果。在中文分詞、中文人名識別和歧義消解等任務中都有應用。本文源於筆者做語句識別序列標註過程中,對條件隨機場的瞭解,逐步研究基於自然語言處理方面的應用。成文主要源於自然語言處理

gulp前端自動化工具---gulp的使用------凡塵

app 一起 dex 前端自動化 指定 sass css 文件的 等待 什麽是gulp? 基於node的自動化構建工具 擴展:開發的時候分為2個節點一個是開發階段 另一個是部署階段 開發階段:源文件不會被壓縮

python爬蟲篇:python連線postgresql

本文記錄一下最近在做的事情,會把思考過程和解決問題的方案寫出來。當然,由於本人技術有限,所以可能並不是最好的方案,還請大家見諒!(黑貓白貓只要抓到老鼠,不就是好喵?~) 前言: 事情是這樣的,有一些文章,我要根據文章內容做分類,具體怎麼分我會單獨開一篇文章來講這件事情,這篇文章的重點不是分類

轉載微信小程式-開發入門

微信小程式已經火了一段時間了,之前一直也在關注,就這半年的發展來看,相對原生APP大部分公司還是不願意將主營業務放到微信平臺上,以免受制於騰訊,不過就小程式的應用場景(用完即走和二維碼分發等)還是很值得我們學習的,技術上面如果瞭解React的話,會發現他們在元件化上面有很多雷同之處。說白了,小程式就是基於微信

SpringMVC7.REST風格的CRUD實戰之前期工作

一、什麼是REST和CRUD? 1.有關REST 有關REST的解釋我已近在之前的SpringMVC系列文章提到過,如果有興趣的同學可以翻看《【SpringMVC】3.REST表現層狀態轉換》進行檢視。 2.有關CRUD In comp

caffe在windows平臺中安裝caffe:基礎安裝及簡單測試

基礎配置 本文中的配置:win10 + vs2015 + python2.5 + cmake3.12 + git2.15 + CUDA8.0 + cuDNN-8.0-5 在進行windows下的caffe安裝前,一定要把以上的這些軟體安裝好,並加入系統路徑中。

OpenStackmetadata在OpenStack中的使用

宣告: 本部落格歡迎轉發,但請保留原作者資訊! 新浪微博:@孔令賢HW; 內容系本人學習、研究和總結,如有雷同,實屬榮幸! 版本:Grizzly master分支 2013.6.17 部署:三節點(controller + network + compute) 網路

在Heroku上部署Django應用

title: 【譯】在Heroku上部署Django應用(1、配置) type: categories date: 2017-05-09 08:56:54 categories: Python tags: [Django, Heroku] H

25手把手教你響應式佈局

一:佈局方式有如下幾種: 1. 固定佈局:固定佈局以PX(畫素)作為單位的,在PC端,設計稿多少PX就寫多少PX,前幾年都是這種佈局,常見的是以960px或者1000px來設計的,但是這樣設計有如下缺點: 1.1.頁面很死板,在更大的螢幕上,頁面左右2邊留白。 1.2.不適

Docker基於例項專案的叢集部署安裝環境搭建

叢集 叢集具有三高特點: 高效能 高負載 高可用 現在的環境中,經常會用到叢集,如資料庫叢集。如,我們在主機上部署資料庫節點,形成叢集。 安裝環境與配置 在Docker中部署叢集,首先要安裝Linux環境,這裡我們使用VMware虛擬機

原創python3將圖片寫入mysql資料庫

01.環境準備使用的包:pymysqlpymysql下載地址:https://pypi.python.org/pypi/PyMySQL#downloads02.pymysql安裝:03.mysql的blob欄位解釋:BLOB型別的欄位用於儲存二進位制資料MySQL中,BLOB

G開源的分散式部署解決方案

做這個開源專案的意義是什麼?(口水自問自答,不喜可略過) 從功能上來說,請參考 預告篇,因自知當時預告篇沒有任何含金量,所以並沒有主動推送到首頁,而是私下的給一些人發的。 從個人角度上來說,我希望.net的環境會越來越好,就我自己的成長曲線是從mxdn開始自學、cxdn嘗試

SylixOSQT程式啟動載入流程簡介

QT應用程式啟動載入流程簡介 QWS(Qt Windows System)是QT自行開發的視窗系統,體系結構類似X Windows的C/S結構。QWS Server在物理裝置上顯示,QWS Client實現介面,兩者通過socket進行彼此的通訊。在很多嵌入式系統裡,QT

LDU新生訓練營杭電100題

A - ASCII碼排序  輸入三個字元後,按各字元的ASCII碼從小到大的順序輸出這三個字元。 Input輸入資料有多組,每組佔一行,有三個字元組成,之間無空格。 Output對於每組輸入資料,輸出一行,字元中間用一個空格分開。 Sample Input qwe

AndroidAndroidStudio編寫外掛超詳細教程

AndroidStudio外掛超詳細教程(一) 本教程從0開始,邊探索邊講解思路,保證詳細~~~寫的時候發現有點長,準備分2-3次寫完吧。 最近專案試了一下Android元件化架構,感覺坑還是蠻多的,首先ButterKnife就用不了了,

深入理解G1的GC日誌

本文翻譯自:https://www.redhat.com/en/blog/collecting-and-reading-g1-garbage-collector-logs-part-2?source=author&term=22991 這篇文章將深入研究G1的日誌和調優引數。為了在實際工作中對G1

Rust巨集:教程與示例

原文標題:Macros in Rust: A tutorial with examples 原文連結:https://blog.logrocket.com/macros-in-rust-a-tutorial-with-examples/ 公眾號: Rust 碎碎念 翻譯 by: Praying 在

Spring Boot幹貨系列:啟動原理解析

無法 time exp 記得 started 打印 ping 正文 exclude 前言 前面幾章我們見識了SpringBoot為我們做的自動配置,確實方便快捷,但是對於新手來說,如果不大懂SpringBoot內部啟動原理,以後難免會吃虧。所以這次博主就跟你們一起一步步揭開

python學習第十七篇:Python中的面向物件

1.什麼是類和類的物件? 類是一種資料結構,我們可以用它來定義物件,後者把資料值和行為特性融合在一起,類是現實世界的抽象的實體以程式設計形式出現。例項是這些物件的具體化。類是用來描述一類事物,類的物件指的是這一類事物的一個個體。例如:“人”就是一個類,而男人,女人,小孩等就是“人”這個類的例項物件;再比如“