home

My NixOS systems configurations.
Log | Files | Refs | LICENSE

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