config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

magit-notes.el (6874B)


      1 ;;; magit-notes.el --- Notes support  -*- 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 `git-notes'.
     26 
     27 ;;; Code:
     28 
     29 (require 'magit)
     30 
     31 ;;; Commands
     32 
     33 ;;;###autoload (autoload 'magit-notes "magit" nil t)
     34 (transient-define-prefix magit-notes ()
     35   "Edit notes attached to commits."
     36   :man-page "git-notes"
     37   ["Configure local settings"
     38    ("c" magit-core.notesRef)
     39    ("d" magit-notes.displayRef)]
     40   ["Configure global settings"
     41    ("C" magit-global-core.notesRef)
     42    ("D" magit-global-notes.displayRef)]
     43   ["Arguments for prune"
     44    :if-not magit-notes-merging-p
     45    ("-n" "Dry run" ("-n" "--dry-run"))]
     46   ["Arguments for edit and remove"
     47    :if-not magit-notes-merging-p
     48    (magit-notes:--ref)]
     49   ["Arguments for merge"
     50    :if-not magit-notes-merging-p
     51    (magit-notes:--strategy)]
     52   ["Actions"
     53    :if-not magit-notes-merging-p
     54    ("T" "Edit"         magit-notes-edit)
     55    ("r" "Remove"       magit-notes-remove)
     56    ("m" "Merge"        magit-notes-merge)
     57    ("p" "Prune"        magit-notes-prune)]
     58   ["Actions"
     59    :if magit-notes-merging-p
     60    ("c" "Commit merge" magit-notes-merge-commit)
     61    ("a" "Abort merge"  magit-notes-merge-abort)])
     62 
     63 (defun magit-notes-merging-p ()
     64   (let ((dir (expand-file-name "NOTES_MERGE_WORKTREE" (magit-gitdir))))
     65     (and (file-directory-p dir)
     66          (directory-files dir nil "\\`[^.]"))))
     67 
     68 (transient-define-infix magit-core.notesRef ()
     69   :class 'magit--git-variable
     70   :variable "core.notesRef"
     71   :reader #'magit-notes-read-ref
     72   :prompt "Set local core.notesRef")
     73 
     74 (transient-define-infix magit-notes.displayRef ()
     75   :class 'magit--git-variable
     76   :variable "notes.displayRef"
     77   :multi-value t
     78   :reader #'magit-notes-read-refs
     79   :prompt "Set local notes.displayRef")
     80 
     81 (transient-define-infix magit-global-core.notesRef ()
     82   :class 'magit--git-variable
     83   :variable "core.notesRef"
     84   :global t
     85   :reader #'magit-notes-read-ref
     86   :prompt "Set global core.notesRef")
     87 
     88 (transient-define-infix magit-global-notes.displayRef ()
     89   :class 'magit--git-variable
     90   :variable "notes.displayRef"
     91   :global t
     92   :multi-value t
     93   :reader #'magit-notes-read-refs
     94   :prompt "Set global notes.displayRef")
     95 
     96 (transient-define-argument magit-notes:--ref ()
     97   :description "Manipulate ref"
     98   :class 'transient-option
     99   :key "-r"
    100   :argument "--ref="
    101   :reader #'magit-notes-read-ref)
    102 
    103 (transient-define-argument magit-notes:--strategy ()
    104   :description "Merge strategy"
    105   :class 'transient-option
    106   :shortarg "-s"
    107   :argument "--strategy="
    108   :choices '("manual" "ours" "theirs" "union" "cat_sort_uniq"))
    109 
    110 (defun magit-notes-edit (commit &optional ref)
    111   "Edit the note attached to COMMIT.
    112 REF is the notes ref used to store the notes.
    113 
    114 Interactively or when optional REF is nil use the value of Git
    115 variable `core.notesRef' or \"refs/notes/commits\" if that is
    116 undefined."
    117   (interactive (magit-notes-read-args "Edit notes"))
    118   (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref))
    119                              "edit" commit))
    120 
    121 (defun magit-notes-remove (commit &optional ref)
    122   "Remove the note attached to COMMIT.
    123 REF is the notes ref from which the note is removed.
    124 
    125 Interactively or when optional REF is nil use the value of Git
    126 variable `core.notesRef' or \"refs/notes/commits\" if that is
    127 undefined."
    128   (interactive (magit-notes-read-args "Remove notes"))
    129   (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref))
    130                              "remove" commit))
    131 
    132 (defun magit-notes-merge (ref)
    133   "Merge the notes ref REF into the current notes ref.
    134 
    135 The current notes ref is the value of Git variable
    136 `core.notesRef' or \"refs/notes/commits\" if that is undefined.
    137 
    138 When there are conflicts, then they have to be resolved in the
    139 temporary worktree \".git/NOTES_MERGE_WORKTREE\".  When
    140 done use `magit-notes-merge-commit' to finish.  To abort
    141 use `magit-notes-merge-abort'."
    142   (interactive (list (magit-read-string-ns "Merge reference")))
    143   (magit-run-git-with-editor "notes" "merge" ref))
    144 
    145 (defun magit-notes-merge-commit ()
    146   "Commit the current notes ref merge.
    147 Also see `magit-notes-merge'."
    148   (interactive)
    149   (magit-run-git-with-editor "notes" "merge" "--commit"))
    150 
    151 (defun magit-notes-merge-abort ()
    152   "Abort the current notes ref merge.
    153 Also see `magit-notes-merge'."
    154   (interactive)
    155   (magit-run-git-with-editor "notes" "merge" "--abort"))
    156 
    157 (defun magit-notes-prune (&optional dry-run)
    158   "Remove notes about unreachable commits."
    159   (interactive (list (and (member "--dry-run" (transient-args 'magit-notes)) t)))
    160   (when dry-run
    161     (magit-process-buffer))
    162   (magit-run-git-with-editor "notes" "prune" (and dry-run "--dry-run")))
    163 
    164 ;;; Readers
    165 
    166 (defun magit-notes-read-ref (prompt _initial-input history)
    167   (and-let* ((ref (magit-completing-read
    168                    prompt (magit-list-notes-refnames) nil nil
    169                    (and-let* ((def (magit-get "core.notesRef")))
    170                      (if (string-prefix-p "refs/notes/" def)
    171                          (substring def 11)
    172                        def))
    173                    history)))
    174     (if (string-prefix-p "refs/" ref)
    175         ref
    176       (concat "refs/notes/" ref))))
    177 
    178 (defun magit-notes-read-refs (prompt &optional _initial-input _history)
    179   (mapcar (lambda (ref)
    180             (if (string-prefix-p "refs/" ref)
    181                 ref
    182               (concat "refs/notes/" ref)))
    183           (completing-read-multiple
    184            (concat prompt ": ")
    185            (magit-list-notes-refnames) nil nil
    186            (mapconcat (lambda (ref)
    187                         (if (string-prefix-p "refs/notes/" ref)
    188                             (substring ref 11)
    189                           ref))
    190                       (magit-get-all "notes.displayRef")
    191                       ","))))
    192 
    193 (defun magit-notes-read-args (prompt)
    194   (list (magit-read-branch-or-commit prompt (magit-stash-at-point))
    195         (and-let* ((str (--first (string-match "^--ref=\\(.+\\)" it)
    196                                  (transient-args 'magit-notes))))
    197           (match-string 1 str))))
    198 
    199 ;;; _
    200 (provide 'magit-notes)
    201 ;;; magit-notes.el ends here