一直忙於各種瑣碎的項目開題報告,編碼做PPT等瑣碎的工作,博客都好久沒更新,罪過罪過!
個人用github有一段時間了,當時學習的時候參照官方的教程,勉強能用,但是有些原理性的東西總是沒搞懂,所以很困惑,而網上關於git和github學習的中文文檔和學習資料都不是很多,所以打算寫一些自己使用github和git的一些心得,讓初學者少走彎路。
----------------------------------------------
基本概念:
版本庫(Repository)是版本控制系統用來存放所有歷史數據的地方,主要存放各個文件的當前狀態,歷史修改時間,誰做的修改,以及修改的原因。舉個簡單的例子,就好比銀行的保險箱,每次往里存錢,都會記錄誰,什么時間,存放多少錢,存入的原因等。對應的版本庫(Repository)主要存放代碼(文檔,數據,圖標等),並且每一次更新都要記錄誰,什么時間,提交了什么更新,以及更新的原因是什么。
git就是管理我們這個版本庫的管家,相當於銀行保險箱的管理人員。以前的版本控制入CVS,SVN等都是集中控制管理的,也就是有一個中央服務器,大家都把代碼提交到中心節點(入下圖),而git是分布式的版本控制工具,也就是說沒有中央服務器,每個節點的地位平等,有點P2P的味道,眾生平等,誰也別瞧不起誰 ! ^_^
-------------------------------------------------
Git的安裝與配置
ubuntu環境:
sudo apt-get build-dep git-core git-doc
make prefix=/usr/local all doc
sudo make install install-doc
檢查安裝是否成功:git --version
Windows環境:
github網站上又git的原生態安裝應用,可以直接“下一步下一步”安裝。下載鏈接:http://windows.github.com/
安裝完成后,桌面上會有Github和Github Shell的快捷方式出現。
配置
首先請注冊github網站,記住用戶名和密碼;
然后Ubuntu下請打開Terminal,Windows下請雙擊Git Shell;
配置用戶名和密碼:
git config --global user.name "Your name"
git config --global user.email "Your Email used to register"
檢查配置是否成功:git config --global --list 查看設置的用戶名和Email。
如果上面和下面要講的任何命令有疑問,使用命令git help <command>查看command的用法。
---------------------------------------------
添加與提交:Git基礎
好了配置好了,現在讓我用git來管理我們的代碼吧,日常是如何使用git呢,主要包括添加於提交,理解和使用分支,查詢git歷史記錄,與遠程版本庫寫作,管理本地版本庫等,在進入具體的內容之前,強烈建議花幾分鍾時間閱讀圖解git這篇文章,用圖像的方式解釋了git的工作原理,非常容易記住,再次強烈建議。
創建版本庫: mkdir test_git //新建目錄test_git
cd test_git //進入目錄
git init //初始化git,現在git會管理這個目錄中的所有內容了
增加文件: touch helloworld.txt //創建文件,在windows下直接到目錄新建文件即可
git add helloworld.txt //告訴git我要添加一個文件,但是git並沒有把你所添加的文件放入版本庫中,而是對內容進行hash后生成了一個編號
//相當於添加內容的身份證號,將該身份證號添加到版本庫index,即告訴git我有一個文件編號XXX的內容將要提交,
//但是並沒有真正提交到版本庫(如下圖),要想將文件真正放入版本庫需要commit
git commit -m "add helloworld.txt" //-m參數是提交留言,說明為什么要提交的更新做了什么事情,方便別人查看。
對下圖的說明:working directory是當前的工作目錄,而stage是暫存區也稱索引區存放工作目錄中那些你打算提交到版本庫的變更,git add只是將文件的索引提交的版本庫,而真正的內容並沒有進入版本庫,History就是版本庫,需要注意的是這是本地的版本庫,存在於本地的電腦中,相當於你電腦上一個你的私人錢財管理員。
兩個常用操作經常一塊使用
git add some-file
git commit -m "some changes to some-file"
查看當前代碼狀態:git status
會顯示
changes to be commited 表示將要提交但是尚未提交的修改(已經add但是尚未commit),也就是在stage區域已經有了,但是還沒有commit的內容
changed but not updated 表示已經修改但是還沒有添加到暫存區的內容(尚未add,當然尚未commit)
查看文件改動 git diff
git diff 比較working directory和stage的差別
git diff --cached 比較stage和history的差別
git diff HEAD 直接比較working directory 和history的區別
文件重命名: git mv
git mv helloworld.txt helloworld2.txt //將helloworld.txt重命名為helloworld2.txt
------------------------------------------------------
理解和使用分支
git可以使用多條分支,這樣就可以再不影響當前進度的情況下,用創建新的分支的方法來進行接下里的開發,何時使用分支是一門藝術,一般來說:
1. 試驗性修改(常用):測試新的算法或者為某個特別的模式重構部分代碼
2. 增加新功能(常用):為每個新功能的開發創建新的分支,完成該功能開發后,在將其合並到主分支上
3. Bug修改:修復代碼中的bug,可以創建新分支來對該bug進行修改,然后將修改合並到主分支上
創建新分支:git branch test //創建名為test的分支
切換分支:git checkout test //切換到test分支工作, 與上面的命令經常一起使用
查看分支:git branch //查看前版本庫(本地)的所有分支
合並分支:git checkout master //切換到“要合並到”的分支,常見的就是test分支合並到master分支,所以先切換到master分支
git merge test //合並test分支到master分支
注意: 在合並分支的時候有時候會出現沖突(conflict)的情況,創建的情況是master分支和test分支對同一文件的同一處代碼的內容不一樣(例如:master分支在hello.cpp中第三行寫入的是"hello", 而test分支在hello.cpp的第三行中寫入的是“world”),這樣使得git不知道如何是好,這時候就需要你手工修改代碼了,我難道要記住master和test在同一位置的內容?當然不用了,git會在git merge的反饋信息中說明,代碼在何部分存在沖突。
刪除分支: git branch -d test //刪除test分支
分支重命名:git branch -m test test2 //將test分支重命名為test2,這個命令不常用
--------------------------------------------------------------------------------------
查詢git歷史記錄
查詢所有的commit歷史:git log
查詢指定范圍的commit歷史: git log --since = "5 hours" //查看最近5小時的commit歷史記錄
git log --before = "5 hours" -2 //查看5小時之前最后2次的提交commit記錄
git log 18f822e..0bb3dfb //查看從18f822e(不包括18f822e)到0bb3dfb之間的提交記錄
git log 18f822e..HEAD //HEAD表示當前所在分支的最新版本,即HEAD指向當前所在分支的最后一次commit
git log HEAD^^^ //^表示父節點,HEAD^就表示HEAD的父節點,以此類推
git log HEAD~3 //~N 表示回溯N個節點,所以與上一個表述等價
查看版本之間的差異: git diff //查看working dir和stage(index)之間差異
git diff --cached //查看stage(index)和History(當前分支版本庫)之間的差異
git diff HEAD //查看working dir 和 History之間的差異
問責文件內容: git blame hello.cpp //查看所用向hello.cpp提交內容的人,方便問責到人,誰,什么時候,提交代號,提交內容,留言等都會顯示
增補提交: git commic -C HEAD -a --amend //用head上次提交的留言(-C表示comments),將這次的提交追加到上一次提交上,不會創建新的提交代號
-----------------------------------------------------------------------------------
與遠程版本庫協作
github就是提交遠程版本庫服務的網站,所以我們這里的遠程版本庫為方便起見用github代替,上面我們得操作都是和本地的git交互,相當於是和本地的git小助手交互,如何將這些在本地的代碼和github上的版本庫連接起來:將本地的代碼推送到github上,將github上的代碼檢出(checkout)到本地?
git支持三種協議:SSH協議格式: usrname@github.com/registername/helloworld.git //常用於將本地版本庫推送到github上的版本庫
git協議格式: git://github.com/registername/helloworld.git //常用於從github版本庫拖入本地版本庫
HTTP/HTTPS協議格式: http://github.com/registername/helloworld.git
克隆github上的Spoon-Knife版本庫到本地: git clone git://github.com/octocat/Spoon-Knife.git
版本庫同步: git fetch //取來(fetch)遠程版本庫到本地,但是並不與本地分支合並
git pull //拖入(pull)遠程版本庫,與本地分支合並,相當於 git fetch + git merge
推送本地代碼到遠程版本庫: git remote add origin https://github.com/registername/reponame.git //為遠程版本庫reponame取別名origin
git push origin master // 將本地master分支推入github上的origin
--------------------------------------------------------------
其他:
還有一些不是很常用的操作簡單的列在下面,如果用到這些命令,可以參看git doc或者本文參考文獻中所列的內容,不一一贅述。
翻轉提交: git revert
復位: git reset
分支變基: git rebase
標簽: git tag
git子模塊: git submodule
導出版本庫: git archive
二分查找: git bisect
-------------------------------------------------------------------------------------------
參考文獻:
[1]Travis Swicegood(董越,付昭偉譯). 版本控制之道——使用git. 電子工業出版社. 2010.
[2]圖解git: http://marklodato.github.io/visual-git-guide/index-zh-cn.html
[3]github官方tutorial:https://help.github.com/