Git版本控制系統之基本使用
最早是通過接觸著名的開源社區Github了解到Git的,但一直沒有系統學習過。這次下定決心從頭到尾系統的學一學,也將學習過程記錄於此,供大家批駁。本篇文章先從以下幾個方面簡單了解一下Git:
- Git的簡介以及Git與GitHub的關係
- Git的下載和初始化信息配置
- Git的基礎指令及其含義
一、Git的簡介以及Git和GitHub的關係
首先Git是由Linux 的締造者Linus Torvalds 創造的,當初這位大牛本著開源的精神將Linux 開源,那麼就需要對成千上萬的貢獻者的代碼進行管理,起初所有的代碼都以郵件的形式發給Linus ,然後由他來手動整合。但是隨著Linux越做越大,代碼量也越來越大,已經無法完全由人來管理了。於是Linus選擇使用商業系統BitKeeper來管理這些代碼,BitKeeper是一個成熟的版本控制系統,直到2005年兩家合作結束。於是Linus大神花了兩周時間用C寫出來了一個版本控制系統,就是現在已經無敵的Git。(牛就是這個樣子的!),想要了解更多Git歷史,可自行查閱資料,此處簡單截取部分時間點以激發對git的興趣。
版本控制系統就是一類用於管理我們項目進度點的系統,對於每次的修改給予記錄,一旦出現錯誤可以立即回滾。想想我們平時對於文件的修改,一旦修改之後,對於之前的內容將會丟失,就是你想要回到過去某個未修改時的狀態,是無法做到的。而我們用版本控制系統追蹤我們的項目文件,每次的修改都是記錄在案的,可以隨時回到過去。這裡我們不討論集中式版本控制系統和分散式版本控制系統的區別,我們只告訴你Git的分散式的,等學完之後你就會明白分散式的各種優點。
相比於Git,我們可能更加熟悉的是GitHub。它是一個開源社區,是一個平台。很多優秀的項目都在上面開源,供全世界的程序員學習和完善。例如:apache/tomcat,eclipse/jetty,jquery/jquery等。我們說Git可以記錄我們對工作文件的每次修改,以便於我們可以快速恢復,但是為了多人協同工作,我們就需要共享同一個項目源碼,所以一般就會將項目源碼放在一個伺服器上,每個開發者從伺服器上下載當前最新的項目並進行工作,工作結束之後向伺服器推送自己所做的更改,這樣每個人無時無刻都在開發(修改)著項目的各個功能,當然位於伺服器上的項目也會無時無刻的記錄每個人的每次提交修改記錄。(出問題了可以迅速找到罪魁禍首)。而GitHub作為一個開源社區平台,它可以充當那個伺服器。但是由於它是開源的,所以一般公司內部項目也是不建議利用GitHub作為公共伺服器來進行開發的。一般會自建伺服器配置成Git伺服器,在內網中使用。
二、Git的下載和初始化信息配置
三大平台中,我從我自己使用的的windows平台介紹Git的安裝,至於Linux和MacOS上的安裝大家可自行查閱資料。windows平台下對Git的安裝是簡單的,前往https://git-for-windows.github.io下載msysgit,然後一鍵式安裝即可。msysgit集成的是Git和Cygwin,Cygwin是一種在windows中模擬Linux/Unix環境的工具,因為Git是需要用到Linux/Unix的一些工具的,所以有人集成了兩者以使得在windows平台下也能使用Git。下面我們簡單說一下對Git的初始化信息的配置。
首先在安裝完成之後,滑鼠右鍵會增加了Git Bash here選項,那就是Git的命令行模式,我們點擊即可展示命令行窗口。我們首先要做的就是告訴Git,本機的身份。因為以後我們在多人協作的時候,每次Git在提交的時候會署名當前提交者,而Git是如何得知提交者的信息的?就是在初始化信息的時候我們告訴它的。
$ git config --global user.name "Your name"
$ git config --global user.email "Your email"
一般我們配置以上兩條信息即可,至於其他的信息配置,例如:默認編輯器等 ,大家在需要用到的時候可以查詢資料簡單配置一下即可。到此為止,有關Git的簡單介紹基本介紹完成,下面我們看看在日常項目中最長使用的幾個Git命令及其含義。
三、基本Git指令
這一小節是本篇文章的核心,主要涉及到初始化倉庫,添加追蹤文件,暫存文件,提交本地資料庫,恢復到以前狀態等。這些內容基本涵蓋了日常項目中最常見的操作,但是想要更加靈活的掌握Git以發揮其在項目管理中的巨大作用,這些是僅僅不夠的。下面我們看第一個指令,初始化倉庫。
1、git init
這是一條用於初始化倉庫的指令,執行它會在當前目錄下創建.git文件夾,該文件夾就是用於管理當前目錄中所有文件的改動的,至於裡面都有哪些內容,後續文章會介紹,請記住,裡面的內容不可隨意更改,否則會破壞git結構導致無法跟蹤工作區文件。例如,我在電腦 F盤中創建一個文件夾single,在git命令行中cd到該目錄,然後執行git init ,結果如下:
打開當前目錄,看到一個文件夾.git,這就是init命令執行之後創建的結果,它就是整個版本控制的核心。至於裡面的內容結構我們在後續的文章中介紹。
從此,在f:/single目錄下為工作區,在這個目錄下的文件都是可以被git追蹤的。
2、git add filename
我們說初始化之後,工作區中的文件是可以被追蹤的,但是只有告訴git哪些文件需要追蹤,它才會顯式的去追蹤該文件,否則git永遠會在你提交的時候告訴你工作區還用哪些文件處於Untracked狀態。而我們add命令就是用來顯式告訴git哪些文件從此時開始追蹤。例如我們在上述的工作區中創建一個文件test.txt,然後使用以下命令就可以追蹤該文件的任意改動情況:
git add test.txt
當然該命令可以多次使用,以添加對多個文件的追蹤。有時候,我們為了方便會使用以下命令添加所有文件的追蹤:
git add .
當然這個add指令的第一個作用就是為未被追蹤的文件添加追蹤,第二個作用是對工作區某個文件的修改進行保存。因為git是根據你保存後的狀態進行提交的,也就是說git的提交並不是提交的工作區的當前狀態,他提交的是你每次保存後的所有文件狀態,例如:我們創建了一個文件test,並使用add命令對其進行追蹤了,下面我們為該文件輸入一些內容(對文件進行了修改,隨意輸入一些即可)。然後我們提交一下當前狀態:
你看,git告訴我們,文件test已經被修改,但是你並沒有進行保存,所有此次no changes added to commit,沒有東西可提交的。而當我們add保存該文件修改之後:
這次,git告訴我們本次提交已經成功添加到master分支上了,相比於上次commit狀態有一個文件的修改。
2、git commit
在介紹commit提交之前,我們先簡單了解一下git的大致結構。深入理解它的結構會在後續文章中學習,此處是為了更加方便的理解幾個命令作用對象的不同。首先,git有三塊區塊,工作區,暫存區,分支。
工作區就是我們能看見的,所謂的「當前目錄」。該目錄下有很多的文件,這些文件就是我們版本控制所要追蹤的內容。暫存區也稱為stage或者index,它保存的是工作區的一次次修改情況,如上我們使用add命令保存某個文件的修改,記錄下該文件當前快照。然後我們用commit命令向分支上提交,位於分支上的每個點都是一次commit留下的。當然我們在回滾的時候也是根據需要回滾到指定的點上。
有人會疑問,為什麼要有暫存區呢,直接工作區對接分支不就好了嗎?其實這樣做具有更高的效率,一般來說,分支上的每次commit都代表著一次重要功能的完成,不能說我們每寫一點代碼就commit一下,這樣會導致太多的commit,未來想要迅速找到想要回滾的點不易。所以git使用暫存區保存每一次小小的修改,等所有修改完成時候,commit命令將會把暫存的修改更新到分支上完成一次commit。
下面理解我們的commit命令就比較容易了,該命令會將暫存區的所有內容提交到分支上形成一次commit。一般我們只有在完成某一個完整的模塊或者功能之後才進行一次commit提交,較小的修改則一般先在暫存區保存。
3、git clone
當我們遇到比較好的開源項目並想要參與其中的時候,我們就需要獲取到別人項目的所有代碼,這時候我們的clone命令就可以發揮作用了。我們在遠程伺服器上上創建一個庫,新建一個文件index.txt,然後我們利用clone命令完成拷貝遠程倉庫的動作。
然後我們打開目錄,f://1testgit下即可看到一個倉庫test被完整的拷貝下來,test目錄裡面就是我們完整項目加上版本控制文件。這裡需要說明一點,我們可以在命令後面指定拷貝下來的倉庫名稱,如果沒有顯式指定則默認和遠程的一樣。例如:
git clone https://github.com/Programer-yang/test.git myResptory
這樣本地倉庫的名稱不再和遠程的一樣了,被顯式修改成myResptory了。簡而言之,想要使用clone命令,首先需要知道將要被clone的倉庫的地址,可以是基於http協議的,也可以是基於git協議的,然後我們需要進入到指定目錄,選擇性的指定被克隆下來的倉庫在本地的名稱。
4、git status
該命令會和我們接下來要介紹的diff命令有點混淆,但是如果掌握他們的本質,區別也是顯而易見的。首先我們要知道,status命令是用來查看當前工作區狀態的,也就是說它會把當前工作區的所有文件狀態和我們本地分支上最近一次的提交進行比較,並列出所有做出的修改條目。例如,我們在當前目錄下創建一個文件test並鍵入簡單內容,commit到master分支(此時工作區和暫存區以及本地分支都是乾淨的,一樣的),而我們執行status命令也會得到以下輸出:
它告訴我們工作區和分支上內容完全一樣,並沒有多餘的修改。但是當我們修改index文件內容之後執行status命令,得到以下結果:
輸出結果很顯然的告訴我們,和本地分支的最近一次提交相比,工作區對index這個文件做了修改,並且還沒有向暫存區保存。這是該命令額外的功能,如果是紅色字體說明你不僅修改了工作區還沒有向暫存區保存,如果是綠色的字體則說明你修改了工作區並向暫存區保存了。看:
以上我們簡單介紹了status這個命令的基本使用,下面介紹diff命令。
5、git diff
diff命令也是用來查看當前狀態的,只是它不同於status,它比較的是工作區和暫存區之間的區別。例如,我們對於乾淨的工作區,修改index文件,然後執行diff命令。輸出如下:
從輸出結果我們可以看出來,diff命令為我們列出了當前工作區和暫存區文件狀態的詳細區別。例如上圖告訴我們,暫存區文件(紅色字體代表暫存區文件的所有內容)index中只有一行信息 hello world,而當前工作區(綠色字體代表工作區文件內容)index中有兩行信息。如果你是多個文件發生了更改,那麼該命令會列出所有被修改文件前後所有內容供程序員查看。
當然我們以上介紹的diff命令是無參的,所以它比較的是工作區和暫存區之間的差異,我們也可以使用參數來指定工作區,暫存區,本地分支兩兩之間的比較。例如:
git diff --cached:比較的是暫存區和本地分支的差異
git difff HEAD:比較的是工作區和本地分支的差異
由此看來,對於git中三個不同區的狀態之間差異的查看我們都可以通過diff命令來完成。顯而易見,diff命令要比status命令輸出內容更加詳細,但是status命令也有其自己的使用場景。
6、git log
這是一個幫助我們查看歷史提交信息的命令,例如:
我們可以看到,輸出結果主要是歷次commit對應的id以及提交者的信息時間,還有提交的描述信息。當然最重要的還是這個由40位十六進位數字組成的SHA-1值,這樣每次提交都對應一個唯一的id,也方便我們回退歷史版本。下面簡單介紹一個該命令的一些選項參數,使用帶參數或者選項的log命令可以為我們提供更加直觀的信息,快速的獲取到我們需要的內容。
直接使用git log命令將會輸出歷史所有的提交信息,有時我們只需要查看進幾次的提交信息,就可以使用-<n>選項來顯式指定輸出的commit次數。例如:
我們也可以使用-pretty=xxx參數來指定輸出的提交信息的簡易程度,有以下一些參數值可供選擇,oneline,short,full 和 fuller。例如:
其他參數的輸出情況大家可以自行嘗試實踐。
還有一個選項是-p,我們往往對於某次提交都是會附帶描述信息的,但是有時候這些描述信息不是很準確,而我們又想確定此次提交做出了那些修改,這時可以使用-p選項來輸出此次提交的修改內容。例如:
輸出結果告訴我們,該命令會列出當前提交對其中文件所有的更改情況。和我們的diff命令輸出一樣。
7、git reset
我們使用git最重要的一個目的就是,隨時可以回退歷史版本,而我們的reset命令就是完成這個工作的。例如:我們在git工作區創建一個文件index然後做一次提交(描述信息one),然後我們為index文件鍵入一些內容,再一次提交(描述信息two),這樣我們構建了兩次提交,最新一次的提交為two,我們可以利用reset回退到one。
我們看到,在回退之前最新的兩次commit分別是two和one,但當我們回退到上一個版本的時候,原最新的commit被丟棄,head指針指向one。這裡需要說明一點的是,head^符號表示的上一個commit的id,我們除了可以這麼回退以外,還可以使用某個commit的唯一標識來回退,例如:
如圖所示,我們成功的回退到描述為 」the forth commit」的版本,很顯然,我們是使用commit的唯一標識來回退的,所以針對任意的一個commit,我們都可以根據他的標識直接回退。但是這裡需要注意的是,reset命令的執行將會直接導致工作區,暫存區,本地分支完全一致,也就是工作樹是乾淨的,所以回退前要慎重檢查是否有內容尚未保存,否則將會導致全部丟失。
至此,本篇文章簡單介紹了git的幾個常用的指令以及他們的簡單應用,當然git有很多命令,我們只是列舉了幾個常用的,至於其他的一些命令部分會出現在後續文章中,我們還將介紹git很核心的內容:分支,這也是git能夠多人協作的一個關鍵點。系列文章參考了一些書籍和網路教程,總結不到之處,望大家指出。
※設計模式之單例模式
※RabbitMQ入門-Routing直連模式
※netty 默認Channel管道線初始化
※NET中解決KafKa多線程發送多主題的問題
※設計模式解密(18)- 原型模式
TAG:科技優家 |
※零基礎打造全屋智能控制系統 篇十二:EraClean Fresh 新風系統的自動化控制
※谷歌Android P操作系統基本功能曝光
※對話AI系統基本架構
※英國宇航系統公司BAE利用HoloLens改善員工培訓
※英國宇航系統公司 BAE 利用 HoloLens 改善員工培訓
※Avro系統及其應用
※安全大躍進:MotoGP強制使用氣囊系統
※學習版本控制系統:從git到github
※Eternal code架構分散式版本文件系統二:系統功能及架構
※iPhone怎麼降回老版本系統呢?教您如何下降iPhone系統版本
※汪方煒實驗室在EMBO Reports等雜誌連續發文系統闡述調控染色體穩定性的新機制
※SMT貼片機基本系統組成
※Uber與NASA簽署合作協議 以建立空中交通管制系統
※俄羅斯央行或將在本土銀行結算系統SPFS上使用以太坊區塊鏈
※user版本的系統上如何備份已安裝的APK
※ID Chain本周發布產品原型 建立高效身份認證系統
※用 Python 管理系統進程
※首個 SteamVR 輸入系統發布,兼容所有主流手柄控制器
※首個SteamVR輸入系統發布,兼容所有主流手柄控制器
※微軟首推自主版本Linux系統