【Hexo】多台電腦佈署 GitHub page 的問題

【Hexo】多台電腦佈署 GitHub page 的問題

本篇重點

  • 了解 Hexo 佈署的流程
  • 多台電腦佈署網站,導致 git 紀錄被覆蓋
  • 使用腳本解決 git 紀錄被覆蓋的問題

Hexo 佈署的流程

演示佈署網站的流程

command
1
2
3
4
5
# 先移除原本已生成的檔案
hexo clean

# 生成檔案並且佈署到 github
hexo d -g

使用 hexo d 前要先到 _config.yml 中配置 GitHub 的設定

hexo d 的時候會將 public 目錄下的檔案複製到 .deploy_git 中,再從這個目錄強制推送 git push -f 到 repository,接著 github page 服務會自動偵測到推送的更新,並在一段時間內更新佈署到網站上

多台電腦佈署網站,導致 git 紀錄被覆蓋

當使用 Hexo 在多台電腦上進行佈署時,可能會遇到 git 紀錄被覆蓋的問題。這是因為 hexo d 會從 .deploy_git 強制推送更新到 github,而不會先拉取最新的紀錄回 .deploy_git。因此,如果在不同的電腦上進行佈署,git 紀錄就可能會被覆蓋。

舉例來說,如果 A 電腦在 7 月 1 日更新了網站,隨後 B 電腦在 7 月 3 日也進行了更新,但由於 B 電腦的 .deploy_git 資料夾沒有拉取最新的記錄,因此 GitHub 上的記錄不會包含 7 月 1 日的更新。

雖然這對網站內容本身沒有任何影響,但版本控制的主要目的是記錄每一次的更改。因此,保留每次更新的記錄是必要的!

解決 git 紀錄被覆蓋的問題

Hexo 官方沒有針對多台電腦佈署的具體方案,因此每次佈署網站時,都需要先進入 .deploy_git 更新進度再執行 hexo d,這樣非常不方便。為了解決這個問題,我編寫了一個腳本來自動化更新進度並佈署網站。

1. 製作自動化腳本 deploy.sh

在每次佈署前先檢查 .deploy_git 資料夾是否存在,並拉取最新的進度。這樣可以確保佈署過程中的進度同步,避免覆蓋提交記錄的問題。

以下是完整的腳本示例:

deploy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/bash

# GitHub Pages repository 的 URL
REPO_URL="https://github.com/forgetfulengineer/forgetfulengineer.github.io.git"
USER_NAME="forgetfulengineer"
USER_EMAIL="thatforgetfulengineer@gmail.com"
FIRST_DEPLOY=0

# 檢查 .deploy_git 資料夾是否存在
echo -e "\n檢查 .deploy_git 資料夾是否存在..."
if [ -d ".deploy_git" ]; then
# 切換到 .deploy_git 資料夾並拉取最新進度
cd .deploy_git || { echo -e "\n切換到 .deploy_git 資料夾失敗"; exit 1; }
echo -e "\n拉取 github page 最新進度..."
git pull || { echo -e "\n拉取進度失敗"; exit 1; }
cd .. || { echo -e "\n返回 Hexo 資料夾失敗"; exit 1; }
else
# 檢查 GitHub Pages repository 是否已有 commit
echo -e "\n檢查 GitHub Pages repository 是否已有 commit..."
if git ls-remote --exit-code "$REPO_URL" HEAD > /dev/null 2>&1; then
echo -e "\nClone repository 到 .deploy_git 資料夾..."
git clone "$REPO_URL" .deploy_git || { echo -e "\nClone repository 失敗"; exit 1; }

# 設置 git config
cd .deploy_git || { echo -e "\n切換到 .deploy_git 資料夾失敗"; exit 1; }
git config --local user.name "$USER_NAME"
git config --local user.email "$USER_EMAIL"
git config --local core.ignorecase false
cd .. || { echo -e "\n返回 Hexo 資料夾失敗"; exit 1; }
else
echo -e "\nGitHub Pages repository 尚無 commit,進行首次佈署"
FIRST_DEPLOY=1
fi
fi

# 清理舊的生成文件
echo -e "\n清理舊的生成文件..."
hexo clean || { echo -e "\nHexo 清理失敗"; exit 1; }

# 生成新的靜態文件並佈署網站
echo -e "\n生成新的靜態文件並佈署網站..."
hexo d -g || { echo -e "\nHexo 佈署失敗"; exit 1; }

# 如果是首次部署,進入 .deploy_git 設置 git config
if [ "$FIRST_DEPLOY" -eq 1 ]; then
echo -e "\n首次佈署,設置 git config --local core.ignorecase false"
cd .deploy_git || { echo -e "\n切換到 .deploy_git 資料夾失敗"; exit 1; }
git config --local core.ignorecase false
cd .. || { echo -e "\n返回 Hexo 資料夾失敗"; exit 1; }
fi

