about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/magit-20180913.1247/magit-subtree.el
blob: b31d0d8b5f1546286e4a2d82c51bcdcfb2647d00 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
;;; magit-subtree.el --- subtree support for Magit  -*- lexical-binding: t -*-

;; Copyright (C) 2011-2018  The Magit Project Contributors
;;
;; You should have received a copy of the AUTHORS.md file which
;; lists all contributors.  If not, see http://magit.vc/authors.

;; Author: Jonas Bernoulli <jonas@bernoul.li>
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>

;; Magit is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; Magit is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Magit.  If not, see http://www.gnu.org/licenses.

;;; Code:

(require 'magit)

;;; Popup

;;;###autoload (autoload 'magit-subtree-popup "magit-subtree" nil t)
(magit-define-popup magit-subtree-popup
  "Popup console for subtree commands."
  :man-page "git-subtree"
  :switches '("Switches for add, merge, push, and pull"
              (?s "Squash" "--squash")
              "Switches for split"
              (?i "Ignore joins" "--ignore-joins")
              (?j "Rejoin"       "--rejoin"))
  :options  '("Options"
              (?p "Prefix" "--prefix=" magit-subtree-read-prefix)
              "Options for add, merge, and pull"
              (?m "Message" "--message=")
              "Options for split"
              (?a "Annotate" "--annotate=")
              (?b "Branch"   "--branch=")
              (?o "Onto"     "--onto=" magit-read-branch-or-commit))
  :actions  '((?a "Add"        magit-subtree-add)
              (?m "Merge"      magit-subtree-merge)
              (?p "Push"       magit-subtree-push)
              (?c "Add commit" magit-subtree-add-commit)
              (?f "Pull"       magit-subtree-pull)
              (?s "Split"      magit-subtree-split))
  :max-action-columns 3)

(defun magit-subtree-read-prefix (prompt &optional default)
  (let* ((insert-default-directory nil)
         (topdir (magit-toplevel))
         (prefix (read-directory-name (concat prompt ": ") topdir default)))
    (if (file-name-absolute-p prefix)
        ;; At least `ido-mode's variant is not compatible.
        (if (string-prefix-p topdir prefix)
            (file-relative-name prefix topdir)
          (user-error "%s isn't inside the repository at %s" prefix topdir))
      prefix)))

;;; Commands

(defun magit-subtree-prefix (prompt)
  (--if-let (--first (string-prefix-p "--prefix=" it)
                     (magit-subtree-arguments))
      (substring it 9)
    (magit-subtree-read-prefix prompt)))

(defun magit-subtree-args ()
  (-filter (lambda (arg)
             (if (eq this-command 'magit-subtree-split)
                 (or (equal arg "--ignore-joins")
                     (equal arg "--rejoin")
                     (string-prefix-p "--annotate=" arg)
                     (string-prefix-p "--branch=" arg)
                     (string-prefix-p "--onto=" arg))
               (or (equal arg "--squash")
                   (and (string-prefix-p "--message=" arg)
                        (not (eq this-command 'magit-subtree-push))))))
           (magit-subtree-arguments)))

(defun magit-git-subtree (subcmd prefix &rest args)
  (magit-run-git-async "subtree" subcmd (concat "--prefix=" prefix) args))

;;;###autoload
(defun magit-subtree-add (prefix repository ref args)
  "Add REF from REPOSITORY as a new subtree at PREFIX."
  (interactive
   (cons (magit-subtree-prefix "Add subtree")
         (let ((remote (magit-read-remote-or-url "From repository")))
           (list remote
                 (magit-read-refspec "Ref" remote)
                 (magit-subtree-args)))))
  (magit-git-subtree "add" prefix args repository ref))

;;;###autoload
(defun magit-subtree-add-commit (prefix commit args)
  "Add COMMIT as a new subtree at PREFIX."
  (interactive (list (magit-subtree-prefix "Add subtree")
                     (magit-read-string-ns "Commit")
                     (magit-subtree-args)))
  (magit-git-subtree "add" prefix args commit))

;;;###autoload
(defun magit-subtree-merge (prefix commit args)
  "Merge COMMIT into the PREFIX subtree."
  (interactive (list (magit-subtree-prefix "Merge into subtree")
                     (magit-read-string-ns "Commit")
                     (magit-subtree-args)))
  (magit-git-subtree "merge" prefix args commit))

;;;###autoload
(defun magit-subtree-pull (prefix repository ref args)
  "Pull REF from REPOSITORY into the PREFIX subtree."
  (interactive
   (cons (magit-subtree-prefix "Pull into subtree")
         (let ((remote (magit-read-remote-or-url "From repository")))
           (list remote
                 (magit-read-refspec "Ref" remote)
                 (magit-subtree-args)))))
  (magit-git-subtree "pull" prefix args repository ref))

;;;###autoload
(defun magit-subtree-push (prefix repository ref args)
  "Extract the history of the subtree PREFIX and push it to REF on REPOSITORY."
  (interactive (list (magit-subtree-prefix "Push subtree")
                     (magit-read-remote-or-url "To repository")
                     (magit-read-string-ns "To reference")
                     (magit-subtree-args)))
  (magit-git-subtree "push" prefix args repository ref))

;;;###autoload
(defun magit-subtree-split (prefix commit args)
  "Extract the history of the subtree PREFIX."
  (interactive (list (magit-subtree-prefix "Split subtree")
                     (magit-read-string-ns "Commit")
                     (magit-subtree-args)))
  (magit-git-subtree "split" prefix args commit))

(provide 'magit-subtree)
;;; magit-subtree.el ends here