SVN 預設不支援徹底刪除歷史記錄中的檔案(為了版本控制完整性)。但某些情況下(敏感資料洩漏、巨大二進位檔佔用空間、誤提交機密資訊),必須從版本庫中永久抹除。本文介紹基於 svnadmin dump/filter/load 的標準方案,並說明恢復誤刪檔案的方法。
SVN 版本庫匯出 → 過濾排除目標路徑 → 建立新版本庫 → 匯入過濾後的資料 → 替換原版本庫
/data/svn/projecttrunk/test.exe、trunk/notallowed/ 目錄/tmp/svn-cleanup
cd /tmp/svn-cleanup
svnadmin dump /data/svn/project > project_original.dump
project_original.dump 包含所有版本、所有變更歷史。
# Linux/Unix
cat project_original.dump | svndumpfilter exclude trunk/test.exe trunk/notallowed > project_new.dump
# Windows (cmd)
type project_original.dump | svndumpfilter exclude trunk/test.exe trunk/notallowed > project_new.dump
# Windows (PowerShell)
Get-Content project_original.dump | svndumpfilter exclude trunk/test.exe trunk/notallowed > project_new.dump
exclude 參數支援多個路徑,路徑相對於版本庫根目錄
svnadmin create /data/svn/project_new
svnadmin load /data/svn/project_new < project_new.dump
# 備份原版本庫(謹慎!)
mv /data/svn/project /data/svn/project_backup_$(date +%Y%m%d)
# 重命名新版本庫
mv /data/svn/project_new /data/svn/project
# 修正權限(視部署用戶而定)
chown -R svn:svn /data/svn/project
chmod -R 770 /data/svn/project
版本庫:E:/svn/project
結構:QA/Trunk、Software/Tags/test.exe
目標:刪除 Software/Tags/test.exe
# 1. 匯出
svnadmin dump E:/svn/project > aaa.dump
# 2. 過濾(注意路徑以 / 開頭)
type aaa.dump | svndumpfilter exclude /Software/Tags/test.exe > bbb.dump
# 3. 建立新庫並匯入
svnadmin create E:/svn/project_new
svnadmin load E:/svn/project_new < bbb.dump
# 4. 替換
rename E:/svn/project E:/svn/project_old
rename E:/svn/project_new E:/svn/project
| 項目 | 說明 |
|---|---|
| 儲存空間 | dump 檔案可能極大(等同版本庫大小),需足夠磁碟空間 |
| 執行時間 | 大型版本庫 dump/load 可能耗時數小時 |
| 版本號變更 | 過濾後版本號重新連續編號,原版本號失效 |
| 相關提交 | 包含被刪除路徑的提交會變成空提交(無檔案變更) |
| 外部引用 | svn:externals 指向被刪路徑會失效 |
| 鎖定/屬性 | 相關鎖定與版本庫屬性會遺失 |
| 客戶端 | 所有使用者需重新 checkout,舊工作副本無法更新 |
svnadmin dump -r 0:10000 分段匯出、過濾、匯入svnadmin dump | gzip > dump.gz、zcat dump.gz | svndumpfilter ... | svnadmin loadsvnserve 或 Apache)避免並發寫入若只是誤刪(而非需徹底抹除歷史),使用標準 SVN 恢復功能即可,無需上述複雜操作。
# 查看刪除歷史
svn log -v | grep -B5 "D.*filename"
# 假設刪除發生在版本 1234
# 恢復到 1233 版本的狀態
svn merge -r 1234:1233 ^/path/to/deleted/item
# 或直接複製舊版本
svn copy -r 1233 ^/path/to/deleted/item ^/path/to/restore/item -m "Restore deleted item"
# 提交
svn commit -m "Restore accidentally deleted file/folder"
svnadmin hotcopy 熱備份版本庫git filter-branch 或 BFG Repo-Cleaner 處理歷史清理更強大SVN 徹底刪除歷史檔案需謹慎操作:dump → filter → load → replace 是標準流程,但會改變版本號、需足夠空間與時間、所有客戶端需重新檢出。誤刪檔案恢復則簡單得多,使用 Show log → Revert 或 svn merge/copy 即可。建議建立預防機制,避免頻繁進行歷史重寫操作。