程式異動對照表 (Compare List) 是上線流程必備文件之一,Git 內建 git diff 指令,能整理出鉅細靡遺的異動記錄,完整度之高,甚至能 Email 給其他開發者跑 git apply 同步原始碼版本,不管是複核、稽查或存證需求,git diff 報告的有效性無庸置疑。不過,純文字形式的 git diff 常被嫌不夠親民(但其實不難懂,Git 老鳥都能肉眼解讀),在非技術人員心中,Compare List 要像 Github 或 TFS 這種形式才合格:

於是,我接到一個需求 - 能不能 git diff 內容轉換成美美的文件呢?

Git 身為當今版控主流(何止主流,差不多一統天下了),相關資源豐富,大小需求幾乎都有人想過,甚至連工具都寫好了。diff2html 是在 Github 得到超過一萬五千顆星星的 JavaScript 開源專案,能將 git diff 輸出結果轉成精美網頁。diff2html 最常見用法是 npm 安裝配合 Node.js 執行或整合到前端專案。由於我的應用情境要涵蓋普羅大眾(包含完全沒摸過 Git 的管理人員或稽查人員),在流程中直接使用 git diff 輸出文字檔作為附件沒問題(純粹只保異動本質,不摻雜顯示樣式資訊,不浪費資料空間),遇到麻瓜人員檢視場合再將咒語似的 git diff 檔轉成凡人可讀的文件,為了讀上線文件要求使用者安裝 Node.js、npm,還要開 DOS 視窗有點不切實際,寫成工具網站是種解法,但必須考量檢視者網路環境及存取權限,有時是件麻煩事。

發現 diff2html 支援在網頁引用 js 跟 css 直接執行的輕前端做法,深得我心,決定寫成單一 HTML 檔案,讓使用者選取 git diff 檔轉成好讀文件。

用個實例示範,假設我提交了一個 Commit,在其中新增一個檔案(added.txt)、刪除一個檔案(to-delete.txt)、更名一個檔案(old-name.txt -> new-name.txt),另外對 web.config appSettings 做了增刪改:

git diff 結果如下:

經驗老道的 Git 老鳥能從中看出 1) csproj 變更、2) added.txt 新增、3) old-name.txt 更名 new-name.txt、4) to-delete.txt 刪除、5) web.config 修改... 等異動,但不可否認,程式碼左右對照的格式可讀性更高。

git diff 閱讀器網頁如下,原理是使用者使用 <input type="file"> 選取 git diff 輸出檔案 (使用 git diff hash_id hash_id > x:\path_to_diff.txt 將輸出結果存成檔案),透過 File API 讀取檔案內容並呼叫 diff2html 函式將其轉為 HTML。(範例中 js 與 css 來自 CDN,改參照本機檔案即可離線使用)

<!DOCTYPE html>

<html>

<head>
    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />
    <script src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html.min.js"></script>
</head>

<body>
    <input type="file" id="diffSrc" />
    <div id=report>

    </div>
    <script>
        function readFile(e) {
            var file = e.target.files[0];
            if (!file) return;
            var reader = new FileReader();
            reader.onload = function (re) {
                var diffText = re.target.result;
                var diffHtml = Diff2Html.html(diffText, {
                    drawFileList: true,
                    matching: 'lines',
                    outputFormat: 'side-by-side',
                });
                document.getElementById('report').innerHTML = diffHtml;
            };
            reader.readAsText(file);
        }
        document.getElementById("diffSrc").addEventListener("change", readFile, false);
    </script>
</body>

</html>

就醬,站在巨人的肩膀上,我們用一個網頁加 15 行程式便完成 git diff 網頁轉換器囉~

Example of using diff2html to convert git diff report to friendly web page with single .html file.


Comments

# by LinnieKao

請教您類似的問題,關於diff後的結果,因為user反應,當單一行內容很長,但是只有異動了幾個字,肉眼比對仍然吃力。 於是加上--word-diff-regex=. ,可以逐字比對,在英數環境下,一切都很美好,但是加入了中文--out出來的結果,卻有可能出現亂碼。 不曉得您是否有類似經驗可以分享,謝謝。

# by Jeffrey

to LinnieKao, 我做了一些研究,請參考新文 https://blog.darkthread.net/blog/git-diff-options/

Post a comment