echo -e "\n佈署完成"

2. 執行 deploy.sh 腳本

完成 deploy.sh 腳本後,將其放在執行 Hexo 的資料夾中。佈署網站時,只需執行 deploy.sh,神奇的事情就會發生囉~😝

command
1
2
# 在 hexo 資料夾的路徑執行 deploy.sh
./deploy.sh

補充說明

檢查 .deploy_git 資料夾是否存在

使用 if [ -d ".deploy_git" ] 檢查 .deploy_git 資料夾是否存在。
在 Shell 中,-d 選項常用來檢查資料夾是否存在。如果要檢查檔案是否存在,可以使用 -f 選項。若要檢查資料夾或是檔案是否存在,則可以使用 -e 選項。

使用 ||{} 處理命令執行失敗的情況

|| 是邏輯 OR 操作符。它表示當前面的命令執行失敗(返回非零退出狀態碼)時,執行後面的命令。例如:

command
1
command1 || command2

如果 command1 執行成功,那麼 command2 不會被執行。如果 command1 執行失敗,那麼 command2 會被執行。

{} 用於將多條命令組合成一個命令塊。命令塊中的命令會按順序執行。通常與邏輯操作符(如 ||&&)結合使用。例如:

command
1
command1 || { command2; command3; }

如果 command1 執行失敗,則執行命令塊 { command2; command3; } 中的命令。

使用 echo -e 啟用反斜杠特殊字符轉義

告訴 echo 啟用反斜杠特殊字符轉義,例如 \n\t\r 。如果沒有使用 -e ,字串會直接顯示不會有特殊符號的效果。

檢查 GitHub Pages repository 是否已有 commit

使用 git ls-remote --exit-code "$REPO_URL" HEAD 檢查 repository 。

ls-remote 用於檢查遠端儲存庫是否存在特定分支的命令,執行後終端顯示該分支最新的進度。

command
1
2
3
4
git ls-remote --exit-code https://github.com/forgetfulengineer/forgetfulengineer.github.io.git

# 終端顯示
4w727c14a1260cf59a65e34de3b643d3f3bee83f HEAD

--exit-code 選項

  • 如果找到指定的引用(例如 HEAD),命令會成功執行並返回退出碼 0
  • 如果未找到指定的引用,命令會返回退出碼 2

不使用 -exit-code 的情況

  • 無論是否找到指定的引用,命令都會成功執行並返回退出碼 0

> /dev/null 2>&1; 表示不顯示 command 的輸出結果

將標準輸出和錯誤輸出重定向到垃圾桶 (/dev/null),這樣執行的結果就不會顯示在終端。

if [ -d ".deploy_git" ]; thenif git ls-remote --exit-code "$REPO_URL" HEAD > /dev/null 2>&1; then 兩種判斷式的差異

[ ... ] 是 POSIX 標準中的測試命令,又稱 test 命令,用來檢查條件表達式是否為真,根據條件的結果返回不同的退出狀態碼。退出狀態碼為 0 表示條件為 true,非 0 表示條件為fasle,通常用於檔案或目錄的存在性、字串比較等操作。

if COMMAND; then 是基於命令執行後的退出狀態碼判斷。退出狀態碼為 0 表示 true,非 0 表示 false,通常用於判斷一個命令是否成功執行。

git config --local core.ignorecase false 設定 git 追蹤檔名大小寫

有兩種情況會首次建立 .deploy_git

  • 首次佈署,執行 hexo d 後建立 .deploy_git
  • GitHub Pages repository 已有 commit,使用 git clone 建立 .deploy_git

建立後建議進入 .deploy_git 設定 git 追蹤檔名大小寫,不然有機會遇到 git 忽略檔名大小寫導致 github page 404 的錯誤

結論

透過上述腳本,我們可以確保在多台電腦上進行 Hexo 佈署時,不會覆蓋 GitHub 上的提交記錄。這樣的解決方案不僅簡單且有效,同時也考慮到首次佈署的情況,確保每次佈署順利進行。

另外也可以使用 GitHub Actions 解決,GitHub Actions 可以設定自動化工作流程,將 Hexo 生成的靜態網站自動佈署到 GitHub Pages,但跟我的佈署習慣不同,所以就沒有使用了,使用方式可以看這篇教學。

希望這篇文章對遇到相同問題的你有所幫助~😁

作者

健忘工程師

發表於

2024-07-25

更新於

2024-07-25

許可協議


評論

複製完成