Git是一個分佈式版本控制系統(Distributed Version Control System,簡稱 DVCS)。 git
對於大多數人而言,或許對svn更爲熟悉,svn屬於集中化的版本控制系統( Centralized Version Control Systems,簡稱 CVCS ),在CVCS中會有一個對版本進行集中管理的服務器,協同工做的人都經過客戶端鏈接到該服務器,檢出最新文件或提交更新。CVCS在協同開發中有兩個比較主要的缺點: github
對於這兩個主要問題,DVCS都有比較好的解決方案: vim
首先,DVCS能夠方便地在本地進行版本管理,就如同在你本地有一個版本管理服務器同樣。你能夠選擇在合適的時候將本地版本推送到統一的版本管理服務器。 windows
其次,DVCS每次都會提取整個代碼倉庫的完整鏡像,即至關於對整個代碼倉庫進行了一次備份。這樣即便版本管理服務器出現意外,也能夠輕鬆地採用任 一本地倉庫恢復。結合本地版本管理功能,在遠程版本管理服務器出現故障的狀況下,你依然能夠放心的進行工做,當遠程服務器恢復工做時,再提交你的本地版 本。 服務器
Git只關心文件數據的總體是否發生變化,而大多數其餘系統則關心文件內容的具體差別,並記錄這些差別。git則是更像一個微型文件系統,保存更新文件的快照,併爲之建立一個索引。 編輯器
CVS,Subversion,Perforce,Bazaar 等等)每次記錄有哪些文件做了更新,以及都更新了哪些行的什麼內容 分佈式
Git 保存每次更新時的文件快照 svn
你須要安裝一個Git客戶端來開始使用Git,你可使用msysgit做爲你windows上的git客戶端,msysgit包含一個命令行工具Git Bash和一個gui工具Git GUI。對於習慣TortoiseSVN的同窗來講,或許Git GUI太簡陋了,不要緊,安裝完msysgit後你依然能夠安裝TortoiseGit,實現svn到git的平滑過渡。TortoiseGit不單獨介紹,本文主要介紹經過Git Bash使用git進行版本管理,在你熟悉Git Bash後相信你對TortoiseGit也會有更深刻的掌握。 工具
安裝好msysgit後,運行Git Bash,在開始全部工做以前咱們須要先作一些配置,如今咱們只需作一些基礎配置,詳細的配置後面再講: fetch
# 用戶名 $ git config --global user.name 'omiga' # email $ git config --global user.email 'omiga@sample.com' # 文本編輯器,默認vim $ git config --global core.editor vim # 差別分析工具 $ git config --global merge.tool vimdiff
由於每次提交git都會記錄committer信息,完成上述配置後,經過cd命令進入到任意文件目錄,而後使用git init命名便可初始化一個git版本庫。
$ cd /d/ohmygod $ git init
這樣ohmygod目錄下的任何改動都處於git版本庫的管理下了。在該目錄下建立一個README文件,再運行git status命令,將會看到git提示README文件處於爲「Untracked files」列表中,並給出了「(use git add <file>… to include in what will be committed)」的建議。此時可使用git add README命名將README文件加入到暫存區。
$ git add README
此時再執行git status,會看到「new file: README」的提示信息。繼續執行git commit README -m 「create README」
$ git commit README -m "create README"
這樣README文件就被提交到了本地版本庫,完成了一個文件從建立到提交的完整過程:
處於git跟蹤下的文件具備三種狀態:
工做目錄,暫存區域,以及本地倉庫
$ git help <verb> $ git <verb> --help $ man git-<verb> # windows下不可用
如查看init命令的幫助信息:
$ git help init $ git init --help
git init命名將在當前目錄新建一個版本庫
從你的git版本服務器上clone版本庫到本地開展工做,或者從github上clone一個開源項目的代碼庫,這時候你就須要git clone命令:
# git clone url [newname] # 克隆到當前目錄 $ git clone https://github.com/octocat/Spoon-Knife.git # 在當前目錄新建目錄knife 將Spoon-Knife克隆到knife目錄 $ git clone https://github.com/octocat/Spoon-Knife.git knife
不論是git init仍是git clone都會在你的本地建立一個包含.git目錄的git版本庫
經過git init命名或git clone命令均可以在本地建立一個git版本庫,版本庫建立成功後即可以在本地進行暫存文件,提交更新等操做了。
在git中可使用git status查看文件的更改信息,但這個信息比較概要。若是想獲取更爲詳細的更改信息,可使用git diff命令:
# 查看未暫存文件的變化(與最近一次的暫存/提交比較) $ git diff # 查看已暫存文件的變化(與最近一次提交比較) $ git diff --cached # 查看與版本庫中任一版本的變化 $ git diff 2bd094a # 查看任意兩個版本間的變化 $ git diff 2bd094a 78ab3d1 # 具體到某個文件 $ git diff 2bd094a 78ab3d1 README
關於diff再補充一點內容:若是暫存區/已暫存區都不存在任何未提交的文件,那麼diff將對最新版本中與上一版本進行比較。
清楚文件更改信息以後,即可使用git commit對暫存區文件進行提交操做。
若是想提交未暫存文件,可使用git commit -a命令:
$ git commit -a -m 'all changes'
可使用git rm <file>:
$ git rm myfile
固然其實你也能夠直接在文件目錄中手動刪除,這二者的區別在於:使用git rm命令至關於手動刪除後使用add命令將更改添加到暫存區域。
$ git reset HEAD <file>
若是想撤銷某(幾)次提交,回退到某個版本,可使用git reset [--mode] <commit>:
$ git reset [--(mixed|soft|hard)] cec8506
git不會跟蹤在文件目錄中手動的文件重命名操做,若是手動重命名了某個文件,git會認爲這是一次delete-create操做。可是,你可使用git mv命令完成重命名(文件目錄亦使用該命令):
$ git mv oldfile newfile
這是git中使用平率很是高的一個操做,git中查看提交歷史的功能也很是強大,提供各類篩選和輸出格式定製功能。
最簡單的,運行git log命令,你將看到一個詳細的提交日誌:
git-log
# 固然也能夠只查看某個版本 $ git log fd0a1b2
信息內容都很好理解,重點說說第一行commit後這個40個字符的字符串,這是該次提交的對應的SHA-1值,在git中,會對提交 (commit)、文件(blob)、目錄(tree)、標籤(tag)生成一個惟一的SHA-1值,git就是基於此來得知文件或目錄的改動,由於這四 類對象計算獲得的SHA-1值都是惟一的,同時你也能夠直接使用SHA-1值來指代相應的對象。好比:
$ git show bdd3996 # 查看某個版本下具體某個文件 $ git show bdd3996 README
git log還有不少命令選項來定製歷史記錄
選項 | 說明 |
---|---|
-(n) | 僅顯示最近的 n 條提交 |
–since,–after | 僅顯示指定時間以後的提交 |
–until,–before | 僅顯示指定時間以前的提交 |
–author | 僅顯示指定做者相關的提交 |
–committer | 僅顯示指定提交者相關的提交 |
–reverse | 按時間倒序顯示 |
-p | 按補丁格式顯示每一個更新之間的差別 |
–stat | 顯示每次更新的文件修改統計信息 |
–shortstat | 只顯示 –stat 中最後的行數修改添加移除統計 |
–name-only | 僅在提交信息後顯示已修改的文件清單 |
–name-status | 顯示新增、修改、刪除的文件清單 |
–abbrev-commit | 僅顯示 SHA-1 的前幾個字符,而非全部的 40 個字符 |
–relative-date | 使用較短的相對時間顯示(好比,「2 weeks ago」) |
–graph | 顯示 ASCII 圖形表示的分支合併歷史 |
–pretty | 使用其餘格式顯示歷史提交信息。可用的選項包括 oneline,short,full,fuller 和 format(後跟指定格式) |
能夠經過對上述選項進行組合定製出更爲個性化的日誌信息,好比:
$ git log --committer 'god' --shortstat --pretty=oneline
該命令將以單行模式顯示由god提交的統計信息。
$ git log -p -5
顯示最近5次提交的,並顯示其差別
除此以外,git log –graph也很好玩。我git log –graph了一下git項目的日誌,很是壯觀。
單獨介紹下–pretty=format選項。使用format和佔位符能夠定製出更爲個性化的顯示格式。
選項 | 說明 |
---|---|
%H | 提交對象(commit)的完整哈希字串 |
%h | 提交對象的簡短哈希字串 |
%T | 樹對象(tree)的完整哈希字串 |
%t | 樹對象的簡短哈希字串 |
%P | 父對象(parent)的完整哈希字串 |
%p | 父對象的簡短哈希字串 |
%an | 做者(author)的名字 |
%ae | 做者的電子郵件地址 |
%ad | 做者修訂日期(能夠用 -date= 選項定製格式) |
%ar | 做者修訂日期,按多久之前的方式顯示 |
%cn | 提交者(committer)的名字 |
%ce | 提交者的電子郵件地址 |
%cd | 提交日期 |
%cr | 提交日期,按多久之前的方式顯示 |
%s | 提交說明 |
$ git log --pretty=format:'%h by %ce at %cd'
該命令將以「簡短SHA-1 by 提交者 at 提交時間」的格式顯示日誌
gitk命名會啓用圖形化的日誌界面
前面已經介紹過使用git reset來撤銷暫存區的文件,以及回退整個版本。但若是隻想恢復某個文件,則須要使用checkout — <file>命名:
$ git checkout -- README
它只有在修改文件尚未暫存的狀況下,使用最近的提交版本進行恢復。若是文件已經暫存,則須要先使用git reset HEAD <file>從暫存區刪除文件,再使用該命令。
git commit –amend命名容許你對最後一次提交信息從新編輯。至關於從新進行一次提交,覆蓋掉上一次提交。
儘管git在本地也能夠方便地進行版本管理,可是多人協做,或者是多地操做時,總須要使用到遠程倉庫來進行版本維護。在前面建立版本庫的內容中其實 使用clone命名就已是在與遠程版本庫進行交互了,clone遠程庫後便會自動建立一個名爲origin的遠程庫,可使用git remote -v命名查看遠程庫的詳細信息。
$ git remote -v
而在實際工做中,咱們可能須要頻繁地與某一個或幾個遠程庫交互,那麼更好的辦法是使用一個別名把遠程庫保存起來。git添加遠程庫的方法很簡單:
# $ git remote add <name> <remote-url> $ git remote add pro-git https://github.com/progit/progit.git
這樣便將https://github.com/progit/progit.git這個遠程git版本庫添加並命名爲pro-git,後續你只須要使用pro-git即可以指代progit的遠程庫。
當你完成本地工做,並將改動提交到本地版本庫後,你即可以使用push將本地提交推送到遠程倉庫了:
# $ git push <remote-name> <branch-name> $ git push pro-git master
默認會使用origin和master做爲遠程倉庫和本地分支的名稱。
固然你也能夠將本地分支推送到遠程倉庫做爲一個分支:
# $ git push <remote-name> <local-branch>:<remote-branch> $ git push pro-git master:git-branch
當<local-branch>爲空時,會嘗試刪除遠程分支:
$ git push pro-git :git-branch
上述命令會刪除遠程倉庫中的」git-branch」分支
fetch與pull命令都會將一個遠程倉庫抓取到本地,不一樣的是fetch僅僅是將遠程倉庫抓取到本地,以供進行後續操做;pull除了將遠程倉庫抓取到本地,還會試圖與本地當前分支進行合併。
他們與clone不一樣的是,clone會copy一份版本倉庫到本地,若是本地已存在版本倉庫,則會被clone後的倉庫替換。而fetch和 pull都須要在已有本地倉庫的條件下操做,不能做爲建立本地倉庫的方法,便是必須先git init或是git clone後才能使用fetch和pull。
$ git remote -d <remote-name>
準確一點說,這只是刪除遠程倉庫在本地的別名,而不是真正刪除遠程服務器上的git倉庫。
$ git remote rename oldname newname
雖然git中不少命名都簡單易記,但每次都手動輸入這些命令確實會浪費很多時間,並且也有那麼些命令選項很是冗長,這時就可使用別名來簡化命令的輸入了。
別名屬於配置項內容,因此須要使用git config命令,如能夠爲「checkout -b」命令配置別名「cob」
$ git config --global alias.cob 'checkout -b'
爲「commit -a -m」配置別名「cam」:
$ git config --global alias.cam 'commit -a -m'
爲單行圖像化顯示log命令「log –pretty=oneline –graph」配置別名「lol」:
$ git config --global alias.lol 'log --pretty=oneline --graph'
至此,git基礎篇結束。你已經可使用git進行平常的代碼管理維護,下一篇進階篇將着重介紹分支,git配置,git原理以及github等內容。