Git 是一個很強大的分布式版本控制系統,我打算用它來管理私人的代碼和文檔。
當使用省略-m參數的 git commit 命令,還有 git rebase 等命令時,Git 會開啟由 GIT_EDITOR 系統內容變數或 Git 的 core.editor 全域變數指定的編輯器。可不可以把我們喜歡的 EmEditor 配置成 Git 的編輯器呢?可以的,雖然最初嘗試的時候遇到了一些小麻煩。
為什麼記事本可以,EmEditor 就不行?
我們可以使用 git config --global core.editor notepad.exe 命令將記事本配置成 Git 的編輯器。之後,修改一些文檔,執行 git commit -a 命令,Git 會在“工作目錄\.git\”建立一個名為 COMMIT_EDITMSG 的文字檔,然後調用記事本開啟這個檔案,等待使用者輸入備忘資訊,此時 git commit -a 命令處於阻塞狀態,直到我們在記事本裡輸入資訊,儲存並關閉記事本之後,Git 再從 COMMIT_EDITMSG 檔案裡讀取備忘資訊,完成提交操作。
由於 Git 是 Linux 下的項目,即使移植到了 Windows 下也仍然使用 LF 而不是 CRLF 作為分行符號,這會導致用記事本開啟的文本全都擠到了一行,所以我們希望使用像 EmEditor 這樣的能夠相容 LF 分行符號的文字編輯器。
但是,如果我們使用 git config --global core.editor F:/工具箱/文檔工具/EmEditor/EmEditor.exe 將 EmEditor 配置為 Git 的編輯器,再執行 git commit -a 命令,會發現雖然成功通過 EmEditor 開啟了 COMMIT_EDITMSG 檔案,但是 git commit -a 命令並沒有阻塞,而是直接讀取了空白的 COMMIT_EDITMSG 檔案(我們還沒來得及輸入資訊呢),並返回“Aborting commit due to empty commit message.”錯誤資訊。
這是為什麼呢?我們可以猜測 git commit -a 的工作原理是:先建立編輯器的一個新的進程,然後將 COMMIT_EDITMSG 檔案傳遞給這個進程並等待進程結束,然後再讀取 COMMIT_EDITMSG 檔案。然而,運行 EmEditor.exe COMMIT_EDITMSG 並不一定會建立新的進程——如果有正在運行著的 EmEditor,將會直接使用這個進程開啟 COMMIT_EDITMSG 檔案(新增一個Tab頁),這樣 Git 自然也就不會阻塞了。為了驗證這個想法,可以做一個小實驗:關閉所有運行著的 EmEditor,包括工作列上的托盤表徵圖(emedtry.exe),然後執行 git commit -a 命令,這次就會處於阻塞狀態了。當然,我們不能每次都這麼幹。好在 EmEditor 有一個“/sp”命令列參數,意思是強制建立新的 EmEditor 進程,有了它,我們差不多就能得償所願了。不過,實際操作一下就會發現,直接使用 git config --global core.editor F:/工具箱/文檔工具/EmEditor/EmEditor.exe 命令進行配置並不好用,而是要像下面這樣操作。
將EmEditor配置為Git的編輯器(Step by Step)
我的 EmEditor.exe 的路徑是“F:/工具箱/文檔工具/EmEditor/EmEditor.exe”,以下配置都是基於這個路徑,如果你的路徑如果與我不同請自行智能錯誤修正。
Step1 新增一個名為 GIT_EDITOR 的系統內容變數,設定它的值為 EmEditor.exe //sp。
Step2 修改 PATH 系統內容變數,追加 F:\工具箱\文檔工具\EmEditor。
Step3 開啟新的Git命令列以便讓系統內容變數的修改生效。
測試 執行 git commit -a 命令,會發現經由新的 EmEditor 進程開啟 COMMIT_EDITMSG 檔案,git commit -a 命令處於阻塞狀態,在 EmEditor 中輸入一些文字,儲存檔案並關閉 EmEditor,git commit -a 命令繼續執行並成功提交。
為什麼不能直接配置 core.editor 全域變數?為什麼不能直接把 GIT_EDITOR 參數設為 F:/工具箱/文檔工具/EmEditor/EmEditor.exe //sp?因為這麼做全都不好用。不是我喜歡彎彎繞,而是 Git 太變態。