*** last update: 2010.11.30 ***
*** refer to: http://zx-1986.blogspot.com/2010/08/git-manual.html ***
Git(http://git-scm.com/)是一套分散式的版本管理系統。
類(lèi)似 SVN(Subversion)或 CVS(Concurrent Version System)對程式碼或文件進(jìn)行管理。
Git 的概念很單純,想像一下:
你的書(shū)櫃裡有許多書(shū),偶而有新書(shū)進(jìn)來(lái),有舊書(shū)捐出去。
有時(shí)候你還會(huì )在某些書(shū)上作筆記、寫(xiě)心得、畫(huà)畫(huà)。
你在書(shū)櫃的側邊貼上一張「大大的白紙」,對書(shū)櫃裡的所有變動(dòng)作紀錄。
紀錄新書(shū)擺入的時(shí)間,擺放的位置,甚至後面加個(gè)註記:『購於網(wǎng)路拍賣(mài)』;
紀錄舊書(shū)清除的時(shí)間,原本的位置,加個(gè)註記:『oh,好捨不得』;
紀錄某書(shū)寫(xiě)入筆記的時(shí)間,什麼樣的筆記,心得或隨手塗鴉;
紀錄……
當然很少人會(huì )這麼費工書(shū)寫(xiě)自己書(shū)櫃的變遷歷史。
但這張書(shū)櫃側邊貼著(zhù)的「大大白紙」就類(lèi)似於 Git,而且 Git 會(huì )做得更鉅細靡遺。
當你對一個(gè)資料夾啟用 Git 進(jìn)行追蹤管理與控制時(shí)(其實(shí)就是 Git 初始化),
Git 程式會(huì )在該資料夾底下新增一個(gè)名為「.git」的隱藏資料夾。
「.git」類(lèi)似於前面提到那張「大大的白紙」,裡面紀錄了檔案的變化史。
「.git」會(huì )對該資料夾內所有的檔案與其底層的所有資料夾進(jìn)行紀錄追蹤。
不過(guò),Git 並不會(huì )主動(dòng)、自動(dòng)紀錄,必須靠使用者操作。使用者類(lèi)似於史官的角色。
當然,Git 的背後的運作方式更為聰明而且複雜。
Git 的功能不僅僅如此。
團隊合作時(shí),同樣一個(gè)文件,在你手上跟在他人手上,可能有不一樣的變化史。
當你的檔案要與他人的合併時(shí),內容有出入的地方,Git 會(huì )協(xié)助進(jìn)行處理。
(例如開(kāi)發(fā)同一個(gè)程式,你寫(xiě)的 code 可能被他人改動(dòng)到,或反之。)
Git 還有其他許多功能與應用,請慢慢挖掘。
*
建議先執行以下指令,將系統預設編輯器選擇為 Vim:
sudo update-alternatives --config editor |
*
Ubuntu 底下安裝 Git 非常簡(jiǎn)單,只要在終端機執行:
sudo apt-get install git-core git-doc |
[ 註:亦可以使用 tarball 進(jìn)行安裝。]
每個(gè)使用者帳號都會(huì )有它自己的 Git 設定檔,通常是:
~/.gitconfig 例如我的設定檔內容是:
設定完成後可以開(kāi)一個(gè)新的資料夾進(jìn)行練習。
設計上 Git 不會(huì )把空的資料夾加入控管。
建議可以在空的資料夾底下建立一個(gè)隱藏檔,例如:.gitignore
執行以下指令產(chǎn)生 .gitignore:
.gitignore 可以寫(xiě)入「不希望被 Git 控管的檔案」,例如:
執行以下指令初始化 Git(資料夾內會(huì )多出一個(gè)名為 .git 的隱藏資料夾):
之後只要每次修改或新增檔案後,執行以下兩個(gè)指令,Git 就會(huì )做一次紀錄:
git add . git commit -a -m '關(guān)於此次修改的描述訊息' |
好了,您已經(jīng)開(kāi)始在使用 Git 啦!
*
執行:
git 會(huì )顯示常用的 Git 指令與參數,例如:
在整個(gè) Git 指令後面加上 -h 參數,能夠查詢(xún)該指令可以附加哪些參數,例如:
要查詢(xún)完整的指令手冊,可以執行:
*
【關(guān)於 Git Repository】
一個(gè)被 Git 所追蹤管理的專(zhuān)案,稱(chēng)為一個(gè) Git Repository(倉儲)。
Git Repository 裡預設的 Trunk(主幹)稱(chēng)為「master」,
Git Repository 裡其他的 Branch(分支)則由使用者命名。
Git 是一個(gè)分散式的版本控制系統,不同於 SVN 傳統的 Server/Client 架構。
Git 不需要像 SVN 必須有一個(gè) Repository Server 作為主要的儲存倉儲。
Git 只要安裝好,預設就可以使用 ssh 互相進(jìn)行 Repository 傳輸了。
當使用 git clone 指令從遠端複製一個(gè) Git Repository 到本地端電腦上時(shí),
遠端的 Git Repository 通常稱(chēng)為「origin」;
本地端的 Git Repository 則沒(méi)有特殊的名稱(chēng)(或許可稱(chēng)為「Local Trunk」?)。
*
一般應用情形是這樣:
假設遠端的電腦叫做 Remote;本地端的電腦叫做 Local。
Remote 上面有一個(gè) Git Repository 資料夾叫做 remote_repository。
要將 remote_repository 整個(gè)複製到 Local 上並命名為 local_repository,在 Local 上執行:
Local$ git clone 「Remote 使用者帳號@Remote 位址」:「remote_repository 在 Remote 上的路徑」 local_repository |
複製完成(git clone)後,Local 與 Remote 已經(jīng)可以分開(kāi)獨立工作了。
Git 不必拘泥於一定要把修改過(guò)的檔案更新存回當初取得檔案的地方。
Remote 可以在 remote_repository 裡發(fā)展它的檔案;
Local 可以在 local_repository 裡發(fā)展它的檔案。
等到哪天 Remote 突然想取得並合併 Local 發(fā)展的檔案,可以在 Remote 上執行:
Remote$ git pull 「Local 使用者帳號@Local 位址」:「local_repository 在 Local 上的路徑」 |
當然,如果 Local 想取得與合併其他人發(fā)展的檔案,可以在 Local 上執行:
Local$ git pull 「使用者帳號@位址」:「路徑」 |
#特別說(shuō)明
git pull – Fetch from and merge with another repository or a local branch
git fetch – Download objects and refs from another repository
官方文件對這兩個(gè)指令是這般解釋的,看起來(lái)似乎是「git pull」會(huì )多進(jìn)行一項合併的動(dòng)作。
簡(jiǎn)單說(shuō),「git pull」其實(shí)等於先執行了「git fetch」,然後再自動(dòng)執行「git merge」。
有人建議少用「git pull」,多用「git fetch」然後「git merge」,請見(jiàn) Reference 05。
透過(guò)底下這張圖可以稍微了解一下 Local 與 Remote 間的關(guān)係:
上圖中間黃色部份的「Staging Area」工作階段是一個(gè)緩衝地帶,
它讓只有被 add 過(guò)的東西,才可以被 commit。
可以直接觀(guān)察下圖了解其間的關(guān)係:
*
【SVN 式的往日時(shí)光】
之前,我在不同的電腦上修改程式,有可能是研究室的電腦、宿舍的電腦或筆記型電腦。
所以我在研究室的一臺主機上架了 SVN 伺服器,程式主要版本儲存在 SVN 伺服器上。
每當在不同的電腦進(jìn)行程式編輯時(shí),會(huì )先從 SVN 伺服器上抓最新版本的程式下來(lái)。
編輯告一段落後,再把修改過(guò)的程式上傳回 SVN 伺服器。
簡(jiǎn)單而言,程式集中在一臺 SVN 伺服器上,要編輯時(shí)從上面更新下來(lái),編輯完再更新回去。
像我這種從 SVN 轉換到 Git 的使用者,還很習慣於從前 SVN 那種模式:
1] 使用 svn checkout 從 SVN 伺服器將整個(gè) Repository 複製到本機端。
2] 本機端對 Repository 的內容進(jìn)行編輯、修改、新增、刪除等等。
3] 使用 svn update 檢查 SVN 伺服器有沒(méi)有其他更新與自己修改的內容有衝突。
4] 解決內容衝突的情況。
5] 使用 svn commit 將自己本機端的所有修改上傳到 SVN 伺服器。
怎麼用 Git 做到類(lèi)似 SVN 那樣的情形?
有個(gè)簡(jiǎn)單的方法。
首先,選定一臺要當 Repository Server 的機器,假設叫 Server。
在 Server 開(kāi)一個(gè)空的資料夾,假設叫 origin,並切換到該資料夾下。
在空資料夾底下執行:
該資料夾底下會(huì )產(chǎn)生以下檔案與資料夾:
本地端的電腦,假設叫 Local。
Local 上一個(gè)叫 local_project 的資料夾要上傳到 Server 進(jìn)行統一管理。
切換到該資料夾底下,執行:
Local$ git commit -a -m 'initialization' Local$ git remote add origin 「Server 使用者帳號@Server 位址」:「Server 上 origin 資料夾的路徑」 |
Local$ git push origin master |
從 Server 上的 origin 複製 local_project 的內容: |
Other$ git clone 「Server 使用者帳號@Server 位址」:「Server 上 origin 資料夾的路徑」 「自訂的資料夾名稱(chēng)」 |
其他電腦要將其修改的內容傳回 Server,可以使用:
Other$ git push origin master |
*
【Git Repository Hosting】
Git Repository 還可以使用 http 等其他方式傳輸、瀏覽、管理。
- gitosis
*
Git 常用指令:
git diff v1.0:檔案名稱(chēng) v2.0:檔案名稱(chēng) |
git show v1.0:檔案名稱(chēng) |
git branch 分支名稱(chēng) v1.0 |
git branch -d 分支名稱(chēng) |
git merge 某個(gè)分支名稱(chēng) |
git checkout -- 檔案名稱(chēng) |
git reset --hard 某個(gè)版本的 hash 編號 |
Reference:
01. http://zh-tw.whygitisbetterthanx.com
02. http://www.qweruiop.org/nchcrails/posts/49
03. http://walkingice.twbbs.org/blog/archives/504
04. http://ihower.tw/blog/archives/3843
05. http://longair.net/blog/2009/04/16/git-fetch-and-merge