目前開發的新項目使用的版本控制工具基本用的都是Git,老項目用的仍是Svn,網上Git資源也不少,多而雜。我整理了一份關於Git的學習資料,但願能幫助到正在學習Git的同窗。jquery
1、 Git 命令初識git
在正式介紹Git命令以前,先介紹一下Git 的基本命令和操做,對Git命令有一個整體的認識github
示例:從Git 版本庫的初始化,一般有兩種方式:web
1)git clone:這是一種較爲簡單的初始化方式,當你已經有一個遠程的Git版本庫,只須要在本地克隆一份服務器
例如:git clone git://github.com/someone/some_project.git some_project app
上面的命令就是將'git://github.com/someone/some_project.git'這個URL地址的遠程版本庫,徹底克隆到本地some_project目錄下webapp
2)git init 和 git remote:這種方式稍微複雜一些,當你本地建立了一個工做目錄,你能夠進入這個目錄,使用'git init'命令進行初始化;Git之後就會對該目錄下的文件進行版本控制,這時候若是你須要將它放到遠程服務器上,能夠在遠程服務器上建立一個目錄,並把可訪問的URL記錄下來,此時你就能夠利用'git remote add'命令來增長一個遠程服務器端,分佈式
例如:git remote add origin git://github.com/someone/another_project.gitsvn
上面的命令就會增長URL地址爲'git: //github.com/someone/another_project.git',名稱爲origin的遠程服務器,之後提交代碼的時候只須要使用 origin別名便可工具
2、 Git 經常使用命令
1) 遠程倉庫相關命令
檢出倉庫: $ git clone git://github.com/jquery/jquery.git
查看遠程倉庫:$ git remote -v
添加遠程倉庫:$ git remote add [name] [url]
刪除遠程倉庫:$ git remote rm [name]
修改遠程倉庫:$ git remote set-url --push [name] [newUrl]
拉取遠程倉庫:$ git pull [remoteName] [localBranchName]
推送遠程倉庫:$ git push [remoteName] [localBranchName]
*若是想把本地的某個分支test提交到遠程倉庫,並做爲遠程倉庫的master分支,或者做爲另一個名叫test的分支,以下:
$git push origin test:master // 提交本地test分支做爲遠程的master分支
$git push origin test:test // 提交本地test分支做爲遠程的test分支
2)分支(branch)操做相關命令
查看本地分支:$ git branch
查看遠程分支:$ git branch -r
建立本地分支:$ git branch [name] ----注意新分支建立後不會自動切換爲當前分支
切換分支:$ git checkout [name]
建立新分支並當即切換到新分支:$ git checkout -b [name]
刪除分支:$ git branch -d [name] ---- -d選項只能刪除已經參與了合併的分支,對於未有合併的分支是沒法刪除的。若是想強制刪除一個分支,可使用-D選項
合併分支:$ git merge [name] ----將名稱爲[name]的分支與當前分支合併
建立遠程分支(本地分支push到遠程):$ git push origin [name]
刪除遠程分支:$ git push origin :heads/[name] 或 $ gitpush origin :[name]
*建立空的分支:(執行命令以前記得先提交你當前分支的修改,不然會被強制刪乾淨沒得後悔)
$git symbolic-ref HEAD refs/heads/[name]
$rm .git/index
$git clean -fdx
3)版本(tag)操做相關命令
查看版本:$ git tag
建立版本:$ git tag [name]
刪除版本:$ git tag -d [name]
查看遠程版本:$ git tag -r
建立遠程版本(本地版本push到遠程):$ git push origin [name]
刪除遠程版本:$ git push origin :refs/tags/[name]
合併遠程倉庫的tag到本地:$ git pull origin --tags
上傳本地tag到遠程倉庫:$ git push origin --tags
建立帶註釋的tag:$ git tag -a [name] -m 'yourMessage'
4) 子模塊(submodule)相關操做命令
添加子模塊:$ git submodule add [url] [path]
如:$git submodule add git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs
初始化子模塊:$ git submodule init ----只在首次檢出倉庫時運行一次就行
更新子模塊:$ git submodule update ----每次更新或切換分支後都須要運行一下
刪除子模塊:(分4步走哦)
1) $ git rm --cached [path]
2) 編輯「.gitmodules」文件,將子模塊的相關配置節點刪除掉
3) 編輯「 .git/config」文件,將子模塊的相關配置節點刪除掉
4) 手動刪除子模塊殘留的目錄
5)忽略一些文件、文件夾不提交
在倉庫根目錄下建立名稱爲「.gitignore」的文件,寫入不須要的文件夾名或文件,每一個元素佔一行便可,如
target
bin
*.db
3、 Git 命令詳解
如今咱們有了本地和遠程的版本庫,讓咱們來試着用用Git的基本命令:
git pull:從其餘的版本庫(既能夠是遠程的也能夠是本地的)將代碼更新到本地,例如:'git pull origin master'就是將origin這個版本庫的代碼更新到本地的master主枝,該功能相似於SVN的update
git add:是將當前更改或者新增的文件加入到Git的索引中,加入到Git的索引中就表示記入了版本歷史中,這也是提交以前所須要執行的一步,例如'git add app/model/user.rb'就會增長app/model/user.rb文件到Git的索引中,該功能相似於SVN的add
git rm:從當前的工做空間中和索引中刪除文件,例如'git rm app/model/user.rb',該功能相似於SVN的rm、del
git commit:提交當前工做空間的修改內容,相似於SVN的commit命令,例如'git commit -m story #3, add user model',提交的時候必須用-m來輸入一條提交信息,該功能相似於SVN的commit
git push:將本地commit的代碼更新到遠程版本庫中,例如'git push origin'就會將本地的代碼更新到名爲orgin的遠程版本庫中
git log:查看歷史日誌,該功能相似於SVN的log
git revert:還原一個版本的修改,必須提供一個具體的Git版本號,例如'git revert bbaf6fb5060b4875b18ff9ff637ce118256d6f20',Git的版本號都是生成的一個哈希值
上面的命令幾乎都是每一個版本控制工具所公有的,下面就開始嘗試一下Git獨有的一些命令:
git branch:對分支的增、刪、查等操做,例如'git branch new_branch'會從當前的工做版本建立一個叫作new_branch的新分支,'git branch -D new_branch'就會強制刪除叫作new_branch的分支,'git branch'就會列出本地全部的分支
git checkout:Git的checkout有兩個做用,其一是在不一樣的branch之間進行切換,例如'git checkout new_branch'就會切換到new_branch的分支上去;另外一個功能是還原代碼的做用,例如'git checkout app/model/user.rb'就會將user.rb文件從上一個已提交的版本中更新回來,未提交的內容所有會回滾
git rebase:用下面兩幅圖解釋會比較清楚一些,rebase命令執行後,其實是將分支點從C移到了G,這樣分支也就具備了從C到G的功能
git reset:將當前的工做目錄徹底回滾到指定的版本號,假設以下圖,咱們有A-G五次提交的版本,其中C的版本號是 bbaf6fb5060b4875b18ff9ff637ce118256d6f20,咱們執行了'git reset bbaf6fb5060b4875b18ff9ff637ce118256d6f20'那麼結果就只剩下了A-C三個提交的版本
git stash:將當前未提交的工做存入Git工做棧中,時機成熟的時候再應用回來,這裏暫時提一下這個命令的用法,後面在技巧篇會重點講解
git config:利用這個命令能夠新增、更改Git的各類設置,例如'git config branch.master.remote origin'就將master的遠程版本庫設置爲別名叫作origin版本庫,後面在技巧篇會利用這個命令個性化設置你的Git,爲你打造獨一無二的 Git
git tag:能夠將某個具體的版本打上一個標籤,這樣你就不須要記憶複雜的版本號哈希值了,例如你可使用'git tag revert_version bbaf6fb5060b4875b18ff9ff637ce118256d6f20'來標記這個被你還原的版本,那麼之後你想查看該版本時,就可使用 revert_version標籤名,而不是哈希值了
Git 之因此可以提供方便的本地分支等特性,是與它的文件存儲機制有關的。Git存儲版本控制信息時使用它本身定義的一套文件系統存儲機制,在代碼根目錄下有一個.git文件夾,會有以下這樣的目錄結構:
有幾個比較重要的文件和目錄須要解釋一下:HEAD文件存放根節點的信息,其實目錄結構就表示一個樹型結構,Git採用這種樹形結構來存儲版本信息,那麼HEAD就表示根;refs目錄存儲了你在當前版本控制目錄下的各類不一樣引用(引用指的是你本地和遠程所用到的各個樹分支的信息),它有heads、remotes、stash、tags四個子目錄,分別存儲對不一樣的根、遠程版本庫、Git棧和標籤的四種引用,你能夠經過命令'git show-ref'更清晰地查看引用信息;logs目錄根據不一樣的引用存儲了日誌信息。所以,Git只須要代碼根目錄下的這一個.git目錄就能夠記錄完整的版本控制信息,而不是像SVN那樣根目錄和子目錄下都有.svn目錄。那麼下面就來看一下Git與SVN的區別吧。
4、 Git 與SVN 比較
SVN(Subversion)是當前使用最多的版本控制工具。與它相比較,Git 最大的優點在於兩點:易於本地增長分支和分佈式的特性。
下面兩幅圖能夠形象的展現Git與SVN的不一樣之處:
------------
1)本地增長分支
圖中Git本地和服務器端結構都很靈活,全部版本都存儲在一個目錄中,你只須要進行分支的切換便可達到在某個分支工做的效果
而SVN則徹底不一樣,若是你須要在本地試驗一些本身的代碼,只能本地維護多個不一樣的拷貝,每一個拷貝對應一個SVN服務器地址
舉一個實際的例子:
使用SVN做爲版本控制工具,當正在試圖加強一個模塊,工做作到一半,因爲會改變原模塊的行爲致使代碼服務器上許多測試的失敗,因此並無提交代碼。
這時候假如如今有一個很緊急的Bug須要處理, 必須在兩個小時內完成。我只好將本地的全部修改diff,並輸出成爲一個patch文件,而後回滾有關當前任務的全部代碼,再開始修改Bug的任務,等到修改好後,在將patch應用回來。前先後後要完成多個繁瑣的步驟,這還不計中間代碼發生衝突所要進行的工做量。
但是若是使用Git, 咱們只須要開一個分支或者轉回到主分支上,就能夠隨時開始Bug修改的任務,完成以後,只要切換到原來的分支就能夠優雅的繼續之前的任務。只要你願意,每個新的任務均可以開一個分支,完成後,再將它合併到主分支上,輕鬆而優雅。
2)分佈式提交
Git 能夠本地提交代碼,因此在上面的圖中,Git有利於將一個大任務分解,進行本地的屢次提交
而SVN只能在本地進行大量的一次性更改,致使未來合併到主幹上形成巨大的風險
3)日誌查看
Git 的代碼日誌是在本地的,能夠隨時查看
SVN的日誌在服務器上的,每次查看日誌須要先從服務器上下載下來
例如:代碼服務器在美國,當每次查看幾年前所作的工做時,日誌下載可能須要十分鐘,這不能不說是一個痛苦。可是若是遷移到Git上,利用Git日誌在本地的特性,查看某個具體任務的全部代碼歷史,每次只須要幾秒鐘,大大方便了工做,提升了效率。
固然分佈式並非說用了Git就不須要一個代碼中心服務器,若是你工做在一個團隊裏,仍是須要一個服務器來保存全部的代碼的。
5、總結
上面簡單介紹了Git 的基本概念、一些經常使用命令和原理,你們也能夠嘗試動手,在Google Code 或 GitHub 上建立一個本身的開源項目