缘起

本人主题使用 hexo-theme-butterfly: 🦋 A Hexo Theme: Butterfly ,但是在此基础上又做了一些自定义。用过一段时间之后,作者的源仓库可能更新了很多没有的功能。之前的时候,每次都是手动 compare 并合并的,但是实践了两次之后,发现存在以下问题:

  1. 每次升级十分耗时
  2. 自己定义的功能在合并时可能丢失或遗漏

鉴于此,本文尝试使用一种较为智能的方式解决以上问题。

TL,DR

要想将源仓库(origin repo)合入(dest repo)中,那么可以将(origin repo)伪造成(dest repo)仓库的一个分支,然后合并到(dest repo)仓库中的指定分支(本文为 dev)。

工作流程

  1. 本地新建目录butterfly
  2. 克隆目标仓库
    git clone https://github.com/imoyao/hexo-theme-butterfly.git imoyao
  3. 克隆源仓库
    git clone https://github.com/jerryc127/hexo-theme-butterfly.git
    克隆两个仓库分别作为子目录
  4. 将源目录(jerryc)作为远程仓库添加到目标仓库(imoyao),并命名为jerryc
    git remote add jerryc ../jerryc
  5. 从源仓库下载数据到本仓库
    $ git fetch jerryc
    remote: Enumerating objects: 139, done.
    remote: Counting objects: 100% (137/137), done.
    remote: Compressing objects: 100% (28/28), done.
    remote: Total 58 (delta 45), reused 43 (delta 30)
    Unpacking objects: 100% (58/58), done.
    From ../jerryc
    * [new branch] dev -> jerryc/dev

    git fetch
    Git - git-fetch Documentation

    git-fetch - Download objects and refs from another repository
    git fetch 是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。

    而 git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。

  6. 查看此时仓库信息

    $ git log
    commit 88b1cc553ce3c2b5e53dccb2ff259ddb078c333b (HEAD -> dev, origin/dev, origin/HEAD)
    Author: Jerry <***@gmail.com>
    commit 88b1cc553ce3c2b5e53dccb2ff259ddb078c333b (HEAD -> dev, origin/dev, origin
    /HEAD)
    Author: Jerry <***@gmail.com>
    Date: Sat Nov 21 00:27:01 2020 +0800

    # 省略内容

    commit 88b1cc553ce3c2b5e53dccb2ff259ddb078c333b (HEAD -> dev, origin/dev, origin
    /HEAD)
    Author: Jerry <***@gmail.com>
    Date: Sat Nov 21 00:27:01 2020 +0800

    # 省略内容

    commit 7f03c3f71696fde1f1d3f1e969844ecde3d7f805
    Author: Jerry <***@gmail.com>
    Date: Tue Nov 3 22:20:16 2020 +0800

    # 省略内容

    ```plain
    7. 将源仓库下载下来的 dev 分支作为新分支 checkout 到目标分支`updatedev`
    ```bash
    git checkout -b updatedev jerryc/dev
    Switched to a new branch 'updatedev'
    Branch 'updatedev' set up to track remote branch 'dev' from 'jerryc'.

    此时分支状态

    $ git branch

      dev           # 我的开发分支
    master # 我的主分支
    * updatedev # 作者和我的fetch之后的分支

  7. 切换到我的dev分支

    git checkout dev

    此时分支状态

    $ git branch

    * dev
    master
    updatedev

  8. 合并fetch的分支代码到我的dev分支

    $ git merge updatedev
    Updating 88b1cc5..dc1c7c5
    Fast-forward
    _config.yml | 6 +-
    languages/default.yml | 6 +-
    languages/en.yml | 2 +
    languages/zh-CN.yml | 4 +-
    # 中间省略
    source/css/_mode/readmode.styl | 19 +++--
    source/js/main.js | 91 ++++++++++++++++------
    source/js/utils.js | 13 +++-
    31 files changed, 374 insertions(+), 169 deletions(-)
    create mode 100644 layout/includes/third-party/newest-comments/twikoo-comment.pug

    补充:如果遇到如下报错:

    fatal: refusing to merge unrelated histories

    那么可以git merge时加上--allow-unrelated-histories后缀:
    git merge repo1 --allow-unrelated-histories

  9. 查看合并后代码

    $ git log
    commit dc1c7c5efdbb92de10a44cec2e15d16b84823ce7 (HEAD -> dev, jerryc/dev, updatedev)
    Merge: 02af307 97fe932
    Author: Jerry Wong <***@gmail.com>
    Date: Mon Dec 7 21:17:09 2020 +0800

    # 省略内容

    commit 97fe932ad9c22fa4b5690d38b33242eed11742f0
    Author: 零度冷咖啡 <***@outlook.com>
    Date: Mon Dec 7 08:25:02 2020 +0800

    # 省略内容

    commit 01e7929c02a5fd018ab3171a381487a78f2df05c
    Merge: 7c3945f 02af307
    Author: 零度冷咖啡 <***@outlook.com>
    Date: Mon Dec 7 08:22:17 2020 +0800

    # 省略内容

    commit 02af3077e71d02071ad3c7e8b159149310597513
    Author: Jerry <***@gmail.com>
    Date: Sat Dec 5 22:28:54 2020 +0800

    # 省略内容

    commit 88b1cc553ce3c2b5e53dccb2ff259ddb078c333b (origin/dev, origin/HEAD)
    Author: Jerry <***@gmail.com>
    Date: Sat Nov 21 00:27:01 2020 +0800

    # 省略内容

    点击可查看大图

    横向拼图参考 此处

  10. 删除无用的fetch分支updatedev

    $ git branch -D updatedev
    Deleted branch updatedev (was dc1c7c5).
  11. 提交到远程仓库
    Administrator@PC201803221826 MINGW64 /h/mycode/butterfly/imoyao (dev)
    $ git add .

    Administrator@PC201803221826 MINGW64 /h/mycode/butterfly/imoyao (dev)
    $ git commit -m 'updatedev'
    On branch dev
    Your branch is ahead of 'origin/dev' by 4 commits.
    (use "git push" to publish your local commits)

    nothing to commit, working tree clean

    Administrator@PC201803221826 MINGW64 /h/mycode/butterfly/imoyao (dev)
    $ git push
    Total 0 (delta 0), reused 0 (delta 0)
    To https://github.com.cnpmjs.org/imoyao/hexo-theme-butterfly.git
    88b1cc5..dc1c7c5 dev -> dev
    同样的道理,我们可以把master分支与原作者保持同步。这个留给读者去实践练习。

