magit-notes.el (6857B)
1 ;;; magit-notes.el --- notes support -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2010-2021 The Magit Project Contributors 4 ;; 5 ;; You should have received a copy of the AUTHORS.md file which 6 ;; lists all contributors. If not, see http://magit.vc/authors. 7 8 ;; Author: Jonas Bernoulli <jonas@bernoul.li> 9 ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li> 10 11 ;; SPDX-License-Identifier: GPL-3.0-or-later 12 13 ;; Magit is free software; you can redistribute it and/or modify it 14 ;; under the terms of the GNU General Public License as published by 15 ;; the Free Software Foundation; either version 3, or (at your option) 16 ;; any later version. 17 ;; 18 ;; Magit is distributed in the hope that it will be useful, but WITHOUT 19 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 20 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 21 ;; License for more details. 22 ;; 23 ;; You should have received a copy of the GNU General Public License 24 ;; along with Magit. If not, see http://www.gnu.org/licenses. 25 26 ;;; Commentary: 27 28 ;; This library implements support for `git-notes'. 29 30 ;;; Code: 31 32 (require 'magit) 33 34 ;;; Commands 35 36 ;;;###autoload (autoload 'magit-notes "magit" nil t) 37 (transient-define-prefix magit-notes () 38 "Edit notes attached to commits." 39 :man-page "git-notes" 40 ["Configure local settings" 41 ("c" magit-core.notesRef) 42 ("d" magit-notes.displayRef)] 43 ["Configure global settings" 44 ("C" magit-global-core.notesRef) 45 ("D" magit-global-notes.displayRef)] 46 ["Arguments for prune" 47 :if-not magit-notes-merging-p 48 ("-n" "Dry run" ("-n" "--dry-run"))] 49 ["Arguments for edit and remove" 50 :if-not magit-notes-merging-p 51 (magit-notes:--ref)] 52 ["Arguments for merge" 53 :if-not magit-notes-merging-p 54 (magit-notes:--strategy)] 55 ["Actions" 56 :if-not magit-notes-merging-p 57 ("T" "Edit" magit-notes-edit) 58 ("r" "Remove" magit-notes-remove) 59 ("m" "Merge" magit-notes-merge) 60 ("p" "Prune" magit-notes-prune)] 61 ["Actions" 62 :if magit-notes-merging-p 63 ("c" "Commit merge" magit-notes-merge-commit) 64 ("a" "Abort merge" magit-notes-merge-abort)]) 65 66 (defun magit-notes-merging-p () 67 (let ((dir (magit-git-dir "NOTES_MERGE_WORKTREE"))) 68 (and (file-directory-p dir) 69 (directory-files dir nil "^[^.]")))) 70 71 (transient-define-infix magit-core.notesRef () 72 :class 'magit--git-variable 73 :variable "core.notesRef" 74 :reader 'magit-notes-read-ref 75 :prompt "Set local core.notesRef") 76 77 (transient-define-infix magit-notes.displayRef () 78 :class 'magit--git-variable 79 :variable "notes.displayRef" 80 :multi-value t 81 :reader 'magit-notes-read-refs 82 :prompt "Set local notes.displayRef") 83 84 (transient-define-infix magit-global-core.notesRef () 85 :class 'magit--git-variable 86 :variable "core.notesRef" 87 :reader 'magit-notes-read-ref 88 :prompt "Set global core.notesRef") 89 90 (transient-define-infix magit-global-notes.displayRef () 91 :class 'magit--git-variable 92 :variable "notes.displayRef" 93 :multi-value t 94 :reader 'magit-notes-read-refs 95 :prompt "Set global notes.displayRef") 96 97 (transient-define-argument magit-notes:--ref () 98 :description "Manipulate ref" 99 :class 'transient-option 100 :key "-r" 101 :argument "--ref=" 102 :reader 'magit-notes-read-ref) 103 104 (transient-define-argument magit-notes:--strategy () 105 :description "Merge strategy" 106 :class 'transient-option 107 :shortarg "-s" 108 :argument "--strategy=" 109 :choices '("manual" "ours" "theirs" "union" "cat_sort_uniq")) 110 111 (defun magit-notes-edit (commit &optional ref) 112 "Edit the note attached to COMMIT. 113 REF is the notes ref used to store the notes. 114 115 Interactively or when optional REF is nil use the value of Git 116 variable `core.notesRef' or \"refs/notes/commits\" if that is 117 undefined." 118 (interactive (magit-notes-read-args "Edit notes")) 119 (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref)) 120 "edit" commit)) 121 122 (defun magit-notes-remove (commit &optional ref) 123 "Remove the note attached to COMMIT. 124 REF is the notes ref from which the note is removed. 125 126 Interactively or when optional REF is nil use the value of Git 127 variable `core.notesRef' or \"refs/notes/commits\" if that is 128 undefined." 129 (interactive (magit-notes-read-args "Remove notes")) 130 (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref)) 131 "remove" commit)) 132 133 (defun magit-notes-merge (ref) 134 "Merge the notes ref REF into the current notes ref. 135 136 The current notes ref is the value of Git variable 137 `core.notesRef' or \"refs/notes/commits\" if that is undefined. 138 139 When there are conflicts, then they have to be resolved in the 140 temporary worktree \".git/NOTES_MERGE_WORKTREE\". When 141 done use `magit-notes-merge-commit' to finish. To abort 142 use `magit-notes-merge-abort'." 143 (interactive (list (magit-read-string-ns "Merge reference"))) 144 (magit-run-git-with-editor "notes" "merge" ref)) 145 146 (defun magit-notes-merge-commit () 147 "Commit the current notes ref merge. 148 Also see `magit-notes-merge'." 149 (interactive) 150 (magit-run-git-with-editor "notes" "merge" "--commit")) 151 152 (defun magit-notes-merge-abort () 153 "Abort the current notes ref merge. 154 Also see `magit-notes-merge'." 155 (interactive) 156 (magit-run-git-with-editor "notes" "merge" "--abort")) 157 158 (defun magit-notes-prune (&optional dry-run) 159 "Remove notes about unreachable commits." 160 (interactive (list (and (member "--dry-run" (transient-args 'magit-notes)) t))) 161 (when dry-run 162 (magit-process-buffer)) 163 (magit-run-git-with-editor "notes" "prune" (and dry-run "--dry-run"))) 164 165 ;;; Readers 166 167 (defun magit-notes-read-ref (prompt _initial-input history) 168 (--when-let (magit-completing-read 169 prompt (magit-list-notes-refnames) nil nil 170 (--when-let (magit-get "core.notesRef") 171 (if (string-prefix-p "refs/notes/" it) 172 (substring it 11) 173 it)) 174 history) 175 (if (string-prefix-p "refs/" it) 176 it 177 (concat "refs/notes/" it)))) 178 179 (defun magit-notes-read-refs (prompt &optional _initial-input _history) 180 (mapcar (lambda (ref) 181 (if (string-prefix-p "refs/" ref) 182 ref 183 (concat "refs/notes/" ref))) 184 (completing-read-multiple 185 (concat prompt ": ") 186 (magit-list-notes-refnames) nil nil 187 (mapconcat (lambda (ref) 188 (if (string-prefix-p "refs/notes/" ref) 189 (substring ref 11) 190 ref)) 191 (magit-get-all "notes.displayRef") 192 ",")))) 193 194 (defun magit-notes-read-args (prompt) 195 (list (magit-read-branch-or-commit prompt (magit-stash-at-point)) 196 (--when-let (--first (string-match "^--ref=\\(.+\\)" it) 197 (transient-args 'magit-notes)) 198 (match-string 1 it)))) 199 200 ;;; _ 201 (provide 'magit-notes) 202 ;;; magit-notes.el ends here