对Hexo的主题进行升级,最头疼的莫过于配置文件(_config.yml)的处理。我们自己需要对它进行自定义配置,但是主题升级更新后它的内容也可能会有所改变,二者可能产生冲突。如果只是在升级后简单把旧的配置文件复制过去,当然是不合理的。
所以,正确的打开方式因该是:利用git的分支与合并功能,自动检查冲突或者快速合并。
1. 关键git命令解释
git checkout [-b <new_branch>] <branch> |
- 不带
-b
,切换到已有的分支<branch>
- 带
-b
参数,以<branch>
为起始点,新建分支<new_branch>
并切换到新分支,其中<branch>
缺省时采用当前分支为起始
git merge [--squash] <branch> |
- 不带
--squash
,将分支<branch>
合并到到当前分支 - 带
--squash
参数,同上,但是只是将<branch>
中的修改内容迁移过来,而不保留其中的commit历史,也就是说,结果是一样的,但是不保留中间过程。
2. 开始使用
首先使用git clone下载主题到本地,此时只有一个默认的master分支,示意如下:
(红圆代表主题发布者的commit,绿圆表示你的commit;末端方框表示分支指针,星号标识活动分支)
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3---m(* master) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none;
但是,先不要着急进行自定义配置,先切换到一个新分支blog
再说:
git checkout -b blog |
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3---m(master) c-m3---b(* blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none;
然后再进行配置编辑,完成后提交commit(可以多次commit):
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3---m(master) c-m3-->c-b1(( )) c-b1---b(* blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-b1 fill:green,stroke:none;
如果之前你已经在master分支上做过了修改,那么也是有办法解决的。
只需要保存当前修改到新分支,并将master分支还原即可。
git add -A |
3. 升级
将远程的master分支更新拉取到本地master分支:
git checkout master |
或者用下面的一条命令简化版,效果一样:
git fetch origin master:master |
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3(( ))-->c-m4(( )) c-m4(( ))-->c-m5(( )) c-m5---m(master) c-m3-->c-b1(( )) c-b1---b(* blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-m4 fill:red,stroke:none; style c-m5 fill:red,stroke:none; style c-b1 fill:green,stroke:none;
然后,在master基础上开一个新的分支:
git checkout -b updated-blog master |
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3(( ))-->c-m4(( )) c-m4(( ))-->c-m5(( )) c-m5---m(master) c-m3-->c-b1(( )) c-b1---b(blog) c-m5---ub(* updated-blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-m4 fill:red,stroke:none; style c-m5 fill:red,stroke:none; style c-b1 fill:green,stroke:none;
此时分支updated-blog
具有远程更新的内容,但是没有自定义的配置,因此需要进行分支合并:
git merge blog |
不少情况下merge可以全自动完成,但是也有的情况下会有合并冲突!例如主题开发者更新了某个_config.yml
配置,而你也恰好编辑了其中内容,因此这时候需要先手动处理冲突。具体方法参见下一节。
合并完成后提交commit确认合并,此时updated-blog
分支同时具有了更新和自定义配置。
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3(( ))-->c-m4(( )) c-m4(( ))-->c-m5(( )) c-m5---m(master) c-m5-->c-merge1(( )) c-m3-->c-b1(( )) c-b1---b(blog) c-b1-->c-merge1 c-merge1---ub(* updated-blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-m4 fill:red,stroke:none; style c-m5 fill:red,stroke:none; style c-b1 fill:green,stroke:none; style c-merge1 fill:green,stroke:none;
如果git merge时带了--sqush
参数,那么结果还是一致的,不过不会保留来自blog
分支的commit历史:
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3(( ))-->c-m4(( )) c-m4(( ))-->c-m5(( )) c-m5---m(master) c-m5-->c-merge1(( )) c-m3-->c-b1(( )) c-b1---b(blog) c-merge1---ub(* updated-blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-m4 fill:red,stroke:none; style c-m5 fill:red,stroke:none; style c-b1 fill:green,stroke:none; style c-merge1 fill:green,stroke:none;
如果有需要,可以删除旧分支blog
:
git branch -D blog |
普通merge:
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3(( ))-->c-m4(( )) c-m4(( ))-->c-m5(( )) c-m5---m(master) c-m5-->c-merge1(( )) c-m3-->c-b1(( )) c-b1-->c-merge1 c-merge1---ub(* updated-blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-m4 fill:red,stroke:none; style c-m5 fill:red,stroke:none; style c-b1 fill:green,stroke:none; style c-merge1 fill:green,stroke:none;
--squash
merge:
graph LR c-m1(( ))-->c-m2(( )) c-m2(( ))-->c-m3(( )) c-m3(( ))-->c-m4(( )) c-m4(( ))-->c-m5(( )) c-m5---m(master) c-m5-->c-merge1(( )) c-merge1---ub(* updated-blog) style c-m1 fill:red,stroke:none; style c-m2 fill:red,stroke:none; style c-m3 fill:red,stroke:none; style c-m4 fill:red,stroke:none; style c-m5 fill:red,stroke:none; style c-merge1 fill:green,stroke:none;
观察上图,尤其是--squash
合并的情况,可以看到整个git commit的图形状回到了升级之前的状态,不同的是拉取了更新并向前推进了。
如果有强迫症,可以将updated-blog
分支重命名一下:
git branch -m updated-blog blog |
4. 合并冲突处理
观察git merge时的输出,或者用git status
命令查看一下,可以知道哪些文件中具有合并冲突,其中会将发生冲突的部分框起来,大致如下:
<<<<<<< HEAD
# 当且分支的内容
=======
# 从被合并分支迁移过来的内容
>>>>>>> blog
手动将框起来的部分斟酌修改即可。