config-vcs.el (7147B)
1 ;;; config-vcs.el --- -*- lexical-binding: t; -*- 2 ;;; Commentary: 3 ;;; Version control configuration 4 ;;; Code: 5 6 (use-package vc 7 :config 8 (setq-default vc-find-revision-no-save t 9 vc-follow-symlinks t) 10 :bind (("C-x v f" . vc-log-incoming) ; git fetch 11 ("C-x v F" . vc-update) 12 ("C-x v d" . vc-diff))) 13 14 (use-package vc-dir 15 :config 16 (defun vde/vc-dir-project () 17 "Unconditionally display `vc-diff' for the current project." 18 (interactive) 19 (vc-dir (vc-root-dir))) 20 21 (defun vde/vc-dir-jump () 22 "Jump to present directory in a `vc-dir' buffer." 23 (interactive) 24 (vc-dir default-directory)) 25 :bind (("C-x v p" . vde/vc-dir-project) 26 ("C-x v j" . vde/vc-dir-jump) ; similar to `dired-jump' 27 :map vc-dir-mode-map 28 ("f" . vc-log-incoming) ; replaces `vc-dir-find-file' (use RET) 29 ("F" . vc-update) ; symmetric with P: `vc-push' 30 ("d" . vc-diff) ; align with D: `vc-root-diff' 31 ("k" . vc-dir-clean-files))) 32 33 (use-package vc-git 34 :config 35 (setq vc-git-diff-switches "--patch-with-stat") 36 (setq vc-git-print-log-follow t)) 37 38 (use-package vc-annotate 39 :config 40 (setq vc-annotate-display-mode 'scale) 41 :bind (("C-x v a" . vc-annotate) 42 :map vc-annotate-mode-map 43 ("t" . vc-annotate-toggle-annotation-visibility))) 44 45 (use-package ediff 46 :commands (ediff ediff-files ediff-merge ediff3 ediff-files3 ediff-merge3) 47 :config 48 (setq ediff-window-setup-function 'ediff-setup-windows-plain) 49 (setq ediff-split-window-function 'split-window-horizontally) 50 (setq ediff-diff-options "-w") 51 (add-hook 'ediff-after-quit-hook-internal 'winner-undo)) 52 53 (use-package diff 54 :config 55 (setq diff-default-read-only nil) 56 (setq diff-advance-after-apply-hunk t) 57 (setq diff-update-on-the-fly t) 58 (setq diff-refine 'font-lock) 59 (setq diff-font-lock-prettify nil) 60 (setq diff-font-lock-syntax nil)) 61 62 (use-package magit-popup) 63 64 (use-package magit 65 :unless noninteractive 66 :commands (magit-status magit-clone magit-pull magit-blame magit-log-buffer-file magit-log) 67 :bind (("C-c v c" . magit-clone) 68 ("C-c v C" . magit-checkout) 69 ("C-c v b" . magit-branch) 70 ("C-c v d" . magit-dispatch) 71 ("C-c v f" . magit-fetch) 72 ("C-c v g" . magit-blame) 73 ("C-c v l" . magit-log-buffer-file) 74 ("C-c v p" . magit-pull) 75 ("C-c v P" . magit-push) 76 ("C-c v r" . magit-rebase) 77 ("C-c v s" . magit-stage) 78 ("C-c v v" . magit-status) 79 ;; magit-commit ? magit-stage ? 80 ) 81 :config 82 (setq-default magit-save-repository-buffers 'dontask 83 magit-refs-show-commit-count 'all 84 magit-branch-prefer-remote-upstream '("main") 85 magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1 86 magit-bury-buffer-function #'magit-restore-window-configuration 87 magit-refresh-status-buffer nil) 88 89 (setq-default git-commit-summary-max-length 50 90 git-commit-known-pseudo-headers 91 '("Signed-off-by" 92 "Acked-by" 93 "Modified-by" 94 "Cc" 95 "Suggested-by" 96 "Reported-by" 97 "Tested-by" 98 "Reviewed-by") 99 git-commit-style-convention-checks 100 '(non-empty-second-line 101 overlong-summary-line)) 102 103 (magit-define-popup-option 'magit-rebase-popup 104 ?S "Sign using gpg" "--gpg-sign=" #'magit-read-gpg-secret-key) 105 (magit-define-popup-switch 'magit-log-popup 106 ?m "Omit merge commits" "--no-merges") 107 ;; cargo-culted from https://github.com/magit/magit/issues/3717#issuecomment-734798341 108 ;; valid gitlab options are defined in https://docs.gitlab.com/ee/user/project/push_options.html 109 ;; 110 ;; the second argument to transient-append-suffix is where to append 111 ;; to, not sure what -u is, but this works 112 (transient-append-suffix 'magit-push "-u" 113 '(1 "=s" "Skip gitlab pipeline" "--push-option=ci.skip")) 114 (transient-append-suffix 'magit-push "=s" 115 '(1 "=m" "Create gitlab merge-request" "--push-option=merge_request.create")) 116 (transient-append-suffix 'magit-push "=m" 117 '(1 "=o" "Set push option" "--push-option=")) ;; Will prompt, can only set one extra 118 119 (defun vde/fetch-and-rebase-from-upstream () 120 "" 121 (interactive) 122 (magit-fetch-all "--quiet") 123 (magit-git-rebase (concat "upstream/" (vc-git--symbolic-ref (buffer-file-name))) "-sS")) 124 125 ;; Hide "Recent Commits" 126 (magit-add-section-hook 'magit-status-sections-hook 127 'magit-insert-modules 128 'magit-insert-unpushed-to-upstream 129 'magit-insert-unpulled-from-upstream) 130 ;; No need for tag in the status header 131 (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header) 132 (setq-default magit-module-sections-nested nil) 133 134 ;; Show refined hunks during diffs 135 (set-default 'magit-diff-refine-hunk t)) 136 137 (use-package gitconfig-mode 138 :commands (gitconfig-mode) 139 :mode (("/\\.gitconfig\\'" . gitconfig-mode) 140 ("/\\.git/config\\'" . gitconfig-mode) 141 ("/git/config\\'" . gitconfig-mode) 142 ("/\\.gitmodules\\'" . gitconfig-mode))) 143 144 (use-package gitignore-mode 145 :commands (gitignore-mode) 146 :mode (("/\\.gitignore\\'" . gitignore-mode) 147 ("/\\.git/info/exclude\\'" . gitignore-mode) 148 ("/git/ignore\\'" . gitignore-mode))) 149 150 (use-package gitattributes-mode 151 :commands (gitattributes-mode) 152 :mode (("/\\.gitattributes" . gitattributes-mode))) 153 154 (use-package dired-git-info 155 :disabled 156 :bind (:map dired-mode-map 157 (")" . dired-git-info-mode)) 158 :defer 2) 159 160 (defun git-blame-line () 161 "Runs `git blame` on the current line and 162 adds the commit id to the kill ring" 163 (interactive) 164 (let* ((line-number (save-excursion 165 (goto-char (point-at-bol)) 166 (+ 1 (count-lines 1 (point))))) 167 (line-arg (format "%d,%d" line-number line-number)) 168 (commit-buf (generate-new-buffer "*git-blame-line-commit*"))) 169 (call-process "git" nil commit-buf nil 170 "blame" (buffer-file-name) "-L" line-arg) 171 (let* ((commit-id (with-current-buffer commit-buf 172 (buffer-substring 1 9))) 173 (log-buf (generate-new-buffer "*git-blame-line-log*"))) 174 (kill-new commit-id) 175 (call-process "git" nil log-buf nil 176 "log" "-1" "--pretty=%h %an %s" commit-id) 177 (with-current-buffer log-buf 178 (message "Line %d: %s" line-number (buffer-string))) 179 (kill-buffer log-buf)) 180 (kill-buffer commit-buf))) 181 182 (use-package git-gutter 183 :hook (prog-mode . git-gutter-mode) 184 :config 185 (setq git-gutter:update-interval 0.2)) 186 187 (use-package git-gutter-fringe 188 :config 189 (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated)) 190 (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated)) 191 (define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240] nil nil 'bottom)) 192 193 (provide 'config-vcs) 194 ;;; config-vcs.el ends here