about summary refs log tree commit diff stats
path: root/.emacs.d/lisp/init-git.el
diff options
context:
space:
mode:
authorDavid Morgan <djm_uk@protonmail.com>2022-10-12 13:29:53 +0100
committerDavid Morgan <djm_uk@protonmail.com>2022-10-12 13:29:53 +0100
commit130bc0a521002244efafbb8feda597a272913c16 (patch)
treed06849fefb8147f5baa3db0b5ecbd1a2368231e9 /.emacs.d/lisp/init-git.el
parent4274f81ede5a550bf7e8c5850cfcf3bd1bb95177 (diff)
downloaddotfiles-130bc0a521002244efafbb8feda597a272913c16.tar.gz
Add some magit and vc-based commands
Diffstat (limited to '.emacs.d/lisp/init-git.el')
-rw-r--r--.emacs.d/lisp/init-git.el81
1 files changed, 81 insertions, 0 deletions
diff --git a/.emacs.d/lisp/init-git.el b/.emacs.d/lisp/init-git.el
index 18c12c0..43e88c7 100644
--- a/.emacs.d/lisp/init-git.el
+++ b/.emacs.d/lisp/init-git.el
@@ -20,11 +20,61 @@
   :bind
   ("C-x v t" . git-timemachine-toggle))
 
+(use-package vc
+  :bind
+  (("C-x v C-r" . my/vc-refresh-state)
+   ("C-x v C-m" . my/update-git-master))
+  :custom (vc-follow-symlinks nil)
+  :config
+  (defun my/vc-refresh-state ()
+    (interactive)
+    (when-let ((root-dir (vc-root-dir)))
+      (dolist (buf (buffer-list))
+        (when (and (not (buffer-modified-p buf))
+                   (buffer-file-name buf)
+                   (file-exists-p (buffer-file-name buf))
+                   (file-in-directory-p (buffer-file-name buf) root-dir))
+          (with-current-buffer buf
+            (vc-refresh-state))))))
+
+  ;; [alias]
+  ;;   update-master = !git fetch origin master:master
+  ;;   update-main = !git fetch origin main:main
+  (defun my/update-git-master ()
+    "Update git master or main branch."
+    (interactive)
+    (if-let ((root (vc-root-dir)))
+        (let* ((branches (vc-git-branches))
+               (main-p (member "main" branches))
+               (master-p (member "master" branches))
+               (current-branch (car branches))
+               (on-master-p (member current-branch '("master" "main")))
+               (command (if main-p "update-main" "update-master"))
+               (buffer "*vc-update-master*"))
+          (if on-master-p
+              (vc-pull)
+            ;; based on vc-git--pushpull
+            (require 'vc-dispatcher)
+            (apply #'vc-do-async-command buffer root vc-git-program command nil)
+            (with-current-buffer buffer
+              (vc-run-delayed
+                (vc-compilation-mode 'git)
+                (setq-local compile-command
+                            (concat vc-git-program " " command))
+                (setq-local compilation-directory root)
+                (setq-local compilation-arguments
+                            (list compile-command nil
+                                  (lambda (_name-of-mode) buffer)
+                                  nil))))
+            (vc-set-async-update buffer)))
+      (message "not a git repository"))))
+
 (use-package magit
   :bind
   ("C-c g g" . magit-dispatch) ;; magit-file-dispatch is C-c M-g
   ("C-c g u" . my/magit-set-upstream)
   ("C-c g r" . my/magit-refresh-state)
+  ("C-c g m" . my/magit-update-git-master)
   :config
   ;; Requires the following gitconfig:
   ;; [alias]
@@ -33,8 +83,10 @@
   (defun my/magit-set-upstream ()
     (interactive)
     (magit-shell-command-topdir "git upstream"))
+
   ;; update stale git info on the modeline (based on code removed from doom modeline)
   (defun my/magit-refresh-state ()
+    "Update modeline git branch information."
     (interactive)
     (dolist (buf (buffer-list))
       (when (and (not (buffer-modified-p buf))
@@ -43,6 +95,35 @@
                  (file-in-directory-p (buffer-file-name buf) (magit-toplevel)))
         (with-current-buffer buf
           (vc-refresh-state)))))
+
+  ;; [alias]
+  ;;   update-master = !git fetch origin master:master
+  ;;   update-main = !git fetch origin main:main
+  (defun my/magit-update-master ()
+    "Update git master or main branch."
+    (interactive)
+    (if (magit-toplevel)
+        (let* ((branches (vc-git-branches))
+               (main-p (member "main" branches))
+               (current-branch (car branches))
+               (on-master-p (member current-branch '("master" "main")))
+               (command (concat "git " (if main-p "update-main" "update-master"))))
+          (if on-master-p
+              (vc-pull)
+            (magit-shell-command-topdir command)))
+      (message "Not a git repository")))
+
+  ;; Based on https://tsdh.org/posts/2022-08-01-difftastic-diffing-with-magit.html
+  (transient-define-prefix my/magit-extra-commands ()
+    "Extra magit commands."
+    ["Extra commands"
+     ("u" "Set upstream" my/magit-set-upstream)
+     ("r" "Refresh state (update modeline)" my/magit-refresh-state)
+     ("m" "Update master/main" my/magit-update-master)])
+  (transient-append-suffix 'magit-dispatch "!"
+    '("#" "Extra Magit Cmds" my/magit-extra-commands))
+  (define-key magit-status-mode-map (kbd "#") #'my/magit-extra-commands)
+
   :custom
   (magit-diff-refine-hunk 'all)
   (magit-diff-paint-whitespace-lines 'all)