git使用小結
很多人可能和我一樣,起初對git是一無所知的。我也是因為一次偶然的機會接觸到git,並被它強大的功能所蟄伏。git其實就是一種版本控制工具,就像svn一樣,但是git是分布式的。我不想給git打廣告,我們直入正題——git能幫我們做什么?
1)源碼版本控制。平常寫一寫demo程序可能和git打不上交道,但是當我們把程序寫到10000行以上,一般一個人開發的話要持續一個多月。期間程序作者可能會保存了N多份程序不同時期的拷貝,一來是為了備份代碼,二者是作者添加新的程序功能,一旦對新功能不滿意時可以方便撤銷。git能幫助我們保存每次提交源碼更改時的歷史記錄,並在需要的時候幫助我們撤銷回滾。
2)協同軟件開發。如果說一個人把程序“寫大”后需要git幫助控制版本,那么當有N個人同時開發一個軟件的時候,git的功能就更加必要了。多人協同開發有很多工作模式,一般會在服務器端保存最新的源碼版本。git幫助開發人員們同步修改,合並更新等。這里就涉及到了github,www.github.com就是保存開源項目的公共服務器,任何開發者都可以從該網站上下載自己項目的最新版本,修改后提交。因此github的命名也很形象,每個開發者就像客戶端連接到公共的git服務器hub(集線器)上。
一言以蔽之,如果平常個人開發軟件的話,git可以幫助我們方便的維護程序的版本;如果是多人共同開發的話,git能幫助我們協同工作。弄清這些,我們就開始Ubuntu上的git的使用。如果你從未用過git,這些入門級的介紹或許對你來說很有幫助,如果你是git專家,也希望你不吝指出文中的錯誤,共同進步!
1.git的安裝和配置
首先從源上直接下載安裝git。
$sudo apt-get install git-core -y
安裝完畢后,需要配置git,告訴它“你是誰?”——包括你的姓名和Email,這些信息會在以后你的每次提交中出現。
$git config --global user.name “Your Name”
$git config --global user.email “your_email@email.com”
這些配置信息會保存在用戶目錄下。
$cat ~/.gitconfig
[user]
name = Your Name
email = your_email@email.com
到這里,就可以正常地在本地使用git了,但是我們還不能從github上下載和上傳數據。因為github的倉庫(Respository)一般都是開源的,所有人都可以自由的下載,但這不意味着所有人都能上傳。如果要獲得對github倉庫的更新的權限,必須首先注冊自己的公鑰。
Ubuntu的用戶RSA公鑰和密鑰默認放在用戶目錄下,如果沒有的話使用命令創建。
$cd ~/.ssh || ssh-keygen -t rsa -C your_email@example.com
密碼是可選的,最終會在~/.ssh下創建密鑰文件id_rsa和公鑰文件id_rsa.pub。
登錄github后打開鏈接https://github.com/settings/ssh設置公鑰。點擊“Add SSH key”添加公鑰。
首先拷貝剛生成的公鑰的二進制數據,使用xclip命令。如果系統未安裝xclip,首先安裝該軟件。
$sudo apt-get install xclip -y
$xclip < ~/.ssh/id_rsa.pub
給公鑰命名,粘貼公鑰內容,添加成功。
最后確認公鑰是否正常。
$ssh -T git@github.com
當看到“Hi YourGithubID! You've successfully authenticated…”的信息時,大功告成!
2.倉庫的創建和初始化
即使是個人獨立開發軟件使用git維護程序版本,使用github也會帶來很大的便捷。只要有網絡,從github上下載最新的源碼,隨時隨地都可以修改更新。要達到這個目的,需要在github上創建一個Respository(網址:https://github.com/new),輸入倉庫名字(如work)創建即可。此時新創建的倉庫是個空的倉庫,等待我們本地上傳新的數據。
首先我們需要創建一個工作目錄,在這個目錄我們開發源代碼, 然后新建一個自讀文件README.md。
$cd
$mkdir work
$cd work
$touch README.md
接着初始化該git倉庫。
$git init
該命令在工作目錄下生成了一個隱藏的文件.git,用於管理工作目錄下所有文件的改變。
因為新建了文件README.md,如果要git對它的版本維護,則需要將它添加到git的索引中(git add . 命令可以添加所有的工作目錄下的文件)。
$git add README.md
因為對git的倉庫做了改動,便可以產生一次提交。
$git commit –am “first commit”
commit僅僅是把更改保存在了本地的git,下面就需要將我們所做的改動更新到服務器上,首先設置服務器git的地址。
$git remote add origin git@github:YourGithubID/work.git
origin是服務器git的別名,如果要上傳我們的數據更新,則使用push命令。
$git push origin master
該命令將本地的git主分支master提交到遠程服務器origin主分支master上。成功后打開地址https://github.com/YourGithubID/work可以看到新建的README.md文件已經存在了。
3.提交的更新和撤銷
git的版本控制功能帶給我們最大的好處是隨時記錄我們對源碼的更改,並在我們需要的時候撤銷已經做過的操作,不過這些便利是建立在每一次提交(commit)上的。每次使用commit命令后,git都會在log中增加一條歷史記錄。
使用status和log命令可以查看當前工作目錄的狀態和提交日志。
$git status
$git log
例如上一節提交的first commit記錄。
commit 903fd****************************f322e05
Author: Your Name <your_email@email.com>
Date: Mon Apr 22 12:02:44 2013 +0800
first commit
除了新加文件需要使用git add命令再提交之外,其他情況的更新直接使用commit –am提交即可,所有的改變都會反映在本地的日志中。
我們也可以建立標簽標記某次重要的提交。
$git tag INIT
如果我們在開發的過程突然發現某次之后的代碼修改需要全部撤銷,這時就是git大顯身手的時候了。git reset命令可以讓我們回到任何一個已經提交的歷史狀態!
$git reset --soft 903fd
該命令將工作的狀態撤銷到first commit之后(903fd為該commit的hash id的開始數個位),而且該命令不會直接修改工作目錄下的源文件。我們也可以使用標簽。
$git reset --soft INIT
如果此時使用commit提交更新的話,則可以把從first commit之后的全部修改合並為一次提交,這樣有減少log記錄的好處。
如果你確信要徹底撤銷工作目錄下的文件的更改,可以這樣做。
$git reset --hard 903fd
這樣就徹底回到了最開始的狀態,除非你完全覺得有必要,否則盡量不要這樣做。
如果使用git僅僅是為了達到偶爾的撤銷的目的,這些功能貌似就夠用了,但是git提供的便利性不僅如此。
4.版本的分支和合並
相比於其他版本控制工具,git更提倡使用分支!所謂分支是相對於服務端的主干版本而言的,從git項目建立時就默認處於主分支master上。如果在開發過程中開發人員有多個思維選擇實現,或者有多個分工同步進行,那么建立多個分支分別同時開發。到分支結束后再決定是選擇放棄哪些分支,或者將分支合並到主分支上等。
總的來說,git的分支模型為開發者提供一種額外的解決問題的思路,而不需要擔心源代碼的修改帶來的副作用。分支上的開發者完全“生存”在另一個時空維度里,就像物理學中的平行空間一樣,他們完全自由的在分支上更改源代碼,甚至最后結果不滿意時放棄這個分支的所有工作!分支模型幫助多人開發進行工作的協同,在每個人看來,開發模式一般是按照“下載最新版本——修改更新——合並提交”這樣的流程進行。這種模式對於獨立的開發者也很方便,開發者隨時都可以下載最新的源碼版本,隨地的修改自己的代碼,然后提交更新。我們按照這個流程看一下git的分支模型的使用。
首先是下載最新的源碼版本。
$git clone https://github.com/YourGithubID/work.git
如果之前已經下載過該項目,則使用。
$git pull origin
直接從origin下載最新版本源碼,並和本地主分支master合並。相當於命令組合。
$git fetch origin
$git merge origin/master
如果我們修改的源碼並非自己github上的倉庫,則需要將別人的倉庫fork一份到自己的github上在按照上述方式下載,更新。最后push request到原作者的github上,如果原作者接受你的push request,則完成對他人代碼的修改。
將最新版本的倉庫下載到本地后,就可以修改源碼了。一般我們不會直接對master分支更新,而是先建立一個臨時的工作分支——如br1。
$git branch br1
$git checkout br1
使用checkout切換到分支br1上,此后所有的操作都是在br1上進行,不會對master有任何影響。最終我們完成了br1上的工作,然后我們需要將br1合並到master主分支上。
$git checkout master
$git merge br1
合並后的主分支記錄了我們在br1上做的所有修改,最后我們需要將新的master主分支push到服務器上,完成當前階段的工作!
5.總結
以上我們涉獵了git的基本使用方法,很多高級的用法無法在這里一一展示,本文也是期望帶領初學者快速了解git的使用,並為自己的代碼開發和版本控制提供便利。如果你在為開發軟件不厭其煩的備份和多人源碼的分工合作頭疼不已時,不妨試一下git,或許有種“撥開雲霧見月明”的感覺!