对hexo页面排版的改动时常需要改主题目录里的文件,但主题也会升级,这意味着用户和主题开发者可能会改动相同的代码,如果不妥善管理代码,需要升级主题时,可能会很不优雅。本文以Next主题为例。
手动升级
面对升级版本之间的改动,一种容易想到的方法是纯手动升级。这里有两个案例
-
手动保存主题改动过的文件
如果你在themes/xxx主题文件有自定义的修改,请自行手动备份一下;如果你是大改的话,我也没有好办法 -
断断续续折腾了两天,才升级成功。所以,如果有啥感想,那就是:没事别瞎TM升级!当然,如果一定要升级,最好做增量升级:另起炉灶,一项一项地加功能,这样好定位问题,也容易回滚。
看来手动升级不够优雅,容易采坑。
通过git升级
为了避免手动升级,一个思路是采用git仓库管理主题目录,当主题升级时,采用git进行平滑升级。
这看似优雅,却会引入另一个问题:如何在主博客仓库中合理管理一个子主题仓库?NexT Issue #932有很多讨论,也有一些解决方案,这里列出几个:
1 采用数据文件的方式
参考数据文件的介绍和NexT Issue #328。采用数据文件也只能避免_config.yml文件冲突,对于用户修改页面模板情况就没办法了。
2 基于fork + submodule
维护父子两个仓库大大增加了复杂度,还要fork一份冗余的主题仓库,为了不经常有的主题升级增加这样的复杂性,实在没什么必要。
3 同步工具
有用户写了一个hexo同步工具hexo-git-backup,支持博客、主题的同步,支持自定义commit消息。但本质上是个备份工具,需要删除掉主题目录的.git目录,所以也不支持通过git升级主题。
采用git升级的方式,确实能够解放双手,平滑升级,但毕竟还是引入了一定的复杂度。有没有一种既能利用git的平滑升级,又不那么复杂的方案?
暴力但不失优雅的解决方式
由于主题升级的次数相对较少,一般不如用户修改频繁,所以一种简单易行暴力的方式是,git只用来升级,不用来同步,既能利用git进行平滑升级,又避免了引入双层git的复杂情况。
原理
由hexo博客主目录作为git仓库统一管理所有代码,主题目录不设单独git仓库。每次升级主题时,手动将主题目录制作成临时的git仓库,进而以git的方式进行升级,升级过后可以再销毁这个临时git仓库,由博客主仓库管理升级变更。
步骤
- 记录当前的主题版本tag,版本号在主题目录的package.json中的version字段。
- 随便找个其他目录,clone最新版本的主题仓库,新建分支temp并checkout,再将temp分支reset –hard到当前版本的tag。
- 【暴力】确认hexo的主题目录中没有.git目录,如果有,删掉。此时拿到步骤2的temp分支对应的.git文件夹,将其拷贝到hexo的主题目录中。
- 在主题目录中的temp分支上做一次提交(这次提交代表着在上一个版本基础上对主题目录所做的所有更改)。
- 在temp分支上merge想要升级到的版本tag,如果有冲突逐一解决掉。
- 至此升级完成,主题目录下的.git可以删掉了(销毁临时git仓库)。升级完成后记得将主目录做一次提交,主目录会将主题升级的所有改动进行提交。
特殊情况——NexT从v5.1.x升级到v6.0.x
NexT从v5.1.x升级到v6.0.x比较特殊,涉及到代码仓库的更改,代码仓库从iissnan改为theme-next。官方推荐这种方式:Update from NexT v5.1.x
,但这种方式治标不治本,保留了iissnan仓库的主题,新建了来自theme-next仓库的主题,做了一个切换而已;而迁移的过程,还是依赖手动,并没有利用类似git merge的平滑升级。
由于本文方法并不强依赖于git提交的连续性,而是只需要临时制作一个git仓库即可,所以天然支持这种更换git仓库的升级。
本文方法稍加改动就可以适用于NexT从v5.1.x升级到v6.0.x,具体步骤:
- 利用iissnan仓库的.git目录,将主题升级到iissnan仓库的最终版本。
- 利用theme-next仓库的.git目录,承接后续的升级。
注意
NexT v6.5.0主题仓库的.gitignore默认忽略了lib/里的font-awasome等内容(其他版本没有了解),如下
1 | .DS_Store |
这带来一个问题,如果主题仓库不是fork来的,而是想用主目录统一管理博客源代码,font-awesome等内容将无法推送到远程仓库,导致在其他环境从远程仓库clone时拿不到font-awasome,进而页面显示不正常。所以这里注意一下,主题.gitignore文件里的内容该删的删,该改的改。