本篇正式開始介紹Git的基礎操做與原理,看完本篇,你應該知道如何使用Git進行一次基礎的版本控制,包括:Git倉庫的生成和獲取,添加和忽略版本控制對象;暫存,查看,緩存,變動;查看和查找提交歷史;格式化歷史記錄輸出;刪除和移動Git倉庫內對象。javascript
使用Git的第一步是要獲取一個Git倉庫,咱們使用Git的操做對象都是存放在Git倉庫裏,獲取Git倉庫的方式有兩種:java
若咱們須要使用一個項目或目錄生成一個Git倉庫,只須要經過命令行進入該目錄,執行以下Git指令:webpack
git init複製代碼
此操做將在此目錄生成一個.git子目錄,該目錄包含整個倉庫結構,即倉庫的全部文件;同時會檢出(checkout)一個默認工做分支,一般名爲master。git
此時,咱們只是初始化生成了一個Git倉庫,還未添加須要進行版本控制的對象--文件或目錄。github
不少時候,咱們須要從遠程服務器獲取一個已存在的Git倉庫,咱們只須要使用以下指令:web
git clone https://github.com/codingplayboy/javascript_notes複製代碼
git clone
後面跟着的url就是已存在的Git倉庫地址,咱們須要知道的是Git克隆是對服務器上倉庫的一次近乎完整的數據拷貝,當前倉庫項目的全部文件及其各版本歷史都會被獲取。緩存
執行如上指令後,會在當前目錄建立一個javascript_notes目錄並在javascript_notes中初始化一個.git子目錄,拉取倉庫的全部數據,而後根據倉庫(或項目)的最新版本檢出(check out)一個工做分支,一般該分支默認名稱爲master。服務器
咱們克隆一個Git倉庫時,其默認名仍是倉庫名,可是也支持咱們自定義本地別名:url
git clone https://github.com/codingplayboy/javascript_notes js_notes複製代碼
執行如上指令,會克隆一個倉庫,並導入到當前目錄下的js_notes目錄。spa
Git倉庫Url支持的協議有不少,最多見的是https:// 和git@;還有使用SSH傳輸協議的,
形如git://或者user@server:path/xxx/repository.git。
在上節,咱們已經知道如何獲取一個Git倉庫,可是到目前爲止也僅僅是存在一個倉庫,咱們進行版本控制的對象(文件或目錄)並無添加進倉庫。
相關指令:git status
當咱們獲取一個倉庫,如克隆一個遠端倉庫後,在倉庫目錄執行上面指令,如圖所示:
on branch master
告訴咱們當前咱們處在名爲master的分支;up-to-date with 'origin/master'
,說明目前分支與遠程倉庫的master分支保持同步最新版本;working directory clean
,說明目前倉庫中沒有新加或修改過的對象(文件或目錄)。在當前工做目錄的文件或目錄,可能出於兩種狀態:
已標記(tracked)
所謂已標記文件或目錄,即那些在Git最新快照裏存在的對象,多是未修改(unmodified),已修改(modified)或暫存(staged)的文件或目錄。
未標記(untracked)
未標記對象,即除去已標記對象外,全部對象,好比在工做目錄下可是未包含在最新快照裏而且不在暫存區(staging area)。
能夠想象一下,當第一次克隆一個遠程倉庫後,倉庫下的全部文件都應該是處於已標記(tracked)可是未修改的狀態。
添加版本控制對象的指令是git add
,好比,咱們可使用以下指令添加一個README.txt文件,固然咱們首先須要在倉庫目錄下,建立該文件(任意方式建立),查看狀態:
如上圖,顯示README.txt文件爲Untracked file,而且提示:use git add
to track;
而後使用git add
指令後:
git add README.txt複製代碼
再次執行git status
指令:
如上,出現:Changes to be committed,說明該文件已被標記(tracked)且被暫存,咱們能夠進行提交了。
固然該指令還能夠對目錄使用:
git add test/複製代碼
如上指令,將添加該test目錄及其內全部文件或子目錄。
最後,也許咱們但願一次添加全部變動,而不是一個一個添加,以下指令,能夠實現:
git add .複製代碼
咱們還須要關注git add
指令,不僅是能添加版本控制對象,還有如下功能:
git add指令,更貼切的做用應該是添加新內容(文件/目錄/變動)到下一次提交,即將新內容加入最新快照,等待提交;
關於後兩點功能,後文有詳細介紹。
有時候,咱們並不但願對倉庫內全部對象(文件或目錄)進行管理,
某些開發依賴或本地調試使用文件和目錄,咱們不須要在團隊間共享,這些文件應該被Git忽略,咱們只須要建立一個.gitignore文件,在此文件中列出但願被忽略的文件或目錄,如:
.gitignore文件語法主要以下:
在添加README.txt文件後,咱們能夠對其進行修改,如在該文件加入一行文字http://blog.codingplayboy.com
,而後執行git status指令
,結果以下:
發現,除了以前新添加文件的記錄,又多了一條記錄:Changes not staged for commit
,代表已標記對象發生變動可是未被暫存,其下面第一第二行是輔助信息,第三行告訴咱們,README.txt已經修改(modified);
隨後咱們可使用git add
指令暫存這次變動,此時,再執行git status
指令,能夠看到:
全部變動都已暫存,等待下一次提交。
上文已經指出,使用git status
能夠查看當前工做目錄完整的狀態,同時,git還支持使用參數指明查看簡短狀態信息:
git status -s
or
git status --short複製代碼
以下,其信息比git status
簡潔明瞭:
前文的git status
能夠查看當前工做目錄的狀態信息,包括當前分支,變動文件等,但都屬於文件層次的信息;
有時咱們但願知道:
git status
顯然是不能告訴咱們,由於這是屬於git diff
的使命,如,在README.txt文件中內容添加‘/’:
,如上圖,git diff
以行爲單位,告訴咱們全部變動文件哪些行發生變動(增長或刪除)。
git diff
比較當前工做目錄和暫存區的內容,而後展現哪些文件內容發生變動而且還沒有暫存;
同時,其支持額外參數--staged
(或--cached),該參數指定時,將輸出上次提交內容與暫存區內容比較後的的變動,
簡言之,git diff
輸出未暫存的變動,git diff --staged
輸出已暫存待提交的變動。
在使用git add .
暫存變動後,使用git diff
指令是沒用的,而使用git diff --staged
指令,輸出以下:
全部的變動,最終都須要提交,才能在本地持久化報存,在將全部變動暫存(git add)後,咱們就能夠進行提交了,相關指令就是:
git commit複製代碼
在輸入如上指令後,將進入Git commit信息編輯狀態:
咱們能夠編輯本次提交的備註信息,其中的默認備註信息都以#開頭,代表提交時會被忽略。
git commit指令告訴Git持久化記錄(提交)咱們暫存區(staging area)中的快照,任何未被暫存的變動,不會被添加進暫存區的快照,仍然保留在當前工做目錄,咱們能夠隨後提交。
除了使用默認的git commit指令,咱們還能夠添加-v
參數,在提交信息中顯示變動內容,以下:
如上圖,和以前的比較,除了基本的提示,還有文件變動內容提示,能夠避免某些誤提交。
固然,Git還支持咱們使用-m
參數,指明咱們在使用git commit
指令時直接填寫提交備註信息:
咱們知道對於發生變動的對象,咱們須要先使用git add
,暫存變動,再使用git commit
提交變動;
可是還有一種能夠不使用git add
指令的方式,能夠提交變動,就是給git commit
指令添加-a
參數:
git commit -a複製代碼
可是須要注意的是,該參數,只能直接提交工做目錄中已標記的對象(文件或目錄)的變動,對於未標記,如新添加的對象,是無效的。
本節要介紹的是如何查看以前的提交歷史及信息,你應該知道的git log
指令,
默認地,不帶參數時,執行git log
指令,輸出的是當前倉庫按逆序排序(最近提交在最前)的提交記錄:
如上圖,每一個提交記錄包含其SHA-1校驗和,提交者用戶名,提交日期,提交備註信息。
git log
指令支持指定許多參數,以過濾輸出不一樣提交記錄,下文展開介紹。
Git支持咱們指定數量參數,限定該次查看提交記錄數量,如git log -2
,以後輸出最近的兩條提交記錄。
Git支持咱們格式化輸出的提交記錄信息,使用--pretty參數,其值主要有如下幾個:
git log --pretty=format:"%h - %an, %ar : %s"複製代碼
git log --stat
輸出以下:
除了輸出基礎提交信息,後面還輸出了本次提交的簡要變動信息:變動了多少文件,及每一個文件變動的行數,並在最後輸出總結數據。
相對於git log --stat
輸出簡要提交變動信息,咱們能夠指定-p參數:git log -p
,輸出提交變動的詳細內容,如:
參數 | 說明 |
---|---|
-p | 顯示詳細提交變動 |
--stat | 顯示簡要提交變動 |
--shortstat | 在--stat參數輸出基礎上只輸出修改,新增或刪除的行 |
--name-only | 顯示提交時發生變動的文件名 |
--name-status | 顯示提交時發生變動的文件名,並顯示變動類型(刪除,新增,或修改) |
--abbrev-commit | 只顯示提交記錄SHA-1校驗和的前幾個字符 |
--relative-date | 顯示簡要提交日期(如, 「2 weeks ago」) |
--graph | 顯示分支提交歷史的ASCII圖 |
--pretty | 支持預約義輸出格式,詳細說明見上文 |
Git支持咱們在輸出歷史記錄時,添加多種過濾條件,最簡單的好比-<num>
參數條件,指定輸出最近的若干條提交記錄,還有諸如提交時間,提交做者等條件。
--since/--after: git log --since=2.weeks
輸出兩週內的提交記錄,參數值還能夠形如"2016-01-15","2 years 1 day 10 minutes ago"
--until/--before: git log --until=2016-01-15
--grep: git log --grep=README
能夠指定關鍵字,只有提交信息中存在關鍵字纔會輸出
--author: 過濾輸出指定提交做者的記錄
-S: git -log -Swebpack
輸出提交內容(代碼或文件或目錄)包含指定字符串的記錄
不少時候,咱們也會須要從Git倉庫中刪除某些對象,rm
就是刪除文件或目錄的指令,可是須要特別強調的是,該指令只是將某對象從當前工做目錄刪除,如:
使用rm
後,當前狀態是"Changes not staged for commit:"這次變動未被暫存和提交。
若你須要將某對象從已標記文件或暫存區刪除,則須要使用git rm
指令,以下:
使用git rm
後,變動會被暫存。
當咱們發生某次變動,且將其添加到暫存區(index索引),咱們只使用git rm
指令是不行的:
咱們必須加上-f
參數,指明強制刪除。
有時候,咱們在某次變動添加了某文件(甚至可能已經添加到暫存區),可是暫時不須要提交,又不想直接刪除它,即只在工做目錄存在,而不將其放入暫存區,只須要添加--cached
參數,如修改README.txt同時,新增了test.txt文件,而且暫存了變動,以後提交時咱們不但願這次提交test.txt,但又不但願刪除它,則在提交前使用git rm --cached test.txt
:
一般,咱們也許須要移動或重命名某文件或目錄,Git有mv
指令,還要一個更方便的指令git mv
,如:
git mv a.txt b.txt複製代碼
另外一方面,重命名或移動某文件或目錄,這兩個操做對於Git來講是沒有太大區別的,好比上面的重命名文件操做等效於:
mv a.txt b.txt
git rm a.txt
git add b.txt複製代碼
咱們能夠看到git mv
指令是在mv
指令操做的基礎上暫存這次操做的變動,而mv
只是一個重命名或移動指令,不涉及版本控制流程。
到此,Git的基本使用,已經介紹完成,不過,本篇講解的基礎操做,都是在計算機本地進行的版本控制,並無同步到服務器,那麼下一篇的主題就出來了:Git如何與遠程服務器進行協同工做。