整個事情源於某天心血來潮又寫了篇博客,當準備使用hexo發表時,忽然想到一個問題以前雖然作到對於博客項目的git備份了,可是最近新換的主題配置修改也備份了嗎?
,有點像強迫症出門後思考房門有沒有鎖好的感受。git
背景是這樣的:最初我剛接觸hexo的時候,以爲發現了寶貝,它是個不錯的靜態博客生成器,風格偏極客風,雖然說是博客工具,但要拿給不會技術的人可能用起來還比較蹩腳,由於其雖然聲稱使用簡便,只須要快速地搭建環境,敲敲命令,就能夠在網頁上展示出漂亮的我的博客網站來,但其搭建環境基於Node.js,命令又依賴於git,還得把本地的博客源文件編譯成瀏覽器可解讀的靜態文件發佈到遠程git倉庫,還得使用支持pages服務的git倉庫,好比github的github pages或coding pages。因此我當初剛接觸的時候,對其原理也是隻知其一;不知其二,僅停留在」會用「程度,但隨着時間的推移,免不了發生一些其餘變更,好比換電腦,這時候我就發現,若是沒有對本地博客項目進行版本庫的管理和備份,那麼只要硬盤上的博客項目文件夾出現丟失或者換電腦,就麻煩了。固然,換電腦還算好,只要用優盤把舊電腦裏的文件夾拷貝過去,在新電腦搭建相同的環境,就能恢復使用了,但這方法不夠優雅,不夠geek。因而就在網上查hexo博客備份的方法,最後結合查到的方式和本身的推敲嘗試,記錄了一篇我是如何備份博客的github
但今天再看,當時只解決了博客「根項目」的保存,最近換了新的主題,主題的配置文件改了一大通,固然就是根據本身進行的個性化修改,忽然想到,主題項目是博客項目themes文件夾的一個子項目,是進到themes目錄,經過git clone
下載到本地的另外一個git項目。問題來了,git項目中嵌套git項目,事情看上去不那麼簡單。好在以前就瞭解過子項目git submodule
的概念,知道這是那塊的東西,但當時剛接觸子項目
的時候以爲有點複雜,就沒再理會,如今發現逃不過了,這是最好也是最恰當的解決方案,因此再次開始了搜查。web
先是根據猜測結合本身使用git的經驗進行嘗試segmentfault
首先,理了一下思路,新下載的hexo-theme-matery
項目是不該該直接劃爲子模塊的,由於它的遠程關聯是github中原做者的項目,我對其的修改不可能直接提交到人家那裏,也提交不上去,因此我首先應該有一份本身的關於hexo-theme-matery
項目的拷貝,不管是本地git仍是遠程倉庫,都是本身的,因此先進入到themes/hexo-theme-matery
目錄,把git初始化刪掉(後來想到這裏其實不用直接把git初始化刪掉,只要把遠程倉庫關聯改爲我本身的就能夠了,由於在本地git的提交都是我本身的,只要同步到本身的遠程倉庫就能夠了)瀏覽器
刪除git初始化(使一個項目脫離git的管理)bash
rm -rf ./.git
複製代碼
而後再從新初始化themes/hexo-theme-matery
目錄成爲一個git項目,並關聯我遠程建的空項目hexo
因爲遠端建的是空項目,因此能夠毫無衝突的直接push並創建默認分支設置(加參數 -u)ide
cd hexo-theme-matery
git init .
git add .
git commit -m 'initial matery theme as a divided git project'
git remote add origin git@git.coding.net:daemonG/my-hexo-theme-matery.git
git push -u origin master
複製代碼
接下來要創建子項目關聯了,參考了網上的一篇文章在 hexo 中使用 git submodules 管理主題工具
照貓畫虎地進行了以下的操做post
按照我對網上文章的理解,覺得是經過以下命令,把某個文件夾變成一個項目並命名子項目爲theme-matery
cd hexo-theme-matery
git add submodule . theme-matery
複製代碼
但發現提示錯誤,發現是命令的參數順序錯了,因而改正爲
git submodule add . theme-matery
複製代碼
還不對,提示子模塊必須是一個絕對路徑的目錄,修改成
git submodule add ./ theme-matery
複製代碼
能夠了,但發現好像不對,子模塊添加成功的提示告訴我,我敲的這個命令是在當前目錄添加了一個theme-matery目錄,內容是當前目錄的全部,這並非我想要的,因而準備刪掉此次操做的產物
git submodule remove theme-matery
複製代碼
提示並無remove這個命令,並提示了我有哪些關於子模塊的命令可用,因而
git submodule deinit
複製代碼
提示須要對所有文件進行子模塊撤銷
git submodule deinit --all
複製代碼
提示新創建的子模塊已經有了git修改記錄,若是此時要撤銷子模塊,須要進行強制撤銷操做
git submodule deinit --all -f
複製代碼
這樣發現,新建的theme-matery
文件夾消失了,但還殘留一個.gitmodules
文件,這是git子模塊的描述文件,既然剛纔是一次失敗的嘗試,這個也刪掉
rm -rf .gitmodules
複製代碼
終於恢復如初了,再來,繼續嘗試其餘方法。既然剛纔的確生成了子模塊描述文件和對應的子項目,那麼方向不錯,只是生成的位置和預期不符,因而我退到項目根路徑從新操做
cd ..
cd ..
git submodule add themes/hexo-theme-matery/ theme-matery
複製代碼
一樣提示了剛纔犯的一個錯誤,指定的子模塊要以絕對路徑給出
git submodule add ./themes/hexo-theme-matery/ theme-matery
複製代碼
這回的確在項目根路徑生成子模塊了,但也不對,原來命令中的最後一個參數是最終生成的子模塊文件夾名稱,而不是對於子模塊定義的別名,我理解錯了,因此還得刪掉重來
git rm theme-matery
git rm theme-matery -f
git rm .gitmodules
複製代碼
這我就迷茫了,到底應該怎麼添加子模塊呢,再看網上查的文章,裏面舉的例子是把一個遠程git項目下載到根項目中並做爲子模塊,前提是我原來只有一個git根項目,而後再添加一個遠程git項目到本地的git項目的一個子文件夾做爲一個子模塊存在,下載+子模塊初始化兩步合併操做,但個人狀況是,我本地已是一個git根項目裏套着一個別人的git項目了,想在本地操做,把這個子git項目變成根git項目的子模塊。
emmmmm...
靈光一閃,有了辦法
反正剛纔已經把本地的主題項目同步到遠端新建的空項目了,因此也就是我修改過配置文件的主題項目已經在遠端有了備份,因此我能夠把本地的刪掉,而後按照參考文章裏的作法,經過下載遠端項目到本地並初始化爲子模塊的方式進行操做了
git submodule add git@git.coding.net:daemonG/my-hexo-theme-matery.git themes/my-hexo-theme-matery
複製代碼
完美,效果是我想要的
接下來還有提交的問題,我已經預料到這個問題,雖然是子模塊,但確定也存在提交的問題,畢竟是兩個獨立的git項目,只是存在父子關聯關係,應該存在單獨提交父項目
、單獨提交子項目
和同時提交父項目和子項目
三種狀況
先試一下
git add .
git commit -m 'add theme/matery as submodule'
複製代碼
在根目錄發現這樣提交併不會提交子模塊的修改
難道是子模塊的修改沒被git管理到?
git submodule add .
git add . --recursive
複製代碼
呃,這都是無用操做
再試了一下參考文章裏的git commit -am 'update config of submodule'
,也不行
感到無助的時候迴歸官方文檔Git 工具 - 子模塊和另外一篇文章的參考Git Submodule的使用,有一句說法醍醐灌頂
主git倉庫中存在.gitmodules文件,它記錄了submodule的基本信息。例如remote地址。 同時在某處記錄了主git倉庫所用的submodule的commit號。 主git倉庫並不一樣步submodule中的全部代碼,而是同步其remote地址和commit號,每一個clone都是根據這兩個信息自行到remote地址獲取到該commit版本的內容。因此,若是你要更新submodule必須作上面的操做步驟。而你操做完成後,你的git倉庫中submodule的commit號獲得更新。
因此,根項目想要把子模塊的修改一併做爲主項目的一部分進行提交,須要察覺到子模塊中的commit號改變
cd ..
cd ..
git add .
git commit -m 'update config of submodule'
複製代碼
這樣再回到主項目,子模塊的提交就一併提交到主項目的遠程了,固然子項目仍是「自治」的,子模塊的提交仍是子模塊的提交,它也是一個獨立的git項目
雖然囉嗦了這麼一大篇,主要是爲了再現當時的各類失敗嘗試,這樣在往後遇到問題時可以想起當時的思路。但也免不了此時的結論就是最佳的方案,可能還有一些操做是錯誤的,或者存在隱患的,關於git子模塊的使用還在進一步的實踐和學習中。
剛作了這樣的嘗試,博客就崩了,發佈上去直接白屏,通過多方排查,想到是我從新命名了主題項目的名稱,而整個hexo的設計都是約定優於配置的,因此改動主題項目名,一定致使配置上對不上,出現報錯,而且還很差定位到錯誤,還好想到了是這裏的問題,因此把根項目配置文件中theme的配置項改成修改後的名稱,博客恢復正常了。
cd 子模塊目錄
git add .
git commit -m '像正常修改提交git項目同樣操做'
git push
cd 父模塊目錄
git add .
git commit -m '提交父模塊中子模塊的改動'
git push
複製代碼
核心步驟:進到子模塊目錄進行提交,再回到父模塊項目再次提交
在父模塊目錄遍歷更新其下的子模塊
cd 父模塊目錄
git submodule foreach git pull
複製代碼
進入到子模塊目錄中正常更新
cd 子模塊
git pull
複製代碼
遞歸下載,同時下載父模塊git項目並遞歸檢查其包含的子模塊git項目一併下載
git clone 項目地址 --recursive
複製代碼
先下載父模塊項目,下載後若是父項目包含子模塊則會有對應子項目名稱的空目錄,進入子模塊目錄初始化子模塊
git clone 項目地址
cd 子模塊目錄
git submodule init
git submodule update
複製代碼
git submodule update
用以確保子模塊更新到最新和下載完整,好比使用遞歸下載git clone 項目地址 --recursive
時下載不全的狀況
git不支持直接刪除子模塊
cd 子模塊
git rm --cached 子模塊
cd 父模塊
rm -rf 子模塊
rm .gitmodules
複製代碼
待補充
總結hexo的優勢和缺點
由於使用hexo-deployer發佈到遠端git倉庫的是對源項目進行編譯後的文件,與原項目有着徹底不一樣的目錄格式,一旦源項目丟失,沒法經過已經發布的遠程git項目逆向生成
由於主題項目通常都是獨立的git項目,也會獨立的更新功能,若是不能很好的將其做爲子模塊和博客項目關聯並對其進行獨立git項目備份的話,在換電腦或主題項目變動後,很難保留用戶本身的修改
由於hexo是基於配置約定的,因此有時用戶會錯誤的使用一些命令或配置修改,會致使hexo在部署到遠端的時候發生錯誤,而產生覆蓋遠端發佈文件,致使博客不可訪問的問題。因此對待hexo博客要像對待一個web項目同樣通過本地測試,命令以下(s爲server的首字母標識)
hexo s
複製代碼
若是默認的4000端口被佔用,可經過添加-p
參數指定其餘端口
hexo s -p 4001
複製代碼
經本地驗證無誤,符合改動預期後再發布遠程
hexo g -d
複製代碼
還有可能致使博客沒法正常訪問的緣由多是pages服務配置不正確,或者域名不可用,域名過時等緣由,須要查閱網上其餘人的解決方案