用 Git 管理合約版本
把合約寫成 Markdown 放進 Git 儲存庫,每次修訂都留下作者、日期與理由,任兩版草稿都能逐行比對。
一份供貨合約,三週內改了五版。
草稿靠郵件附件來回傳:合約_v3.docx、合約_v3_最終版.docx、合約_v4_乾淨版.docx。
簽約當天有人問:責任上限什麼時候從十二個月費用降成六個月?誰同意的?
沒人能從這堆附件回答。 追蹤修訂某一輪被全部接受,下一輪就看不到了;要比對第二版和第五版,只能兩份對著讀。
軟體工程師用版本控制處理這種問題。 我認為合約也適用,前提只有一個:合約得是文字。
版本控制能替合約做什麼
Git 把文件記成一連串提交(commit)。 每次提交是檔案在某個時間點的狀態,附帶:
- 誰改的;
- 何時改的;
- 為什麼改。
有了這串紀錄,就能回答談判與稽核常問的事:兩版之間改了哪幾條、某一行最後是誰改的、某天合約寫的是什麼。
Word 的追蹤修訂只活在單一檔案裡,修訂一接受就消失。 Git 保留每個狀態,任兩個都能比對,不限相鄰版本。
第一步:把合約寫成 Markdown
Git 逐行比對文字,所以合約得是文字檔。 Markdown 剛好:章節用標題,條款用編號,沒有藏在格式裡的東西。
# 供貨合約 — 甲公司
## 第九條 責任限制
9.1 任一方依本合約所負之賠償責任總額,以請求發生前六個月內已支付之費用為上限。
9.2 違反保密義務(第十二條)者,不適用第 9.1 條。
一行放一句或一個子條款,比對時看到的就是改動的那一句。
第二步:每份合約有固定位置
- 每個交易對象一個資料夾,例如
contracts/acme/; - 每份合約一個 Markdown 檔,例如
supply-agreement.md; - 簽好的 PDF 放在旁邊,例如
supply-agreement-signed-2026-10-01.pdf。
Git 也保存 PDF 的每個版本,只是無法逐行比對。 Markdown 是工作版,PDF 是簽了什麼的紀錄。
第三步:有意義的修訂就提交
寄給對方的新草稿、電話裡談定的修改、自己審閱的更正,都值得一次提交。 說明寫下理由:
責任上限降為六個月費用
甲公司於 9 月 24 日電話會議提出,財務已同意。
半年後有人問「誰同意的」,答案就在這裡。
第四步:比對版本、追查條款
兩版之間改了什麼:命令列用 git diff,或用 GitHub 的比對頁面。
只會標出刪除與新增的行。
某一條最後是誰改的:用 blame。 GitHub 的 blame 檢視會在每一行旁列出最後改動它的提交,連同作者、日期與說明。
第五步:先審再算數
需要核准的修改,在分支上改,再開 pull request。 審閱者只看到會變動的幾行,可以直接留言、核准。 主分支只留下談定的文字。
第六步:保護歷史
每次提交都以內容與先前歷史的雜湊值識別。 改動舊的提交,之後的雜湊值全部跟著變,對不上先前的副本。
有寫入權限的人仍可用 force push 改寫分支。
在 GitHub 保護主分支,禁止 force push 與刪除。
簽署版加上標籤(tag),例如 signed-2026-10-01,隨時找得到。
Git 不會替你做的事
Git 不會談判。 對方寄來帶修訂標記的 Word 檔,還是得有人把修改變成提交。 Git 也不排版;要簽署時,用 Pandoc 這類工具把 Markdown 匯出成 PDF 或 Word。
它做的是誠實記錄文字:每個版本、誰改的、為什麼。
不用命令列也能做
MyGitNotes 是在你自己 Git 儲存庫上運作的 Markdown 工作區。 在瀏覽器裡寫合約,提交前就能看差異,提交訊息依修改內容自動擬好。 檔案留在你的儲存庫,紀錄不依賴我們。
法務團隊想這樣管理大量合約,請見法務與文件頁面。