forked from magit/magit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
magit-cherry.el
108 lines (91 loc) · 4.05 KB
/
magit-cherry.el
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
;;; magit-cherry.el --- "git cherry" support for Magit
;; Copyright (C) 2013 The Magit Project Developers.
;;
;; For a full list of contributors, see the AUTHORS.md file
;; at the top-level directory of this distribution and at
;; https://raw.github.com/magit/magit/master/AUTHORS.md
;; Author: Moritz Bunkus <moritz@bunkus.org>
;; 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/>.
;;; Commentary:
;; Control git-cherry from Magit.
;;; Code:
(require 'magit)
(defvar magit--cherry-buffer-name "*magit-cherry*")
(define-derived-mode magit-cherry-mode magit-mode "Magit Cherry"
"Magit Cherry")
(magit-define-command cherry (upstream head)
(interactive
(let ((branch (or (magit-get-current-branch)
(error "Don't cherry on a detached head."))))
(list (magit-read-rev "Cherry upstream"
(magit-format-ref
(magit-remote-branch-for branch t)))
(magit-read-rev "Cherry head" branch))))
(let ((topdir (magit-get-top-dir default-directory)))
(magit-buffer-switch magit--cherry-buffer-name)
(magit-mode-init topdir
#'magit-cherry-mode
#'magit--refresh-cherry-buffer
upstream
head)))
(defun magit--refresh-cherry-buffer (cherry-upstream cherry-head)
(magit-create-buffer-sections
(let ((branch-head (magit-format-commit "HEAD" "%h %s")))
(insert-before-markers
(format "Repository: %s %s\n"
(propertize (magit-get-current-branch) 'face 'magit-branch)
(abbreviate-file-name default-directory))
(format "Branch head: %s\n" (or branch-head "nothing committed (yet)"))
"\n"
(format "%s means: equivalent exists in '%s'\n"
(propertize " - " 'face 'magit-diff-del)
cherry-upstream)
(format "%s means: only exists in '%s'\n"
(propertize " + " 'face 'magit-diff-add)
cherry-head)
"\n"
(propertize "Cherry commits:" 'face 'magit-section-title) "\n"))
(magit-git-section 'commit nil 'magit--wash-cherry-output
"cherry" "-v" cherry-upstream cherry-head)))
;;; Format of "git cherry -v ..." output:
;;+ 8927349872a908bf hello world
;;- 098340983094fffa chunky bacon
(defun magit--wash-cherry-output ()
(while (looking-at "^\\(\\+\\|-\\) +\\([0-9a-f]+ *\\)")
(let* ((summary-start (match-end 2))
(direction (match-string 1))
(revision (replace-regexp-in-string " +" "" (match-string 2))))
;; Delete direction mark and revision before reconstructing
;; them.
(beginning-of-line)
(delete-region (point) summary-start)
;; Re-create output and propertize properly.
(insert (propertize (concat " " direction " ")
'face (if (string= direction "+")
'magit-diff-add
'magit-diff-del))
" "
(propertize revision 'face 'magit-log-sha1)
" ")
;; Set section info to commit's SHA
(let ((section (magit-set-section revision 'commit
(line-beginning-position)
(min (1+ (line-end-position))
(point-max)))))
(magit-set-section-info revision section))
;; Go to beginning of next line.
(beginning-of-line)
(forward-line))))
(provide 'magit-cherry)
;;; magit-cherry.el ends here