使用场景
- 使用org文件记录各种用户名+密码,使用GnuPG加密org文件,文件后缀为 .org.gpg。
- 使用emacs打开gpg文件时自动引导输入密码进行解密,保存时自动加密。
- gpg文件加入git版本管理
困扰
- 在不同的pc上编辑gpg文件,在push的时候才发现没有和仓库同步,导致冲突由于是二进制文件,无法通过magit进行 diff/merge操作。
- 在此请教各位的解决方案(如有,后文可忽略)
尝试解决方案
- diff:
-
git diff:通过以下配置可以实现
git diff
,但在magit中ediff-diff-program
仍然是diff
,不能处理 gpg 文件git config --global diff.gpg.textconv “gpg --no-tty --decrypt”
-
ediff:追踪找到
ediff-make-temp-file
函数,添加了伪分隔线
后面的部分。- 通过判断 buffer名,将临时文件重命名为gpg文件
- 使用 find-file 重新解密
- 保存解密后的明文,返回明文临时文件,提供给
ediff-diff-program
使用
目前此方法遇到的问题是:如果将工作区的文件与历史版本进行比较,工作区密文文件对应的buffer会被替换成明文临时文件的buffer,不能使用ediff进行merge
-
(with-eval-after-load 'ediff
(defun ediff-make-temp-file (buff &optional prefix given-file start end)
(let* ((p (ediff-convert-standard-filename (or prefix "ediff")))
(short-p p)
(coding-system-for-write ediff-coding-system-for-write)
f short-f)
(if (and (fboundp 'msdos-long-file-names)
(not (msdos-long-file-names))
(> (length p) 2))
(setq short-p (substring p 0 2)))
(setq f (concat ediff-temp-file-prefix p)
short-f (concat ediff-temp-file-prefix short-p)
f (cond (given-file)
((find-file-name-handler f 'insert-file-contents)
;; to thwart file handlers in write-region, e.g., if file
;; name ends with .Z or .gz
;; This is needed so that patches produced by ediff will
;; have more meaningful names
(ediff-make-empty-tmp-file short-f))
(prefix
;; Prefix is most often the same as the file name for the
;; variant. Here we are trying to use the original file
;; name but in the temp directory.
(ediff-make-empty-tmp-file f 'keep-name))
(t
;; If don't care about name, add some random stuff
;; to proposed file name.
(ediff-make-empty-tmp-file short-f))))
;; create the file
(ediff-with-current-buffer buff
(write-region (if start start (point-min))
(if end end (point-max))
f
nil ; don't append---erase
'no-message)
(set-file-modes f ediff-temp-file-mode)
(expand-file-name f))
;--------------------------------------------------------------------------------------
(if (string-match "org.gpg" (buffer-name buff))
(if (string-match "org.gpg$" (buffer-name buff))
(progn ;; file has been decoded, write buffer's conntent to
(let* ((f (ediff-make-empty-tmp-file short-f)))
(get-buffer-create "*New-decode*")
(switch-to-buffer buff)
(append-to-buffer "*New-decode*" (point-min) (point-max))
(write-file f nil)
(kill-buffer (get-buffer "*New-decode*"))
(expand-file-name f)
))
(with-current-buffer buff
(read-only-mode 0)
(erase-buffer)
(let* ((f-gpg (format "%s.org.gpg" f))
(buff-decode (format "%s.gpg" (file-name-base f-gpg)))
(file-decode (file-name-sans-extension f-gpg)))
(rename-file f f-gpg)
(find-file f-gpg)
(delete-file f-gpg)
(recentf-remove-if-non-kept f-gpg)
(write-file file-decode nil)
(append-to-buffer buff (point-min) (point-max))
(kill-buffer (get-buffer buff-decode))
(switch-to-buffer buff)
(expand-file-name file-decode))))
(expand-file-name f))
)))