# Debian 打包利器:gbp pq 完整指南與工作流程詳解 在 Debian 打包的世界裡,當您選擇使用 Git 作為主要的版本控制工具時,`git-buildpackage` (簡稱 `gbp`) 工具集將會是您的得力助手。其中,`gbp pq` 更是管理原始碼補丁 (patch) 的一把瑞士刀。 這篇文章將從零開始,為您深入解析 `gbp pq` 的工作流程,並解釋其背後由多個 Git 分支協同運作的優雅機制。 ## Gbp 工作流程的核心角色:四大分支 要完全理解 `gbp` 的運作,首先要認識它所依賴的四個核心 Git 分支,它們各司其職,共同構成一個清晰、可靠的打包環境。 1. `upstream` **(上游原始碼分支)** * **角色**:原味湯底。 * **內容**:儲存最純淨、未經任何修改的上游開發者原始碼。 * **來源**:通常由 `gbp import-orig` 指令從上游發布的 `.tar.gz` 壓縮檔自動產生或更新。 2. `main` **(主要打包分支)** * **角色**:特製鍋物。 * **內容**:以 `upstream` 分支為基礎,並額外包含了 Debian 打包所需的 `debian/` 目錄以及所有透過 patch 應用上去的修改。這是您最主要的工作分支。 3. `pristine-tar` **(原始壓縮檔校驗分支)** * **角色**:品質保證書。 * **內容**:它不儲存程式碼,而是記錄上游原始 `.tar.gz` 壓縮檔的校驗碼 (checksum)。 * **用途**:確保您可以隨時透過 Git 倉庫 100% 精確地還原出當初匯入的那個原始壓縮檔,是套件可重現性 (reproducibility) 的重要基石。 4. `patch-queue/main` **(Patch 管理工作區)** * **角色**:暫存的手術台。 * **內容**:這是一個臨時的工作分支,專門用來建立和修改 patch。您在這個分支上的每一個 commit,最終都會被轉換成一個 `.patch` 檔案。 * **管理者**:完全由 `gbp pq` 工具在幕後自動管理。 ## 完整工作流程圖 這張圖表呈現了從拿到原始碼到產出 patch 的完整旅程,以及四大分支之間如何互動。 ```mermaid graph LR subgraph "A. Repo 內的核心分支" direction TB U["upstream"] M["main"] PQ["patch-queue/main"] PT["pristine-tar"] end subgraph "B. 工作流程與指令" direction TB B1["1\. gbp import-orig"] B2["2\. gbp pq switch<br/>(從 main 進入)"] B3["3\. 在 patch-queue 上<br/>修改 & git commit"] B4["(可選) gbp pq rebase upstream"] B5["4\. gbp pq export<br/>(在 patch-queue 上執行)"] B6["5\. 在 main 上<br/>git commit patches"] end %% 關係連結與狀態變化 B1 -- "更新" --> U & PT M -- "執行" --> B2 -- "切換至" --> PQ PQ -- "在此分支上操作" --> B3 B3 --> B4 -- "更新" --> PQ PQ -- "執行" --> B5 B5 -- "<b>匯出 patch 並自動切換回</b>" --> M M -- "提交最終變更" --> B6 %% 樣式設定 classDef command fill:#f9f,stroke:#333,stroke-width:2px; class B1,B2,B3,B4,B5,B6 command; ``` ----- # 實戰教學:一步步走過 gbp pq 流程 讓我們跟著流程圖的腳步,實際操作一次。 ## 步驟 1:匯入上游原始碼 (`gbp import-orig`) 一切始於您取得了上游釋出的原始碼壓縮檔 (例如 `example-pkg-1.0.0.tar.gz`)。 ```bash # --pristine-tar 參數會建立並更新 pristine-tar 分支 gbp import-orig --pristine-tar /path/to/example-pkg-1.0.0.tar.gz ``` 這個指令是整個流程的發動機,它會自動為您: * 在 `pristine-tar` 分支記錄壓縮檔的校驗資訊。 * 在 `upstream` 分支提交解壓縮後的純淨原始碼。 * (如果這是第一次匯入) 通常建議您從 `upstream` 建立 `main` 分支: `git checkout upstream -b main`。 ## 步驟 2:進入 Patch 工作區 (`gbp pq switch`) 現在,假設您在 `main` 分支上,發現需要修改程式碼。這時,就要請出 `gbp pq` 了。 ```bash # 確認目前在 main 分支上 git checkout main # 執行 switch 指令 gbp pq switch ``` 執行後,您的工作目錄會被自動切換到 `patch-queue/main` 分支。這是一個隔離的環境,您可以安心地在上面進行修改,不必擔心弄亂 `main` 分支。 ## 步驟 3:建立 Patch (`git commit`) 在 `patch-queue/main` 分支上,您可以像平常一樣修改、新增、刪除檔案。當一項修改完成後,就用 `git commit` 將它提交。 **重點**:在這裡,**每一個 commit 就代表未來的一個 patch 檔案**。Commit 的訊息 (message) 會成為 patch 的標頭和描述,請務必用心撰寫。 ```bash # (修改 src/main.c 檔案...) # 將修改加入暫存區 git add src/main.c # 提交變更,這個 commit 就是一個 patch git commit -m "Fix: 修正用戶迴圈中的緩衝區溢位問題" ``` 您可以重複此步驟,建立多個 commits 來應對不同的修改。 ## 步驟 4:匯出 Patch 並返回 (`gbp pq export`) 這是整個流程中最神奇的一步。當您在 `patch-queue/main` 上完成所有 commits 後,請執行: ```bash # 確認目前在 patch-queue/main 分支上 # 直接執行 export 指令 gbp pq export ``` 這個指令非常強大,它會**自動完成**以下所有事情: 1. 讀取 `patch-queue/main` 上的所有新 commits。 2. 將這些 commits 轉換成標準格式的 `.patch` 檔,存入 `debian/patches/`。 3. 自動更新 `debian/patches/series` 檔案,確保 patch 的應用順序。 4. **將您從 `patch-queue/main` 自動切換回原本的 `main` 分支**。 5. 將 `debian/patches/` 目錄下的所有變動 `git add` 到暫存區。 您不需要手動切換分支,`export` 指令一鍵搞定! ## 步驟 5:提交最終變更 (`git commit` on `main`) `gbp pq export` 完成後,您已經回到了 `main` 分支。此時,您只需要做最後的確認與提交。 ```bash # 確認狀態,會看到 debian/patches/* 的變更已在暫存區 git status # 提交這些由 gbp pq 生成的 patch 檔案 git commit -m "Add patch to fix user loop overflow." ``` 至此,一個完整的「新增 patch」流程就完成了。您的 `main` 分支乾淨地記錄了「新增一組 patch」這個動作,而 patch 的具體內容則由 `gbp pq` 完美地管理。 ## (可選) 場景:當上游發布新版本 如果上游發布了 `1.0.1` 版本,您的工作流程會是: 1. 執行 `gbp import-orig` 匯入新版 tarball,`upstream` 分支會更新。 2. 切換到 `main` 分支,執行 `git merge upstream` 將新版原始碼合併進來。 3. 執行 `gbp pq rebase upstream`。這個指令會自動進入 `patch-queue/main`,並將您之前寫的所有 patch (commits) 重新應用 (rebase) 到最新的 `upstream` 程式碼之上。 4. 若有衝突則解決衝突,完成 rebase。 5. 執行 `gbp pq export` 匯出更新後的 patch。 6. 在 `main` 分支上 `git commit` 提交變更。 # 結論 `gbp pq` 透過巧妙地運用 Git 分支,將傳統上繁瑣的 patch 管理化繁為簡。它將 patch 從一堆散亂的檔案提升為帶有清晰歷史紀錄的 Git commit,讓 Debian 打包工作流程更加現代化、透明且易於維護。希望這篇詳盡的指南能幫助您充滿信心地駕馭這個強大的工具。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up