magit-reflog.el (7164B)
1 ;;; magit-reflog.el --- Inspect ref history -*- lexical-binding:t -*- 2 3 ;; Copyright (C) 2008-2024 The Magit Project Contributors 4 5 ;; Author: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev> 6 ;; Maintainer: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev> 7 8 ;; SPDX-License-Identifier: GPL-3.0-or-later 9 10 ;; Magit is free software: you can redistribute it and/or modify it 11 ;; under the terms of the GNU General Public License as published by 12 ;; the Free Software Foundation, either version 3 of the License, or 13 ;; (at your option) any later version. 14 ;; 15 ;; Magit is distributed in the hope that it will be useful, but WITHOUT 16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 18 ;; License for more details. 19 ;; 20 ;; You should have received a copy of the GNU General Public License 21 ;; along with Magit. If not, see <https://www.gnu.org/licenses/>. 22 23 ;;; Commentary: 24 25 ;; This library implements support for looking at Git reflogs. 26 27 ;;; Code: 28 29 (require 'magit-core) 30 (require 'magit-log) 31 32 ;;; Options 33 34 (defcustom magit-reflog-limit 256 35 "Maximal number of entries initially shown in reflog buffers. 36 The limit in the current buffer can be changed using \"+\" 37 and \"-\"." 38 :package-version '(magit . "3.0.0") 39 :group 'magit-commands 40 :type 'number) 41 42 (defcustom magit-reflog-margin 43 (list (nth 0 magit-log-margin) 44 (nth 1 magit-log-margin) 45 'magit-log-margin-width nil 46 (nth 4 magit-log-margin)) 47 "Format of the margin in `magit-reflog-mode' buffers. 48 49 The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH). 50 51 If INIT is non-nil, then the margin is shown initially. 52 STYLE controls how to format the author or committer date. 53 It can be one of `age' (to show the age of the commit), 54 `age-abbreviated' (to abbreviate the time unit to a character), 55 or a string (suitable for `format-time-string') to show the 56 actual date. Option `magit-log-margin-show-committer-date' 57 controls which date is being displayed. 58 WIDTH controls the width of the margin. This exists for forward 59 compatibility and currently the value should not be changed. 60 AUTHOR controls whether the name of the author is also shown by 61 default. 62 AUTHOR-WIDTH has to be an integer. When the name of the author 63 is shown, then this specifies how much space is used to do so." 64 :package-version '(magit . "2.9.0") 65 :group 'magit-log 66 :group 'magit-margin 67 :type magit-log-margin--custom-type 68 :initialize #'magit-custom-initialize-reset 69 :set-after '(magit-log-margin) 70 :set (apply-partially #'magit-margin-set-variable 'magit-reflog-mode)) 71 72 ;;; Faces 73 74 (defface magit-reflog-commit '((t :foreground "green")) 75 "Face for commit commands in reflogs." 76 :group 'magit-faces) 77 78 (defface magit-reflog-amend '((t :foreground "magenta")) 79 "Face for amend commands in reflogs." 80 :group 'magit-faces) 81 82 (defface magit-reflog-merge '((t :foreground "green")) 83 "Face for merge, checkout and branch commands in reflogs." 84 :group 'magit-faces) 85 86 (defface magit-reflog-checkout '((t :foreground "blue")) 87 "Face for checkout commands in reflogs." 88 :group 'magit-faces) 89 90 (defface magit-reflog-reset '((t :foreground "red")) 91 "Face for reset commands in reflogs." 92 :group 'magit-faces) 93 94 (defface magit-reflog-rebase '((t :foreground "magenta")) 95 "Face for rebase commands in reflogs." 96 :group 'magit-faces) 97 98 (defface magit-reflog-cherry-pick '((t :foreground "green")) 99 "Face for cherry-pick commands in reflogs." 100 :group 'magit-faces) 101 102 (defface magit-reflog-remote '((t :foreground "cyan")) 103 "Face for pull and clone commands in reflogs." 104 :group 'magit-faces) 105 106 (defface magit-reflog-other '((t :foreground "cyan")) 107 "Face for other commands in reflogs." 108 :group 'magit-faces) 109 110 ;;; Commands 111 112 ;;;###autoload 113 (defun magit-reflog-current () 114 "Display the reflog of the current branch. 115 If `HEAD' is detached, then show the reflog for that instead." 116 (interactive) 117 (magit-reflog-setup-buffer (or (magit-get-current-branch) "HEAD"))) 118 119 ;;;###autoload 120 (defun magit-reflog-other (ref) 121 "Display the reflog of a branch or another ref." 122 (interactive (list (magit-read-local-branch-or-ref "Show reflog for"))) 123 (magit-reflog-setup-buffer ref)) 124 125 ;;;###autoload 126 (defun magit-reflog-head () 127 "Display the `HEAD' reflog." 128 (interactive) 129 (magit-reflog-setup-buffer "HEAD")) 130 131 ;;; Mode 132 133 (defvar-keymap magit-reflog-mode-map 134 :doc "Keymap for `magit-reflog-mode'." 135 :parent magit-log-mode-map 136 "C-c C-n" #'undefined 137 "L" #'magit-margin-settings) 138 139 (define-derived-mode magit-reflog-mode magit-mode "Magit Reflog" 140 "Mode for looking at Git reflog. 141 142 This mode is documented in info node `(magit)Reflog'. 143 144 \\<magit-mode-map>\ 145 Type \\[magit-refresh] to refresh the current buffer. 146 Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \ 147 to visit the commit at point. 148 149 Type \\[magit-cherry-pick] to apply the commit at point. 150 Type \\[magit-reset] to reset `HEAD' to the commit at point. 151 152 \\{magit-reflog-mode-map}" 153 :interactive nil 154 :group 'magit-log 155 (magit-hack-dir-local-variables) 156 (setq magit--imenu-item-types 'commit)) 157 158 (defun magit-reflog-setup-buffer (ref) 159 (require 'magit) 160 (magit-setup-buffer #'magit-reflog-mode nil 161 (magit-buffer-refname ref) 162 (magit-buffer-log-args (list (format "-n%s" magit-reflog-limit))))) 163 164 (defun magit-reflog-refresh-buffer () 165 (magit-set-header-line-format (concat "Reflog for " magit-buffer-refname)) 166 (magit-insert-section (reflogbuf) 167 (magit-git-wash (apply-partially #'magit-log-wash-log 'reflog) 168 "reflog" "show" "--format=%h%x00%aN%x00%gd%x00%gs" "--date=raw" 169 magit-buffer-log-args magit-buffer-refname "--"))) 170 171 (cl-defmethod magit-buffer-value (&context (major-mode magit-reflog-mode)) 172 magit-buffer-refname) 173 174 (defvar magit-reflog-labels 175 '(("commit" . magit-reflog-commit) 176 ("amend" . magit-reflog-amend) 177 ("merge" . magit-reflog-merge) 178 ("checkout" . magit-reflog-checkout) 179 ("branch" . magit-reflog-checkout) 180 ("reset" . magit-reflog-reset) 181 ("rebase" . magit-reflog-rebase) 182 ("rewritten" . magit-reflog-rebase) 183 ("cherry-pick" . magit-reflog-cherry-pick) 184 ("initial" . magit-reflog-commit) 185 ("pull" . magit-reflog-remote) 186 ("clone" . magit-reflog-remote) 187 ("autosave" . magit-reflog-commit) 188 ("restart" . magit-reflog-reset))) 189 190 (defun magit-reflog-format-subject (subject) 191 (let* ((match (string-match magit-reflog-subject-re subject)) 192 (command (and match (match-string 1 subject))) 193 (option (and match (match-string 2 subject))) 194 (type (and match (match-string 3 subject))) 195 (label (if (string= command "commit") 196 (or type command) 197 command)) 198 (text (if (string= command "commit") 199 label 200 (string-join (delq nil (list command option type)) " ")))) 201 (format "%-16s " 202 (magit--propertize-face 203 text (or (cdr (assoc label magit-reflog-labels)) 204 'magit-reflog-other))))) 205 206 ;;; _ 207 (provide 'magit-reflog) 208 ;;; magit-reflog.el ends here