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