git是利用檔案庫的觀念來管理檔案的歷史記錄,並追蹤檔案內容的狀態和版本等資訊,而GitHub網站是利用git來管理世界各地程式設計師所提供的程式原始碼。本文將利用GitHub所提供的gh-pages分支功能來架設一個提供靜態網頁功能的網站。
一般而言,要完成一個完整的網站服務,首先必須先準備一台主機,並在該主機上安裝網站伺服器(例如常見的Apache或IIS)軟體,再申請ISP的網路服務(頻寬越大,所需要的價格就越貴)。
最後,還要再視情況來決定是否需要申請網域名稱(如果沒有申請,使用者就僅能以IP的方式連接至網站伺服器)。如此一來,不僅費時,而且各種成本加起來也是一個不小的負擔。
如果僅是希望有一個能夠呈現靜態網頁內容的網站伺服器,那GitHub網站所提供的gh-pages頁面功能,就能夠在不需要任何預算的情況下滿足此類需求。因此,本文將說明如何利用GitHub來實作個人的網站。
什麼是git
git原先的目的是管理Linux核心程式的版本。但因其優異的功能,慢慢地成為程式設計師在選擇版本控制軟體的首選。
版本控制系統依其運作方式,可分為「集中式版本控制系統」(如傳統的cvs、Subversion)與「分散式版本控制」(如git),以下說明兩者的差異:
集中式版本控制系統
此類系統架構採用主從式的系統架構,參與專案的開發者會將所有版本的檔案集中儲存在遠端的版本控制系統伺服器(以下簡稱遠端伺服器)內,而在開發者本機端的儲存庫上只會儲存最新版本的歷史紀錄。當開發者完成程式撰寫後,想要上傳最新的檔案至遠端伺服器上(此動作稱為「提交」,英文是Commit),或者在撰寫的過程中想要查詢儲存在遠端伺服器的程式版本差異,甚至想要修改開發過程的歷史紀錄資訊,都必須透過網路連到遠端伺服器才能進行。
在初期開發時,由於相關檔案量不多,可能遠端伺服器的效能還不會受到太大的影響,但隨著時間的推移,當所儲存的專案程式版本越來越多時,就會影響版本控制系統伺服器的運作效率。另外,集中式的控管,高度依賴著網路的穩定性,一旦網路不穩定時,許多的開發工作就可能無法順利地進行。
集中式版本管理的最大優點在於,所有的歷史程式碼都集中在遠端伺服器上,因此可以很方便地進行集中式的權限控管,亦即可輕易地限制開發者接觸開發檔案的使用權限。
但其缺點是在離線狀態時,使用者能夠使用的版本控制功能有限,例如使用者無法查詢每一個歷史版本的資訊。另外,由於本機端僅儲存最新版本的歷史紀錄,因此也無法針對其他的版本進行差異比較。
分散式版本控制
相對於上述的集中式版本控制系統,此類系統是除了遠端伺服器上擁有專案各版本的完整程式碼之外,每個參與專案的開發者都會有一份完整的本機檔案庫,也儲存了所有變更過的檔案,以及專案各版本的歷史紀錄。因此,在遠端伺服器上所儲存的專案程式並非是唯一的,而是一個供多人同步專案資料用的共享版本。
由於各開發者都擁有完整的程式碼,所以在提交新版本時,並不需要利用網路同步至遠端的伺服器,僅須在使用者要提交最新版本時,再利用網路將最新版本更新到遠端伺服器上。
分散式版本控制在本機端存有一份完整的檔案庫,所以不會因為沒有網路連線而沒辦法進行歷史版本的查詢、歷史版本差異比較等功能。但是,其最大的缺點是無法有效地控管各開發者開啟目錄的權限。
在簡單比較兩種版本控制系統的優缺之後,接著繼續說明git的重要功能架構圖,如圖1所示。
git是利用檔案庫(Repository)的觀念來管理檔案的歷史記錄,例如記錄檔案、目錄狀態或修改歷史記錄,並追蹤檔案內容的狀態和版本等資訊。依其用途,可分為「遠端檔案庫」和「本地端檔案庫」。
「遠端檔案庫」指的是安裝在遠端的伺服器上,可讓團隊中的各個成員來分享相關資訊,主要的目的是為了讓開發團隊能共享資訊而建立的檔案庫。而「本地端檔案庫」,是為了方便開發者個人使用,在自己的機器上所配置的檔案庫。因此,開發者可在本地端檔案庫上完整地使用git所提供的功能。
依使用環境可區分為「本地端(Local)」與「遠端(Remote)」兩個環境,由於git屬於分散式的版本控制系統,所以開發者可利用離線的方式,在本地端的環境下開發,等到開發完成後,再把完整的程式利用網路推(Push)至遠端檔案庫上。或者,在開發的過程中以拉(Pull)的方式從遠端檔案庫取得其他開發者的程式來進行整合。
而在本地端的環境中,可以分為「工作目錄(Working Directory)」及「暫存目錄(Staging Area)」。「工作目錄」指的是開發者程式撰寫時所使用的目錄位置,亦即開發過程中所有的檔案都需要儲存在這個目錄下。而所有執行與專案相關的git指令,也都必須在工作目錄下執行。在開發完成前,git會暫時將檔案置入到「暫存目錄」,直到開發完成後,才會以提交(Commit)的方式儲存至本地端檔案庫。接著視需求而定,再決定是否要以推(Push)的方式將本地端檔案上傳至遠端檔案庫,以供其他開發團隊分享。
在簡單說明過git的工作環境後,接著進行git的實作。
進行git實作
為了讓大家能更輕易地了解git的實際執行過程,在此採用指令的方式來執行git相關的作業(以CentOS 7為例)。
首先,利用「yum install git」指令安裝git軟體。安裝完成後,就會提供git程式供使用者進行程式的版本控制。
git指令用法
接著說明常見的git指令用法,如下所述:
git init:建立管控程式用的本地端檔案庫,這是建立版本控制的第一個步驟。
git add:將程式加進暫存目錄中,以便日後提交至檔案庫。
git commit:在完成開發工作後,將完整的程式提交至檔案庫,可利用-m參數寫入本次提交的相關說明。
git rm:將檔案刪除掉,並移除該檔案的管控。
git status:顯示相關狀態資訊。
git branch [分支名稱]:建立分支程式。
git checkout [分支名稱]:切換到該分支下。如果僅執行「git checkout」,表示退出該分支。
git push:將檔案上傳至遠端的檔案庫。
git clone:從遠端伺服器上完整下載某個檔案庫內容。
在此以「/tmp/practice」為工作目錄(表示所有的操作都必須在此目錄內)為例,實作一次簡單地將檔案提交至本地端檔案庫的流程。
在使用git進行版本控制之前,首先必須建立本地端檔案庫,所以執行「git init」指令。
執行成功之後,將會在這個工作目錄下產生一個「.git」資料目錄,來儲存所有版本變更所需要的資訊,如圖2所示。接著,使用「git status」指令來查看目前的狀態,如圖3所示。
由於目前工作目錄內並無任何檔案,因此會回覆「沒東西可以提交(nothing to commit)」的訊息。
接下來,在工作目錄下新增一個檔案(檔名為test.txt),再同樣以「git status」指令來查詢狀態,便會發現檔案已成為untracked的狀態,如圖4所示。
git檔案狀態
git會將檔案狀態分成以下四類,分別加以說明:
‧untracked:代表未被追蹤的狀態,此為在工作目錄中新增檔案的最初始狀態,表示該檔案尚未被git所追蹤及管控。
‧unmodified:表示未被修改的狀態,當使用者以「git add」指令將狀態為untracked的檔案加入追蹤,就會將該檔案狀態從untracked更改到unmodified。另外一種情況是檔案已經被提交至檔案庫,也會將檔案的狀態回復到unmodified。
‧modified:已被修改的狀態,當檔案被改變時便會轉換到此狀態。
‧staged:表示暫存的狀態,通常處於這個狀態的檔案,即表示要準備提交到檔案庫上。
檔案加入追蹤
在新增檔案後,接著可利用「git add test.txt」指令將test.txt加入追蹤。
同樣地,利用「git status」指令查看,會發現檔案已被git所追蹤,如圖5所示。
在這裡要特別提醒的是,一般在第一次新增檔案時,會先以「git add [檔名]」指令將該檔案加入到暫存目錄並加以管控,而後如果再編輯該檔案的內容,git並不會同步更新在暫存目錄內的檔案,所以在編輯完成之後,記得還要再執行一次「git add」指令,才會更新相關變更後的內容。
在整個作業全部完成之後,最後即可利用「git commit」指令將相關程式更新到本地端的檔案庫。在簡單說明檔案提交的過程後,繼續實作上傳檔案至gh-pages。
開始gh-pages實作
相信大部分的程式設計師都聽過GitHub網站,這個網站即是利用git來管理世界各地程式設計師所提供的程式原始碼。在架構上,可將GitHub視為一個遠端檔案庫。如果想要和全世界其他程式開發者合作或是貢獻程式成為開放原始碼的話,都可以透過GitHub來當作遠端工作環境,去管理所開發的程式碼。但本文的目的並不在於管理程式的版本,而是利用GitHub所提供的gh-pages分支功能來架設一個提供靜態網頁功能的網站。
在GitHub的專案內新建一個分支名稱為「gh-pages」時,GitHub便會預設將此分支內的檔案以靜態網頁的方式呈現,因此可以利用此類特性來製造一個簡單的網站。而使用gh-pages時,會有以下的限制:
1. 僅能呈現靜態頁面的內容(即HTML網頁),並無法提供動態網頁,例如利用PHP、JSP等等網頁程式所撰寫的檔案。
2. 不能支援如.htaccess之類的密碼驗證功能,亦即不能針對gh-pages的頁面設定密碼保護。
3. 所有的gh-pages內的頁面都是公開的,表示所有的人都可存取到相關的頁面。
4. gh-pages上的檔案庫大小限制為1GB。
5. 每個月的頻寬限制為100GB。
6. 每小時最多能提交10個版本的檔案。
在簡單說明gh-pages後,接著就來實作gh-pages功能。
首先,建立一個GitHub的帳號(目前為免費)。註冊過程很簡單,在GitHub的官方網站(https://github.com/)註冊頁面內,填寫使用者帳號、密碼以及電子郵件等資訊即可。
在註冊完成後,GitHub就會寄發一封認證信到所填寫的電子郵件帳號,只須根據電子郵件內的指示回覆,即可完成註冊程序。在完成註冊後,接著即可繼續。
然後,在GitHub新建一個檔案庫(以本例而言,檔案庫的名稱為pagedemo),在建立過程中,建議勾選「initialize this repository with a README」選項,此選項會自動建立README的檔案,建立過程如圖6所示。
成功建立檔案庫之後,可利用如「https://github.com/[使用者名稱]/pagedemo」網址來查看檔案庫的內容,在此階段中,通常只會有一個名為「README.md」的檔案。接著,在本地端的工作機上(以下簡稱本地端)執行下列指令,將網頁檔案提交到新建的檔案庫。首先,以「git clone https://github.com/[使用者名稱]/pagedemo.git」來取得GitHub檔案庫內的檔案。成功執行後,在本地端會產生一個名稱為「pagedemo」的目錄(存放該檔案庫的所有檔案),此即為工作目錄,可以在此目錄中編輯相關的網頁檔案。如圖7所示。
接著,在此工作目錄內執行「git branch gh-pages」指令,新建一個名稱為「gh-pages」的分支。在建立分支成功後,以「git checkout gh-pages」指令切換到gh-pages分支上。在切換過後,即可在工作目錄內簡單地新增一個網頁檔(以index.html為檔名)。
接著,執行「git add .」指令將此檔案儲存到暫存區,並利用「git commit -m "test page"」指令(其中-m參數為本次提交的說明文字)提交到本地端的檔案庫上。
最後,使用「git push origin gh-pages」指令將本地端檔案庫內的檔案上傳至GitHub網站上。在上傳的過程中,會要求輸入GitHub上所註冊的帳號及密碼,如圖8所示。整個過程完成之後,連結「https://[使用者帳號].github.io/pagedemo/」網址,即可看到所製作的網頁內容。
結語
為了簡化說明起見,本文僅說明如何利用gh-pages的特性來達到最簡單的網站伺服器功能(僅能顯示靜態網頁),但gh-pages事實上也支援如Markdown(一種輕量級的標籤語言)、CSS(Cascading Style Sheets)樣式等等的語法,可讓靜態網頁產生更多的變化。
本文中所介紹的git指令,讓大家不必再辛苦地利用指令來執行。在開源碼社群中就有許多好用的圖形git軟體,例如GitHub Desktop(官方網址為https://desktop.github.com),只要能理解git的基本原理,相信就能夠輕易駕馭此類工具。 除此之外,在使用gh-pages頁面時,必須使用GitHub的網域(例如github.io)。但是若有自己的網域名稱,gh-pages也提供CNAME機制,可利用此機制來設定使用自行申請的網域名稱。
<本文作者:吳惠麟,多年資安經驗,喜好利用開源碼建構相關解決方案,著有「資訊安全原理與實驗」等書。>