更上一层楼

把我自己修改的合并到我的仓库中。

  1. 拷贝目录到同级目录
    三个同级文件夹
  2. 初始化为仓库(否则无法执行 git 合并)
    $ git init
    Initialized empty Git repository in H:/mycode/butterfly/masantu/.git/
  3. 在 masantu 仓库中 add 并 commit 代码作为一次提交
    git add .
    git commit -m 'init mycode to repo'
  4. 添加远程仓库masantu并命名为masantu
    关于这条命令的解释Git - git-remote Documentation

    git remote add [shortname] [url]
    Add a remote named for the repository at . The command git fetch can then be used to create and update remote-tracking branches /.

    $ git remote add masantu ../masantu
  5. masantu仓库的代码拉到imoyao仓库中
    $ git fetch masantu
    warning: no common commits
    remote: Enumerating objects: 261, done.
    remote: Counting objects: 100% (261/261), done.
    remote: Compressing objects: 100% (259/259), done.
    remote: Total 261 (delta 18), reused 0 (delta 0)
    Receiving objects: 100% (261/261), 259.62 KiB | 1.08 MiB/s, done.
    Resolving deltas: 100% (18/18), done.
    From ../masantu
    * [new branch] master -> masantu/master

  6. masantu/master作为基准新建分支upmst(updatemasantu 的简写)

    $ git checkout -b upmst masantu/master
    Switched to a new branch 'upmst'
    Branch 'upmst' set up to track remote branch 'master' from 'masantu'.

    此时分支状态

    $ git branch

      dev
    * upmst
    master

  7. 切换分支到dev

    $ git checkout dev
    Switched to branch 'dev'
    Your branch is up to date with 'origin/dev'.
    $ git branch
    * dev
    upmst
    master

  8. 合并masantu分支到dev
    git merge upmst --allow-unrelated-histories
    CONFLICT (add/add): Merge conflict in source/js/utils.js
    Auto-merging source/js/utils.js
    # 省略内容
    Auto-merging source/css/_global/function.styl
    CONFLICT (add/add): Merge conflict in package.json
  9. 手动解决冲突
  10. 测试(如果必要)并提交合并的代码
  11. 删除刚才的分支和添加的远程源
    git branch -D upmst
    git remote remove masantu

    参考链接

合并两个不相关的 Git 仓库 | 周立的博客 - 关注 Spring Cloud、Docker