Browse files

upgrade magit

  • Loading branch information...
1 parent 6ca9b3f commit 5247e6c6527b3585d655a9743c0bcd435d4418d1 @bleything committed Oct 28, 2012
View
83 elpa/magit-1.1.1/magit-autoloads.el
@@ -1,83 +0,0 @@
-;;; magit-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-
-;;;### (autoloads (magit-status) "magit" "magit.el" (20287 63976))
-;;; Generated autoloads from magit.el
-
-(autoload 'magit-status "magit" "\
-Open a Magit status buffer for the Git repository containing
-DIR. If DIR is not within a Git repository, offer to create a
-Git repository in DIR.
-
-Interactively, a prefix argument means to ask the user which Git
-repository to use even if `default-directory' is under Git control.
-Two prefix arguments means to ignore `magit-repo-dirs' when asking for
-user input.
-
-\(fn DIR)" t nil)
-
-;;;***
-
-;;;### (autoloads (turn-on-magit-stgit magit-stgit-mode) "magit-stgit"
-;;;;;; "magit-stgit.el" (20287 63976))
-;;; Generated autoloads from magit-stgit.el
-
-(autoload 'magit-stgit-mode "magit-stgit" "\
-StGit support for Magit
-
-\(fn &optional ARG)" t nil)
-
-(autoload 'turn-on-magit-stgit "magit-stgit" "\
-Unconditionally turn on `magit-stgit-mode'.
-
-\(fn)" nil nil)
-
-;;;***
-
-;;;### (autoloads (turn-on-magit-svn magit-svn-mode) "magit-svn"
-;;;;;; "magit-svn.el" (20287 63976))
-;;; Generated autoloads from magit-svn.el
-
-(autoload 'magit-svn-mode "magit-svn" "\
-SVN support for Magit
-
-\(fn &optional ARG)" t nil)
-
-(autoload 'turn-on-magit-svn "magit-svn" "\
-Unconditionally turn on `magit-svn-mode'.
-
-\(fn)" nil nil)
-
-;;;***
-
-;;;### (autoloads (turn-on-magit-topgit magit-topgit-mode) "magit-topgit"
-;;;;;; "magit-topgit.el" (20287 63976))
-;;; Generated autoloads from magit-topgit.el
-
-(autoload 'magit-topgit-mode "magit-topgit" "\
-Topgit support for Magit
-
-\(fn &optional ARG)" t nil)
-
-(autoload 'turn-on-magit-topgit "magit-topgit" "\
-Unconditionally turn on `magit-topgit-mode'.
-
-\(fn)" nil nil)
-
-;;;***
-
-;;;### (autoloads nil nil ("magit-bisect.el" "magit-key-mode.el"
-;;;;;; "magit-pkg.el") (20287 63976 383848))
-
-;;;***
-
-(provide 'magit-autoloads)
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; magit-autoloads.el ends here
View
1 elpa/magit-1.1.1/magit-pkg.el
@@ -1 +0,0 @@
-(define-package "magit" "1.1.1" "Control Git from Emacs.")
View
18 elpa/magit-1.2.0/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Magit: (magit). Using Git from Emacs with Magit.
View
164 elpa/magit-1.2.0/magit-autoloads.el
@@ -0,0 +1,164 @@
+;;; magit-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+
+;;;### (autoloads (magit-status) "magit" "magit.el" (20585 57328
+;;;;;; 0 0))
+;;; Generated autoloads from magit.el
+
+(autoload 'magit-status "magit" "\
+Open a Magit status buffer for the Git repository containing
+DIR. If DIR is not within a Git repository, offer to create a
+Git repository in DIR.
+
+Interactively, a prefix argument means to ask the user which Git
+repository to use even if `default-directory' is under Git control.
+Two prefix arguments means to ignore `magit-repo-dirs' when asking for
+user input.
+
+\(fn DIR)" t nil)
+
+;;;***
+
+;;;### (autoloads (magit-blame-mode) "magit-blame" "magit-blame.el"
+;;;;;; (20585 57328 0 0))
+;;; Generated autoloads from magit-blame.el
+
+(autoload 'magit-blame-mode "magit-blame" "\
+Display blame information inline.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (turn-on-magit-stgit magit-stgit-mode) "magit-stgit"
+;;;;;; "magit-stgit.el" (20585 57328 0 0))
+;;; Generated autoloads from magit-stgit.el
+
+(autoload 'magit-stgit-mode "magit-stgit" "\
+StGit support for Magit
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-magit-stgit "magit-stgit" "\
+Unconditionally turn on `magit-stgit-mode'.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (turn-on-magit-svn magit-svn-mode) "magit-svn"
+;;;;;; "magit-svn.el" (20585 57328 0 0))
+;;; Generated autoloads from magit-svn.el
+
+(autoload 'magit-svn-mode "magit-svn" "\
+SVN support for Magit
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-magit-svn "magit-svn" "\
+Unconditionally turn on `magit-svn-mode'.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (turn-on-magit-topgit magit-topgit-mode) "magit-topgit"
+;;;;;; "magit-topgit.el" (20585 57328 0 0))
+;;; Generated autoloads from magit-topgit.el
+
+(autoload 'magit-topgit-mode "magit-topgit" "\
+Topgit support for Magit
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-magit-topgit "magit-topgit" "\
+Unconditionally turn on `magit-topgit-mode'.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads (global-magit-wip-save-mode magit-wip-save-mode
+;;;;;; magit-wip-mode) "magit-wip" "magit-wip.el" (20585 57328 0
+;;;;;; 0))
+;;; Generated autoloads from magit-wip.el
+
+(defvar magit-wip-mode nil "\
+Non-nil if Magit-Wip mode is enabled.
+See the command `magit-wip-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-wip-mode'.")
+
+(custom-autoload 'magit-wip-mode "magit-wip" nil)
+
+(autoload 'magit-wip-mode "magit-wip" "\
+In Magit log buffers; give wip refs a special appearance.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'magit-wip-save-mode "magit-wip" "\
+Magit support for committing to a work-in-progress ref.
+
+When this minor mode is turned on and a file is saved inside a writable
+git repository then it is also committed to a special work-in-progress
+ref.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-magit-wip-save-mode nil "\
+Non-nil if Global-Magit-Wip-Save mode is enabled.
+See the command `global-magit-wip-save-mode' for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-magit-wip-save-mode'.")
+
+(custom-autoload 'global-magit-wip-save-mode "magit-wip" nil)
+
+(autoload 'global-magit-wip-save-mode "magit-wip" "\
+Toggle Magit-Wip-Save mode in all buffers.
+With prefix ARG, enable Global-Magit-Wip-Save mode if ARG is positive;
+otherwise, disable it. If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Magit-Wip-Save mode is enabled in all buffers where
+`turn-on-magit-wip-save' would do it.
+See `magit-wip-save-mode' for more information on Magit-Wip-Save mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads (rebase-mode) "rebase-mode" "rebase-mode.el" (20585
+;;;;;; 57328 0 0))
+;;; Generated autoloads from rebase-mode.el
+
+(autoload 'rebase-mode "rebase-mode" "\
+Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'. They describe how Git should perform
+the rebase. See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("git-rebase-todo" . rebase-mode))
+
+;;;***
+
+;;;### (autoloads nil nil ("magit-bisect.el" "magit-key-mode.el"
+;;;;;; "magit-pkg.el") (20585 57328 470027 0))
+
+;;;***
+
+(provide 'magit-autoloads)
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; magit-autoloads.el ends here
View
5 elpa/magit-1.1.1/magit-bisect.el → elpa/magit-1.2.0/magit-bisect.el
@@ -10,8 +10,7 @@
"Return t if a bisect session is running.
If REQUIRED-STATUS is not nil then the current status must also
match REQUIRED-STATUS."
- (and (file-exists-p (concat (magit-get-top-dir default-directory)
- ".git/BISECT_LOG"))
+ (and (file-exists-p (concat (magit-git-dir) "BISECT_LOG"))
(or (not required-status)
(eq (plist-get (magit--bisect-info) :status)
required-status))))
@@ -137,7 +136,7 @@ match REQUIRED-STATUS."
(with-temp-buffer
(insert "#!/bin/sh\n" command "\n")
(write-region (point-min) (point-max) file))
- (chmod file #o755)
+ (set-file-modes file #o755)
(magit-run-git-async "bisect" "run" file)
(magit-display-process)
(setq buffer (get-buffer magit-process-buffer-name))
View
303 elpa/magit-1.2.0/magit-blame.el
@@ -0,0 +1,303 @@
+;;; magit-blame.el --- blame support for magit
+
+;; Copyright (C) 2012 Rüdiger Sonderfeld
+;; Copyright (C) 2012 Yann Hodique
+;; Copyright (C) 2011 byplayer
+;; Copyright (C) 2010 Alexander Prusov
+;; Copyright (C) 2009 Tim Moore
+;; Copyright (C) 2008 Linh Dang
+;; Copyright (C) 2008 Marius Vollmer
+
+;; Author: Yann Hodique <yann.hodique@gmail.com>
+;; Keywords:
+
+;; 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:
+
+;; This code has been backported from Egg (Magit fork) to Magit
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'magit)
+
+(defface magit-blame-header
+ '((t :inherit magit-header))
+ "Face for blame header."
+ :group 'magit-faces)
+
+(defface magit-blame-sha1
+ '((t :inherit (magit-log-sha1
+ magit-blame-header)))
+ "Face for blame sha1."
+ :group 'magit-faces)
+
+(defface magit-blame-culprit
+ '((t :inherit magit-blame-header))
+ "Face for blame culprit."
+ :group 'magit-faces)
+
+(defface magit-blame-time
+ '((t :inherit magit-blame-header))
+ "Face for blame time."
+ :group 'magit-faces)
+
+(defface magit-blame-subject
+ '((t :inherit (magit-log-message magit-blame-header)))
+ "Face for blame tag line."
+ :group 'magit-faces)
+
+(defconst magit-blame-map
+ (let ((map (make-sparse-keymap "Magit:Blame")))
+ (define-key map (kbd "l") 'magit-blame-locate-commit)
+ (define-key map (kbd "RET") 'magit-blame-locate-commit)
+ (define-key map (kbd "q") 'magit-blame-mode)
+ (define-key map (kbd "n") 'magit-blame-next-chunk)
+ (define-key map (kbd "p") 'magit-blame-previous-chunk)
+ map)
+ "Keymap for an annotated section.\\{magit-blame-map}")
+
+(defvar magit-blame-buffer-read-only)
+(make-variable-buffer-local 'magit-blame-buffer-read-only)
+
+;;;###autoload
+(define-minor-mode magit-blame-mode
+ "Display blame information inline."
+ :keymap magit-blame-map
+ :lighter " blame"
+ (unless (buffer-file-name)
+ (error "Current buffer has no associated file!"))
+ (when (and (buffer-modified-p)
+ (y-or-n-p (format "save %s first? " (buffer-file-name))))
+ (save-buffer))
+
+ (if magit-blame-mode
+ (progn
+ (setq magit-blame-buffer-read-only buffer-read-only)
+ (magit-blame-file-on (current-buffer))
+ (set-buffer-modified-p nil)
+ (setq buffer-read-only t))
+ (magit-blame-file-off (current-buffer))
+ (set-buffer-modified-p nil)
+ (setq buffer-read-only magit-blame-buffer-read-only)))
+
+(defun magit-blame-file-off (buffer)
+ (save-excursion
+ (save-restriction
+ (with-current-buffer buffer
+ (widen)
+ (mapc (lambda (ov)
+ (if (overlay-get ov :blame)
+ (delete-overlay ov)))
+ (overlays-in (point-min) (point-max)))))))
+
+(defun magit-blame-file-on (buffer)
+ (magit-blame-file-off buffer)
+ (save-excursion
+ (with-current-buffer buffer
+ (save-restriction
+ (with-temp-buffer
+ (magit-git-insert (list "blame" "--porcelain" "--"
+ (file-name-nondirectory
+ (buffer-file-name buffer))))
+ (magit-blame-parse buffer (current-buffer)))))))
+
+(defun magit-blame-locate-commit (pos)
+ "Jump to a commit in the branch history from an annotated blame section."
+ (interactive "d")
+ (let ((overlays (overlays-at pos))
+ sha1)
+ (dolist (ov overlays)
+ (if (overlay-get ov :blame)
+ (setq sha1 (plist-get (nth 3 (overlay-get ov :blame)) :sha1))))
+ (if sha1
+ (magit-show-commit sha1))))
+
+(defun magit-find-next-overlay-change (BEG END PROP)
+ "Return the next position after BEG where an overlay matching a
+property PROP starts or ends. If there are no matching overlay
+boundaries from BEG to END, the return value is nil."
+ (save-excursion
+ (goto-char BEG)
+ (catch 'found
+ (flet ((overlay-change (pos)
+ (if (< BEG END) (next-overlay-change pos)
+ (previous-overlay-change pos)))
+ (within-bounds-p (pos)
+ (if (< BEG END) (< pos END)
+ (> pos END))))
+ (let ((ov-pos BEG))
+ ;; iterate through overlay changes from BEG to END
+ (while (within-bounds-p ov-pos)
+ (let* ((next-ov-pos (overlay-change ov-pos))
+ ;; search for an overlay with a PROP property
+ (next-ov
+ (let ((overlays (overlays-at next-ov-pos)))
+ (while (and overlays
+ (not (overlay-get (car overlays) PROP)))
+ (setq overlays (cdr overlays)))
+ (car overlays))))
+ (if next-ov
+ ;; found the next overlay with prop PROP at next-ov-pos
+ (throw 'found next-ov-pos)
+ ;; no matching overlay found, keep looking
+ (setq ov-pos next-ov-pos)))))))))
+
+(defun magit-blame-next-chunk (pos)
+ "Go to the next blame chunk."
+ (interactive "d")
+ (let ((next-chunk-pos (magit-find-next-overlay-change pos (point-max) :blame)))
+ (when next-chunk-pos
+ (goto-char next-chunk-pos))))
+
+(defun magit-blame-previous-chunk (pos)
+ "Go to the previous blame chunk."
+ (interactive "d")
+ (let ((prev-chunk-pos (magit-find-next-overlay-change pos (point-min) :blame)))
+ (when prev-chunk-pos
+ (goto-char prev-chunk-pos))))
+
+(defcustom magit-time-format-string "%Y-%m-%dT%T%z"
+ "How to format time in magit-blame header."
+ :group 'magit
+ :type 'string)
+
+(defun magit-blame-decode-time (unixtime &optional tz)
+ "Decode UNIXTIME into (HIGH LOW) format.
+
+The second argument TZ can be used to add the timezone in (-)HHMM
+format to UNIXTIME. UNIXTIME should be either a number
+containing seconds since epoch or Emacs's (HIGH LOW
+. IGNORED) format."
+ (when (numberp tz)
+ (unless (numberp unixtime)
+ (setq unixtime (float-time unixtime)))
+ (let* ((ptz (abs tz))
+ (min (+ (* (/ ptz 100) 60)
+ (mod ptz 100))))
+ (setq unixtime (+ (* (if (< tz 0) (- min) min) 60) unixtime))))
+
+ (when (numberp unixtime)
+ (setq unixtime (seconds-to-time unixtime)))
+ unixtime)
+
+(defun magit-blame-format-time-string (format &optional unixtime tz)
+ "Use FORMAT to format the time UNIXTIME, or now if omitted.
+
+UNIXTIME is specified as a number containing seconds since epoch
+or Emacs's (HIGH LOW . IGNORED) format. The optional argument TZ
+can be used to set the time zone. If TZ is a number it is
+treated as a (-)HHMM offset to Universal Time. If TZ is not
+a number and non-nil the time is printed in UTC. If TZ is nil
+the local zime zone is used. The format of the function is
+similar to `format-time-string' except for %Z which is not
+officially supported at the moment."
+ (unless unixtime
+ (setq unixtime (current-time)))
+ (when (numberp tz) ;; TODO add support for %Z
+ (setq format (replace-regexp-in-string "%z" (format "%+05d" tz) format)))
+ (format-time-string format (magit-blame-decode-time unixtime tz) tz))
+
+(defun magit-blame-parse (target-buf blame-buf)
+ "Parse blame-info in buffer BLAME-BUF and decorate TARGET-BUF buffer."
+ (save-match-data
+ (let ((blank (propertize " " 'face 'magit-blame-header))
+ (nl (propertize "\n" 'face 'magit-blame-header))
+ (commit-hash (make-hash-table :test 'equal :size 577))
+ commit commit-info old-line new-line num old-file subject author
+ author-time author-timezone info ov beg end blame)
+ (with-current-buffer blame-buf
+ (goto-char (point-min))
+ ;; search for a ful commit info
+ (while (re-search-forward "^\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)$" nil t)
+ (setq commit (match-string-no-properties 1)
+ old-line (string-to-number
+ (match-string-no-properties 2))
+ new-line (string-to-number
+ (match-string-no-properties 3))
+ num (string-to-number
+ (match-string-no-properties 4)))
+ ;; was this commit already seen (and stored in the hash)?
+ (setq commit-info (gethash commit commit-hash))
+ ;; Nope, this is the 1st time, the full commit-info follow.
+ (unless commit-info
+ (re-search-forward "^author \\(.+\\)$")
+ (setq author (match-string-no-properties 1))
+ (re-search-forward "^author-time \\(.+\\)$")
+ (setq author-time (string-to-number
+ (match-string-no-properties 1)))
+ (re-search-forward "^author-tz \\(.+\\)$")
+ (setq author-timezone (string-to-number
+ (match-string-no-properties 1)))
+ (re-search-forward "^summary \\(.+\\)$")
+ (setq subject (match-string-no-properties 1))
+ (re-search-forward "^filename \\(.+\\)$")
+ (setq old-file (match-string-no-properties 1))
+ (setq commit-info (list :sha1 commit :author author
+ :author-time author-time
+ :author-timezone author-timezone
+ :subject subject :file old-file))
+ ;; save it in the hash
+ (puthash commit commit-info commit-hash))
+ ;; add the current blame-block into the list INFO.
+ (setq info (cons (list old-line new-line num commit-info)
+ info))))
+ ;; now do from beginning
+ (setq info (nreverse info))
+ (with-current-buffer target-buf
+ ;; for every blame chunk
+ (dolist (chunk info)
+ (setq commit-info (nth 3 chunk)
+ old-line (nth 0 chunk)
+ new-line (nth 1 chunk)
+ num (nth 2 chunk)
+ commit (plist-get commit-info :sha1)
+ author (plist-get commit-info :author)
+ author-time (plist-get commit-info :author-time)
+ author-timezone (plist-get commit-info :author-timezone)
+ subject (plist-get commit-info :subject))
+
+ (goto-char (point-min))
+ (forward-line (1- new-line))
+
+ (setq beg (line-beginning-position)
+ end (save-excursion
+ (forward-line num)
+ (line-beginning-position)))
+ ;; mark the blame chunk
+ (put-text-property beg end :blame chunk)
+
+ ;; make an overlay with blame info as 'before-string
+ ;; on the current chunk.
+ (setq ov (make-overlay beg end))
+ (overlay-put ov :blame chunk)
+ (setq blame (concat
+ (propertize (substring-no-properties commit 0 8)
+ 'face 'magit-blame-sha1)
+ blank
+ (propertize (format "%-20s" author)
+ 'face 'magit-blame-culprit)
+ blank
+ (propertize (magit-blame-format-time-string
+ magit-time-format-string
+ author-time author-timezone)
+ 'face 'magit-blame-time)
+ blank
+ (propertize subject 'face 'magit-blame-subject)
+ blank nl))
+ (overlay-put ov 'before-string blame))))))
+
+(provide 'magit-blame)
+;;; magit-blame.el ends here
View
153 elpa/magit-1.1.1/magit-key-mode.el → elpa/magit-1.2.0/magit-key-mode.el
@@ -1,6 +1,5 @@
(require 'magit)
-(require 'assoc)
(eval-when-compile (require 'cl))
(defvar magit-key-mode-key-maps '()
@@ -82,13 +81,20 @@
(branching
(man-page "git-branch")
(actions
- ("v" "Branch manager" magit-show-branches)
- ("n" "New" magit-create-branch)
- ("m" "Move" magit-move-branch)
- ("d" "Delete" magit-delete-branch)
- ("D" "Force Delete" magit-delete-branch-forced)
+ ("v" "Branch manager" magit-branch-manager)
+ ("c" "Create" magit-create-branch)
+ ("r" "Rename" magit-move-branch)
+ ("k" "Delete" magit-delete-branch)
("b" "Checkout" magit-checkout)))
+ (remoting
+ (man-page "git-remote")
+ (actions
+ ("v" "Branch manager" magit-branch-manager)
+ ("a" "Add" magit-add-remote)
+ ("r" "Rename" magit-rename-remote)
+ ("k" "Remove" magit-remove-remote)))
+
(tagging
(man-page "git-tag")
(actions
@@ -103,16 +109,17 @@
("z" "Save" magit-stash)
("s" "Snapshot" magit-stash-snapshot))
(switches
- ("-k" "Keep index" "--keep-index")))
+ ("-k" "Keep index" "--keep-index")
+ ("-u" "Include untracked files" "--include-untracked")
+ ("-a" "Include all files" "--all")))
(merging
(man-page "git-merge")
(actions
- ("m" "Merge" magit-merge))
+ ("m" "Merge" magit-manual-merge))
(switches
("-ff" "Fast-forward only" "--ff-only")
("-nf" "No fast-forward" "--no-ff")
- ("-nc" "No commit" "--no-commit")
("-sq" "Squash" "--squash"))
(arguments
("-st" "Strategy" "--strategy=" read-from-minibuffer)))
@@ -169,7 +176,7 @@ and put in its place an empty one of the same name."
(when (assoc group magit-key-mode-groups)
(magit-key-mode-delete-group group))
(setq magit-key-mode-groups
- (cons (list group '(actions)) magit-key-mode-groups)))
+ (cons (list group (list 'actions)) magit-key-mode-groups)))
(defun magit-key-mode-key-defined-p (for-group key)
"If KEY is defined as any of switch, argument or action within
@@ -244,6 +251,17 @@ FOR-GROUP."
(error "Nothing at point to do.")))
(def (lookup-key (current-local-map) key)))
(call-interactively def)))
+(defun magit-key-mode-jump-to-next-exec ()
+ "Jump to the next action/args/option point."
+ (interactive)
+ (let* ((oldp (point))
+ (old (get-text-property oldp 'key-group-executor))
+ (p (if (= oldp (point-max)) (point-min) (1+ oldp))))
+ (while (let ((new (get-text-property p 'key-group-executor)))
+ (and (not (= p oldp)) (or (not new) (eq new old))))
+ (setq p (if (= p (point-max)) (point-min) (1+ p))))
+ (goto-char p)
+ (skip-chars-forward " ")))
(defun magit-key-mode-build-keymap (for-group)
"Construct a normal looking keymap for the key mode to use and
@@ -256,6 +274,8 @@ put it in magit-key-mode-key-maps for fast lookup."
(suppress-keymap map 'nodigits)
;; ret dwim
(define-key map (kbd "RET") 'magit-key-mode-exec-at-point)
+ ;; tab jumps to the next "button"
+ (define-key map (kbd "TAB") 'magit-key-mode-jump-to-next-exec)
;; all maps should `quit' with `C-g' or `q'
(define-key map (kbd "C-g") `(lambda ()
@@ -289,7 +309,7 @@ put it in magit-key-mode-key-maps for fast lookup."
(defkey k `(magit-key-mode-add-argument
',for-group ,(nth 2 k) ',(nth 3 k))))))
- (aput 'magit-key-mode-key-maps for-group map)
+ (push (cons for-group map) magit-key-mode-key-maps)
map))
(defvar magit-key-mode-prefix nil
@@ -376,85 +396,73 @@ highlighted before the description."
(defun magit-key-mode-redraw (for-group)
"(re)draw the magit key buffer."
(let ((buffer-read-only nil)
- (old-point (point)))
+ (old-point (point))
+ (is-first (zerop (buffer-size)))
+ (actions-p nil))
(erase-buffer)
(make-local-variable 'font-lock-defaults)
(use-local-map (magit-key-mode-get-key-map for-group))
- (magit-key-mode-draw for-group)
+ (setq actions-p (magit-key-mode-draw for-group))
(delete-trailing-whitespace)
(setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
- (goto-char old-point))
+ (if (and is-first actions-p)
+ (progn (goto-char actions-p)
+ (magit-key-mode-jump-to-next-exec))
+ (goto-char old-point)))
(setq buffer-read-only t)
(fit-window-to-buffer))
(defun magit-key-mode-draw-header (header)
"Draw a header with the correct face."
- (insert (propertize header 'face 'font-lock-keyword-face)))
+ (insert (propertize header 'face 'font-lock-keyword-face) "\n"))
(defvar magit-key-mode-args-in-cols nil
"When true, draw arguments in columns as with switches and
options.")
(defun magit-key-mode-draw-args (args)
"Draw the args part of the menu."
- (when args
- (let ((strs (mapcar
- (lambda (argument)
- (propertize
- (format " %s: %s (%s) %s"
- (propertize
- (car argument)
- 'face 'font-lock-builtin-face)
- (nth 1 argument)
- (nth 2 argument)
- (propertize
- (gethash (nth 2 argument)
- magit-key-mode-current-args
- "")
- 'face 'widget-field))
- 'key-group-executor (car argument)))
- args)))
- (magit-key-mode-draw-header "Args\n")
- (magit-key-mode-draw-in-cols strs (not magit-key-mode-args-in-cols)))))
+ (magit-key-mode-draw-buttons
+ "Args"
+ args
+ (lambda (x)
+ (format "(%s) %s"
+ (nth 2 x)
+ (propertize (gethash (nth 2 x) magit-key-mode-current-args "")
+ 'face 'widget-field)))
+ (not magit-key-mode-args-in-cols)))
(defun magit-key-mode-draw-switches (switches)
"Draw the switches part of the menu."
- (when switches
- (let ((switch-strs (mapcar
- (lambda (s)
- (let ((option (nth 2 s)))
- (propertize
- (format " %s: %s (%s)"
- (propertize (car s)
- 'face 'font-lock-builtin-face)
- (nth 1 s)
- (if (member option magit-key-mode-current-options)
- (propertize
- option
- 'face 'font-lock-warning-face)
- option))
- 'key-group-executor (car s))))
- switches)))
- (magit-key-mode-draw-header "Switches\n")
- (magit-key-mode-draw-in-cols switch-strs))))
+ (magit-key-mode-draw-buttons
+ "Switches"
+ switches
+ (lambda (x)
+ (format "(%s)" (let ((s (nth 2 x)))
+ (if (member s magit-key-mode-current-options)
+ (propertize s 'face 'font-lock-warning-face)
+ s))))))
(defun magit-key-mode-draw-actions (actions)
"Draw the actions part of the menu."
- (when actions
- (let ((action-strs (mapcar
- (lambda (a)
- (propertize
- (format
- " %s: %s"
- (propertize (car a)
- 'face 'font-lock-builtin-face)
- (nth 1 a))
- 'key-group-executor (car a)))
- actions)))
- (magit-key-mode-draw-header "Actions\n")
- (magit-key-mode-draw-in-cols action-strs))))
-
-(defun magit-key-mode-draw-in-cols (strings &optional one-col-each)
+ (magit-key-mode-draw-buttons "Actions" actions nil))
+
+(defun magit-key-mode-draw-buttons (section xs maker
+ &optional one-col-each)
+ (when xs
+ (magit-key-mode-draw-header section)
+ (magit-key-mode-draw-in-cols
+ (mapcar (lambda (x)
+ (let* ((head (propertize (car x) 'face 'font-lock-builtin-face))
+ (desc (nth 1 x))
+ (more (and maker (funcall maker x)))
+ (text (format " %s: %s%s%s"
+ head desc (if more " " "") (or more ""))))
+ (propertize text 'key-group-executor (car x))))
+ xs)
+ one-col-each)))
+
+(defun magit-key-mode-draw-in-cols (strings one-col-each)
"Given a list of strings, print in columns (using `insert'). If
ONE-COL-EACH is true then don't columify, but rather, draw each
item on one line."
@@ -475,15 +483,20 @@ item on one line."
(insert "\n"))
(defun magit-key-mode-draw (for-group)
- "Function used to draw actions, switches and parameters."
+ "Function used to draw actions, switches and parameters.
+
+Returns the point before the actions part, if any."
(let* ((options (magit-key-mode-options-for-group for-group))
(switches (cdr (assoc 'switches options)))
(arguments (cdr (assoc 'arguments options)))
- (actions (cdr (assoc 'actions options))))
+ (actions (cdr (assoc 'actions options)))
+ (p nil))
(magit-key-mode-draw-switches switches)
(magit-key-mode-draw-args arguments)
+ (when actions (setq p (point-marker)))
(magit-key-mode-draw-actions actions)
- (insert "\n")))
+ (insert "\n")
+ p))
(defun magit-key-mode-de-generate (group)
"Unbind the function for GROUP."
View
1 elpa/magit-1.2.0/magit-pkg.el
@@ -0,0 +1 @@
+(define-package "magit" "1.2.0" "Control Git from Emacs.")
View
0 elpa/magit-1.1.1/magit-stgit.el → elpa/magit-1.2.0/magit-stgit.el
File renamed without changes.
View
0 elpa/magit-1.1.1/magit-svn.el → elpa/magit-1.2.0/magit-svn.el
File renamed without changes.
View
0 elpa/magit-1.1.1/magit-topgit.el → elpa/magit-1.2.0/magit-topgit.el
File renamed without changes.
View
153 elpa/magit-1.2.0/magit-wip.el
@@ -0,0 +1,153 @@
+;;; magit-wip.el --- git-wip plug-in for Magit
+
+;; Copyright (C) 2012 Jonas Bernoulli
+;; Copyright (C) 2012 Ryan C. Thompson
+
+;; 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/>.
+
+;;; Commentary:
+
+;; This plug-in provides support for special work-in-progress refs.
+
+;; This requires the third-party git command "git wip" which is available
+;; from https://github.com/bartman/git-wip.
+
+;; The global mode `magit-wip-mode' provides highlighting of wip refs in
+;; Magit buffers while the local mode `magit-wip-save-mode' commits to
+;; such a ref when saving a file-visiting buffer.
+
+;; To enable `magit-wip-save-mode' enable `global-magit-wip-save-mode'
+;; and use the Magit extension mechanism to select the repositories in
+;; which you want to use a work-in-progress ref. Usually you also want
+;; to enable `magit-wip-mode'.
+;;
+;; (magit-wip-mode 1)
+;; (global-magit-wip-save-mode 1)
+;;
+;; $ git config --add magit.extension wip-save # or
+;; $ git config --global --add magit.extension wip-save
+
+;; Note that `global-magit-wip-save-mode' is the only mode that uses the
+;; extension mechanism for file-visiting buffers all other global modes
+;; making use of it to turn on local modes in Magit buffers.
+
+;;; Code:
+
+(require 'magit)
+(require 'format-spec)
+
+;;; Magit Wip Mode.
+
+(defface magit-log-head-label-wip
+ '((((class color) (background light))
+ :box t
+ :background "Grey95"
+ :foreground "LightSkyBlue3")
+ (((class color) (background dark))
+ :box t
+ :background "Grey07"
+ :foreground "LightSkyBlue4"))
+ "Face for git-wip labels shown in log buffer."
+ :group 'magit-faces)
+
+(defun magit-log-get-wip-color (suffix)
+ (list (concat "(WIP) " suffix)
+ 'magit-log-head-label-wip))
+
+(defconst magit-wip-refs-namespace
+ '("wip" magit-log-get-wip-color))
+
+;;;###autoload
+(define-minor-mode magit-wip-mode
+ "In Magit log buffers; give wip refs a special appearance."
+ :group 'magit
+ :global t
+ (if magit-wip-mode
+ (add-to-list 'magit-refs-namespaces magit-wip-refs-namespace 'append)
+ (setq magit-refs-namespaces
+ (delete magit-wip-refs-namespace magit-refs-namespaces))))
+
+;;; Magit Wip Save Mode.
+
+(defcustom magit-wip-commit-message "WIP %r"
+ "Commit message for git-wip commits.
+
+The following `format'-like specs are supported:
+%f the full name of the file being saved, and
+%r the name of the file being saved, relative to the repository root
+%g the root of the git repository."
+ :group 'magit
+ :type 'string)
+
+(defcustom magit-wip-echo-area-message "Wrote %f (wip)"
+ "Message shown in the echo area after creating a git-wip commit.
+
+The following `format'-like specs are supported:
+%f the full name of the file being saved, and
+%r the name of the file being saved, relative to the repository root.
+%g the root of the git repository."
+ :group 'magit
+ :type '(choice (const :tag "No message" nil) string))
+
+(defvar magit-wip-save-mode-lighter " Wip")
+
+;;;###autoload
+(define-minor-mode magit-wip-save-mode
+ "Magit support for committing to a work-in-progress ref.
+
+When this minor mode is turned on and a file is saved inside a writable
+git repository then it is also committed to a special work-in-progress
+ref."
+ :lighter magit-wip-save-mode-lighter
+ (if magit-wip-save-mode
+ (add-hook 'after-save-hook 'magit-wip-save-safe t t)
+ (remove-hook 'after-save-hook 'magit-wip-save-safe t)))
+
+;;;###autoload
+(define-globalized-minor-mode global-magit-wip-save-mode
+ magit-wip-save-mode turn-on-magit-wip-save
+ :group 'magit)
+
+(defun turn-on-magit-wip-save ()
+ (when (and (buffer-file-name)
+ (magit-get-top-dir default-directory)
+ (member "wip-save" (magit-get-all "magit.extension")))
+ (if (= (magit-git-exit-code "wip" "-h") 0)
+ (magit-wip-save-mode 1)
+ (message "Git command 'git wip' cannot be found"))))
+
+(defun magit-wip-save-safe ()
+ (condition-case err
+ (magit-wip-save)
+ (error
+ (message "Magit WIP got an error: %S" err))))
+
+(defun magit-wip-save ()
+ (let* ((top-dir (magit-get-top-dir default-directory))
+ (name (file-truename (buffer-file-name)))
+ (spec `((?r . ,(file-relative-name name top-dir))
+ (?f . ,(buffer-file-name))
+ (?g . ,top-dir))))
+ (when (and top-dir (file-writable-p top-dir))
+ (save-excursion ; kludge see https://github.com/magit/magit/issues/441
+ (magit-run-git "wip" "save"
+ (format-spec magit-wip-commit-message spec)
+ "--editor" "--" name))
+ (when magit-wip-echo-area-message
+ (message (format-spec magit-wip-echo-area-message spec))))))
+
+(provide 'magit-wip)
+;;; magit-wip.el ends here
View
1,506 elpa/magit-1.1.1/magit.el → elpa/magit-1.2.0/magit.el
@@ -1,4 +1,4 @@
-;;; magit.el -- control Git from Emacs.
+;;; magit.el --- control Git from Emacs
;; Copyright (C) 2010 Aaron Culich.
;; Copyright (C) 2010 Alan Falloon.
@@ -22,7 +22,7 @@
;; Copyright (C) 2010 Nathan Weizenbaum.
;; Copyright (C) 2010 Oscar Fuentes.
;; Copyright (C) 2009 Pavel Holejsovsky.
-;; Copyright (C) 2011 Peter J Weisberg
+;; Copyright (C) 2011-2012 Peter J Weisberg
;; Copyright (C) 2009, 2010 Phil Jackson.
;; Copyright (C) 2010 Philip Weaver.
;; Copyright (C) 2010 Ramkumar Ramachandra.
@@ -46,7 +46,7 @@
;; - Peter J Weisberg
;; - Yann Hodique
;; - Rémi Vanicat
-;; Version: 1.1.1
+;; Version: 1.2.0
;; Keywords: tools
;;
@@ -85,6 +85,9 @@
(require 'diff-mode)
;; Silences byte-compiler warnings
+(eval-and-compile
+ (unless (fboundp 'declare-function) (defmacro declare-function (&rest args))))
+
(eval-when-compile (require 'view))
(declare-function view-mode 'view)
(eval-when-compile (require 'iswitchb))
@@ -132,7 +135,8 @@ Magit will only descend this many levels deep."
:type 'integer)
(defcustom magit-set-upstream-on-push nil
- "Non-nil means that \\[magit-push] will use --set-upstream when pushing a branch.
+ "Non-nil means that `magit-push' may use --set-upstream when pushing a branch.
+This only applies if the branch does not have an upstream set yet.
Setting this to t will ask if --set-upstream should be used.
Setting it to 'dontask will always use --set-upstream.
Setting it to 'refuse will refuse to push unless a remote branch has already been set.
@@ -155,8 +159,10 @@ save all modified buffers without asking."
(defcustom magit-save-some-buffers-predicate
'magit-save-buffers-predicate-tree-only
- "Specifies a predicate function on \\[magit-save-some-buffers] to determine which
- unsaved buffers should be prompted for saving."
+ "A predicate function to decide whether to save a buffer.
+
+Used by function `magit-save-some-buffers' when the variable of
+the same name is non-nil."
:group 'magit
:type '(radio (function-item magit-save-buffers-predicate-tree-only)
@@ -193,6 +199,11 @@ after a confirmation."
:group 'magit
:type 'boolean)
+(defcustom magit-sha1-abbrev-length 7
+ "The number of digits to show when a sha1 is displayed in abbreviated form."
+ :group 'magit
+ :type 'integer)
+
(defcustom magit-log-cutoff-length 100
"The maximum number of commits to show in the log and whazzup buffers."
:group 'magit
@@ -237,7 +248,7 @@ completion.
The value 'name-then-remote means remotes will be of the
form \"name (remote)\", while the value 'remote-slash-name
-means that they'll be of the form \"remote/name\". I.e. something that's
+means that they'll be of the form \"remote/name\". I.e. something that's
listed as \"remotes/upstream/next\" by \"git branch -l -a\"
will be \"upstream/next\"."
:group 'magit
@@ -247,10 +258,11 @@ will be \"upstream/next\"."
(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
"Connection type used for the git process.
-nil mean pipe, it is usually faster and more efficient, and work on cygwin.
-t mean pty, it enable magit to prompt for passphrase when needed."
+If nil, use pipes: this is usually more efficient, and works on Cygwin.
+If t, use ptys: this enables magit to prompt for passphrases when needed."
:group 'magit
- :type 'boolean)
+ :type '(choice (const :tag "pipe" nil)
+ (const :tag "pty" t)))
(defcustom magit-completing-read-function 'magit-builtin-completing-read
"Function to be called when requesting input from the user."
@@ -283,47 +295,45 @@ The function is given one argument, the status buffer."
"Whether magit includes the selected base commit in a rewrite operation.
t means both the selected commit as well as any subsequent
-commits will be rewritten. This is magit's default behaviour,
+commits will be rewritten. This is magit's default behaviour,
equivalent to 'git rebase -i ${REV}~1'
A'---B'---C'---D'
^
nil means the selected commit will be literally used as 'base',
-so only subsequent commits will be rewritten. This is consistent
+so only subsequent commits will be rewritten. This is consistent
with git-rebase, equivalent to 'git rebase -i ${REV}', yet more
cumbersome to use from the status buffer.
A---B'---C'---D'
- ^
-"
+ ^"
:group 'magit
:type '(choice (const :tag "Always" t)
(const :tag "Never" nil)
(const :tag "Ask" ask)))
(defcustom magit-highlight-whitespace t
- "Specifies where to highlight whitespace errors. See
-`magit-highlight-trailing-whitespace',
-`magit-highlight-indentation'. `t' means in all diffs, the
-symbol `status' means only in the status buffer, and `nil' means
-nowhere."
+ "Specifies where to highlight whitespace errors.
+See `magit-highlight-trailing-whitespace',
+`magit-highlight-indentation'. The symbol t means in all diffs,
+'status means only in the status buffer, and nil means nowhere."
:group 'magit
:type '(choice (const :tag "Always" t)
(const :tag "Never" nil)
(const :tag "In status buffer" status))
:set 'magit-set-variable-and-refresh)
(defcustom magit-highlight-trailing-whitespace t
- "If `magit-highlight-whitespace' is enabled, highlight
-whitespace at the end of a line in diffs."
+ "Highlight whitespace at the end of a line in diffs.
+Used only when `magit-highlight-whitespace' is non-nil."
:group 'magit
:type 'boolean
:set 'magit-set-variable-and-refresh)
(defcustom magit-highlight-indentation nil
- "If `magit-highlight-whitespace' is enabled, highlight the
-\"wrong\" indentation style.
+ "Highlight the \"wrong\" indentation style.
+Used only when `magit-highlight-whitespace' is non-nil.
The value is a list of cons cells. The car is a regular
expression, and the cdr is the value that applies to repositories
@@ -341,9 +351,26 @@ many spaces. Otherwise, highlight neither."
(const :tag "Neither" nil))))
:set 'magit-set-variable-and-refresh)
+(defcustom magit-diff-refine-hunk nil
+ "Show fine (word-granularity) differences within diff hunks.
+
+There are three possible settings:
+
+ nil means to never show fine differences
+
+ t means to only show fine differences for the currently
+ selected diff hunk
+
+ `all' means to always show fine differences for all displayed diff hunks"
+ :group 'magit
+ :type '(choice (const :tag "Never" nil)
+ (const :tag "Selected only" t)
+ (const :tag "All" all))
+ :set 'magit-set-variable-and-refresh)
+
(defvar magit-current-indentation nil
- "Indentation highlight used in the current buffer, as specified
-in `magit-highlight-indentation'.")
+ "Indentation highlight used in the current buffer.
+This is calculated from `magit-highlight-indentation'.")
(make-variable-buffer-local 'magit-current-indentation)
(defgroup magit-faces nil
@@ -497,6 +524,12 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(defvar magit-read-rev-history nil
"The history of inputs to `magit-read-rev'.")
+(defvar magit-buffer-internal nil
+ "Track associated *magit* buffers.
+Do not customize this (used in the `magit-log-edit-mode' implementation
+to switch back to the *magit* buffer associated with a given commit
+operation after commit).")
+
(defvar magit-back-navigation-history nil
"History items that will be visited by successively going \"back\".")
(make-variable-buffer-local 'magit-back-navigation-history)
@@ -539,6 +572,9 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(suppress-keymap map t)
(define-key map (kbd "n") 'magit-goto-next-section)
(define-key map (kbd "p") 'magit-goto-previous-section)
+ (define-key map (kbd "^") 'magit-goto-parent-section)
+ (define-key map (kbd "M-n") 'magit-goto-next-sibling-section)
+ (define-key map (kbd "M-p") 'magit-goto-previous-sibling-section)
(define-key map (kbd "TAB") 'magit-toggle-section)
(define-key map (kbd "<backtab>") 'magit-expand-collapse-section)
(define-key map (kbd "1") 'magit-show-level-1)
@@ -559,6 +595,7 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(define-key map (kbd "!") 'magit-key-mode-popup-running)
(define-key map (kbd ":") 'magit-git-command)
(define-key map (kbd "C-x 4 a") 'magit-add-change-log-entry-other-window)
+ (define-key map (kbd "L") 'magit-add-change-log-entry-no-option)
(define-key map (kbd "RET") 'magit-visit-item)
(define-key map (kbd "SPC") 'magit-show-item-or-scroll-up)
(define-key map (kbd "DEL") 'magit-show-item-or-scroll-down)
@@ -569,6 +606,7 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(define-key map (kbd "P") 'magit-key-mode-popup-pushing)
(define-key map (kbd "f") 'magit-key-mode-popup-fetching)
(define-key map (kbd "b") 'magit-key-mode-popup-branching)
+ (define-key map (kbd "M") 'magit-key-mode-popup-remoting)
(define-key map (kbd "B") 'magit-key-mode-popup-bisecting)
(define-key map (kbd "F") 'magit-key-mode-popup-pulling)
(define-key map (kbd "l") 'magit-key-mode-popup-logging)
@@ -588,6 +626,7 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(define-key map (kbd "-") 'magit-diff-smaller-hunks)
(define-key map (kbd "+") 'magit-diff-larger-hunks)
(define-key map (kbd "0") 'magit-diff-default-hunks)
+ (define-key map (kbd "h") 'magit-toggle-diff-refine-hunk)
map))
(defvar magit-commit-mode-map
@@ -612,6 +651,9 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(define-key map (kbd "z") 'magit-key-mode-popup-stashing)
map))
+(eval-after-load 'dired-x
+ '(define-key magit-status-mode-map [remap dired-jump] 'magit-dired-jump))
+
(defvar magit-log-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd ".") 'magit-mark-item)
@@ -626,21 +668,24 @@ Do not customize this (used in the `magit-key-mode' implementation).")
(define-key map (kbd "i") 'magit-ignore-item)
map))
-(defvar magit-show-branches-mode-map
+(defvar magit-branch-manager-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map (kbd "k") 'magit-remove-branch)
- (define-key map (kbd "K") 'magit-remove-branch-in-remote-repo)
- (define-key map (kbd "v") 'magit-show-branches)
+ (define-key map (kbd "c") 'magit-create-branch)
+ (define-key map (kbd "a") 'magit-add-remote)
+ (define-key map (kbd "r") 'magit-move-item)
+ (define-key map (kbd "k") 'magit-discard-item)
(define-key map (kbd "T") 'magit-change-what-branch-tracks)
map))
(defvar magit-bug-report-url
"http://github.com/magit/magit/issues")
-(defconst magit-version "1.1.1"
+(defconst magit-version "1.2.0"
"The version of Magit that you're using.")
(defun magit-bug-report (str)
+ "Asks the user to submit a bug report about the error described in STR."
+;; XXX - should propose more information to be included.
(message (concat
"Unknown error: %s\n"
"Please, with as much information as possible, file a bug at\n"
@@ -868,6 +913,11 @@ Does not follow symlinks."
"Return all values of the Git config entry specified by KEYS."
(magit-git-lines "config" "--get-all" (mapconcat 'identity keys ".")))
+(defun magit-get-boolean (&rest keys)
+ "Return the boolean value of Git config entry specified by KEYS."
+ (equal (magit-git-string "config" "--bool" (mapconcat 'identity keys "."))
+ "true"))
+
(defun magit-set (val &rest keys)
"Set Git config settings specified by KEYS to VAL."
(if val
@@ -897,6 +947,10 @@ Does not follow symlinks."
(defun magit-git-repo-p (dir)
(file-exists-p (expand-file-name ".git" dir)))
+(defun magit-git-dir ()
+ "Returns the .git directory for the current repository."
+ (concat (expand-file-name (magit-git-string "rev-parse" "--git-dir")) "/"))
+
(defun magit-no-commit-p ()
"Return non-nil if there is no commit in the current git repository."
(not (magit-git-string
@@ -988,11 +1042,11 @@ autocompletion will offer directory names."
;; so magit-git-string returns nil.
(not (magit-git-string "rev-parse" "--abbrev-ref" ref)))
-(defun magit-name-rev (rev)
+(defun magit-name-rev (rev &optional no-trim)
"Return a human-readable name for REV.
Unlike git name-rev, this will remove tags/ and remotes/ prefixes
-if that can be done unambiguously. In addition, it will filter
-out revs involving HEAD."
+if that can be done unambiguously (unless optional arg NO-TRIM is
+non-nil). In addition, it will filter out revs involving HEAD."
(when rev
(let ((name (magit-git-string "name-rev" "--no-undefined" "--name-only" rev)))
;; There doesn't seem to be a way of filtering HEAD out from name-rev,
@@ -1012,7 +1066,7 @@ out revs involving HEAD."
(setq rev (or name rev))
(when (string-match "^\\(?:tags\\|remotes\\)/\\(.*\\)" rev)
(let ((plain-name (match-string 1 rev)))
- (unless (magit-ref-ambiguous-p plain-name)
+ (unless (or no-trim (magit-ref-ambiguous-p plain-name))
(setq rev plain-name))))
rev)))
@@ -1102,28 +1156,37 @@ argument or a list of strings used as regexps."
(funcall uninteresting ref)))
((and (not (functionp uninteresting))
(loop for i in uninteresting thereis (string-match i ref))))
- ((string-match "refs/heads/\\(.*\\)" ref)
- (let ((branch (match-string 1 ref)))
- (push (cons branch branch) refs)))
- ((string-match "refs/tags/\\(.*\\)" ref)
- (push (cons (format
- (if (eq magit-remote-ref-format 'branch-then-remote)
- "%s (tag)" "%s")
- (match-string 1 ref))
- ref)
- refs))
- ((string-match "refs/remotes/\\([^/]+\\)/\\(.+\\)" ref)
- (push (cons (if (eq magit-remote-ref-format 'branch-then-remote)
- (format "%s (%s)"
- (match-string 2 ref)
- (match-string 1 ref))
- (format "%s/%s"
- (match-string 1 ref)
- (match-string 2 ref)))
- ref)
- refs))))))
+ (t
+ (let ((fmt-ref (magit-format-ref ref)))
+ (when fmt-ref
+ (push (cons fmt-ref
+ (replace-regexp-in-string "^refs/heads/"
+ "" ref))
+ refs))))))))
(nreverse refs)))
+(defun magit-format-ref (ref)
+ "Convert fully-specified ref REF into its displayable form
+according to `magit-remote-ref-format'"
+ (cond
+ ((null ref)
+ nil)
+ ((string-match "refs/heads/\\(.*\\)" ref)
+ (match-string 1 ref))
+ ((string-match "refs/tags/\\(.*\\)" ref)
+ (format (if (eq magit-remote-ref-format 'branch-then-remote)
+ "%s (tag)"
+ "%s")
+ (match-string 1 ref)))
+ ((string-match "refs/remotes/\\([^/]+\\)/\\(.+\\)" ref)
+ (if (eq magit-remote-ref-format 'branch-then-remote)
+ (format "%s (%s)"
+ (match-string 2 ref)
+ (match-string 1 ref))
+ (format "%s/%s"
+ (match-string 1 ref)
+ (match-string 2 ref))))))
+
(defun magit-tree-contents (treeish)
"Returns a list of all files under TREEISH. TREEISH can be a tree,
a commit, or any reference to one of those."
@@ -1137,7 +1200,7 @@ a commit, or any reference to one of those."
(push (match-string 1) return-value)))
return-value))
-(defvar magit-uninteresting-refs '("refs/remotes/\\([^/]+\\)/HEAD$"))
+(defvar magit-uninteresting-refs '("refs/remotes/\\([^/]+\\)/HEAD$" "refs/stash"))
(defun magit-read-file-from-rev (revision)
(magit-completing-read (format "Retrieve file from %s: " revision)
@@ -1150,14 +1213,11 @@ a commit, or any reference to one of those."
(let ((topdir-length (length (magit-get-top-dir default-directory))))
(substring (buffer-file-name) topdir-length)))))
-;; TODO: fix this so that def can (must?) be git rev instead of, say, "master (origin)"
-;; which involves a particular display strategy and shouldn't be visible to callers
-;; of magit-read-rev
-(defun magit-read-rev (prompt &optional def uninteresting)
+(defun magit-read-rev (prompt &optional default uninteresting)
(let* ((interesting-refs (magit-list-interesting-refs
(or uninteresting magit-uninteresting-refs)))
(reply (magit-completing-read (concat prompt ": ") interesting-refs
- nil nil nil 'magit-read-rev-history def))
+ nil nil nil 'magit-read-rev-history default))
(rev (or (cdr (assoc reply interesting-refs)) reply)))
(if (string= rev "")
nil
@@ -1210,8 +1270,8 @@ a commit, or any reference to one of those."
(magit-rev-describe (cdr range)))
(format "%s at %s" things (magit-rev-describe (car range))))))
-(defun magit-default-rev ()
- (or (magit-name-rev (magit-commit-at-point t))
+(defun magit-default-rev (&optional no-trim)
+ (or (magit-name-rev (magit-commit-at-point t) no-trim)
(let ((branch (magit-guess-branch)))
(if branch
(if (string-match "^refs/\\(.*\\)" branch)
@@ -1221,25 +1281,26 @@ a commit, or any reference to one of those."
(defun magit-read-remote (&optional prompt def)
"Read the name of a remote.
PROMPT is used as the prompt, and defaults to \"Remote\".
-DEF is the default value, and defaults to the value of `magit-get-current-branch'."
- (let* ((prompt (or prompt "Remote: "))
- (def (or def (magit-get-current-remote)))
+DEF is the default value."
+ (let* ((prompt (or prompt "Remote"))
+ (def (or def (magit-guess-remote)))
(remotes (magit-git-lines "remote"))
- (reply (magit-completing-read prompt remotes
+
+ (reply (magit-completing-read (concat prompt ": ") remotes
nil nil nil nil def)))
(if (string= reply "") nil reply)))
(defun magit-read-remote-branch (remote &optional prompt default)
- (let* ((prompt (or prompt (format "Remote branch (in %s): " remote)))
+ (let* ((prompt (or prompt (format "Remote branch (in %s)" remote)))
(branches (delete nil
(mapcar
(lambda (b)
(and (not (string-match " -> " b))
(string-match (format "^ *%s/\\(.*\\)$"
- remote) b)
+ (regexp-quote remote)) b)
(match-string 1 b)))
(magit-git-lines "branch" "-r"))))
- (reply (magit-completing-read prompt branches
+ (reply (magit-completing-read (concat prompt ": ") branches
nil nil nil nil default)))
(if (string= reply "") nil reply)))
@@ -1474,15 +1535,15 @@ see `magit-insert-section' for meaning of the arguments"
(append magit-git-standard-options args)))
(defun magit-goto-next-section ()
- "Go to the next Magit section."
+ "Go to the next section."
(interactive)
(let ((next (magit-find-section-after (point))))
(if next
(magit-goto-section next)
(message "No next section"))))
(defun magit-goto-previous-section ()
- "Go to the previous Magit section."
+ "Go to the previous section."
(interactive)
(if (eq (point) 1)
(message "No previous section")
@@ -1495,6 +1556,31 @@ see `magit-insert-section' for meaning of the arguments"
(when parent
(goto-char (magit-section-beginning parent)))))
+(defun magit-goto-next-sibling-section ()
+ "Go to the next sibling section."
+ (interactive)
+ (let* ((initial (point))
+ (section (magit-current-section))
+ (end (- (magit-section-end section) 1))
+ (parent (magit-section-parent section))
+ (siblings (magit-section-children parent))
+ (next-sibling (magit-find-section-after* end siblings)))
+ (if next-sibling
+ (magit-goto-section next-sibling)
+ (magit-goto-next-section))))
+
+(defun magit-goto-previous-sibling-section ()
+ "Go to the previous sibling section."
+ (interactive)
+ (let* ((section (magit-current-section))
+ (beginning (magit-section-beginning section))
+ (parent (magit-section-parent section))
+ (siblings (magit-section-children parent))
+ (previous-sibling (magit-find-section-before* beginning siblings)))
+ (if previous-sibling
+ (magit-goto-section previous-sibling)
+ (magit-goto-parent-section))))
+
(defun magit-goto-section (section)
(goto-char (magit-section-beginning section))
(cond
@@ -1713,41 +1799,79 @@ one for all, one for current lineage."
TITLE is the displayed title of the section."
(let ((fun (intern (format "magit-jump-to-%s" sym)))
(doc (format "Jump to section `%s'." title)))
- `(defun ,fun ()
- ,doc
- (interactive)
- (magit-goto-section-at-path '(,sym)))))
+ `(progn
+ (defun ,fun ()
+ ,doc
+ (interactive)
+ (magit-goto-section-at-path '(,sym)))
+ (put ',fun 'definition-name ',sym))))
(defmacro magit-define-inserter (sym arglist &rest body)
(declare (indent defun))
(let ((fun (intern (format "magit-insert-%s" sym)))
(before (intern (format "magit-before-insert-%s-hook" sym)))
(after (intern (format "magit-after-insert-%s-hook" sym)))
(doc (format "Insert items for `%s'." sym)))
- `(defun ,fun ,arglist
- ,doc
- (run-hooks ',before)
- ,@body
- (run-hooks ',after))))
-
-(defvar magit-highlight-overlay nil)
+ `(progn
+ (defvar ,before nil)
+ (defvar ,after nil)
+ (defun ,fun ,arglist
+ ,doc
+ (run-hooks ',before)
+ ,@body
+ (run-hooks ',after))
+ (put ',before 'definition-name ',sym)
+ (put ',after 'definition-name ',sym)
+ (put ',fun 'definition-name ',sym))))
(defvar magit-highlighted-section nil)
+(defun magit-refine-section (section)
+ "Apply temporary refinements to the display of SECTION.
+Refinements can be undone with `magit-unrefine-section'."
+ (let ((type (and section (magit-section-type section))))
+ (cond ((and (eq type 'hunk)
+ magit-diff-refine-hunk
+ (not (eq magit-diff-refine-hunk 'all)))
+ ;; Refine the current hunk to show fine details, using
+ ;; diff-mode machinery.
+ (save-excursion
+ (goto-char (magit-section-beginning magit-highlighted-section))
+ (diff-refine-hunk))))))
+
+(defun magit-unrefine-section (section)
+ "Remove refinements to the display of SECTION done by `magit-refine-section'."
+ (let ((type (and section (magit-section-type section))))
+ (cond ((and (eq type 'hunk)
+ magit-diff-refine-hunk
+ (not (eq magit-diff-refine-hunk 'all)))
+ ;; XXX this should be in some diff-mode function, like
+ ;; `diff-unrefine-hunk'
+ (remove-overlays (magit-section-beginning section)
+ (magit-section-end section)
+ 'diff-mode 'fine)))))
+
+(defvar magit-highlight-overlay nil)
+
(defun magit-highlight-section ()
"Highlight current section if it has a type."
(let ((section (magit-current-section)))
(when (not (eq section magit-highlighted-section))
+ (when magit-highlighted-section
+ ;; remove any refinement from previous hunk
+ (magit-unrefine-section magit-highlighted-section))
(setq magit-highlighted-section section)
(if (not magit-highlight-overlay)
(let ((ov (make-overlay 1 1)))
(overlay-put ov 'face 'magit-item-highlight)
(setq magit-highlight-overlay ov)))
(if (and section (magit-section-type section))
- (move-overlay magit-highlight-overlay
- (magit-section-beginning section)
- (magit-section-end section)
- (current-buffer))
+ (progn
+ (magit-refine-section section)
+ (move-overlay magit-highlight-overlay
+ (magit-section-beginning section)
+ (magit-section-end section)
+ (current-buffer)))
(delete-overlay magit-highlight-overlay)))))
(defun magit-section-context-type (section)
@@ -1790,7 +1914,7 @@ where SECTION-TYPE describe section where BODY will be run.
This returns non-nil if some section matches. If the
corresponding body return a non-nil value, it is returned,
-otherwise it roturn t.
+otherwise it returns t.
If no section matches, this returns nil if no OPNAME was given
and throws an error otherwise."
@@ -1801,8 +1925,8 @@ and throws an error otherwise."
(context (make-symbol "*context*"))
(opname (caddr head)))
`(let* ((,section (magit-current-section))
- (,info (magit-section-info ,section))
- (,type (magit-section-type ,section))
+ (,info (and ,section (magit-section-info ,section)))
+ (,type (and ,section (magit-section-type ,section)))
(,context (magit-section-context-type ,section)))
(cond ,@(mapcar (lambda (clause)
(if (eq (car clause) t)
@@ -1882,12 +2006,16 @@ function can be enriched by magit extension like magit-topgit and magit-svn"
(when (eq (car form) 'interactive)
(setq inter form
instr (cdr instr))))
- `(defun ,fun ,arglist
- ,doc
- ,inter
- (or (run-hook-with-args-until-success
- ',hook ,@(remq '&optional (remq '&rest arglist)))
- ,@instr))))
+ `(progn
+ (defvar ,hook nil)
+ (defun ,fun ,arglist
+ ,doc
+ ,inter
+ (or (run-hook-with-args-until-success
+ ',hook ,@(remq '&optional (remq '&rest arglist)))
+ ,@instr))
+ (put ',fun 'definition-name ',sym)
+ (put ',hook 'definition-name ',sym))))
;;; Running commands
@@ -2029,17 +2157,29 @@ function can be enriched by magit extension like magit-topgit and magit-svn"
"Checks if git/ssh asks for a password and ask the user for it."
(let (ask)
(cond ((or (string-match "^Enter passphrase for key '\\\(.*\\\)': $" string)
- (string-match "^\\\(.*\\\)'s password:" string))
+ (string-match "^\\\(.*\\\)'s password:" string)
+ (string-match "^Password for '\\\(.*\\\)':" string))
(setq ask (format "Password for '%s': " (match-string 1 string))))
((string-match "^[pP]assword:" string)
(setq ask "Password:")))
(when ask
(process-send-string proc (concat (read-passwd ask nil) "\n")))))
+(defun magit-username (proc string)
+ "Checks if git asks for a username and ask the user for it."
+ (when (string-match "^Username for '\\\(.*\\\)':" string)
+ (process-send-string proc
+ (concat
+ (read-string (format "Username for '%s': "
+ (match-string 1 string))
+ nil nil (user-login-name))
+ "\n"))))
+
(defun magit-process-filter (proc string)
(save-current-buffer
(set-buffer (process-buffer proc))
(let ((inhibit-read-only t))
+ (magit-username proc string)
(magit-password proc string)
(goto-char (process-mark proc))
;; Find last ^M in string. If one was found, ignore everything
@@ -2140,7 +2280,7 @@ function can be enriched by magit extension like magit-topgit and magit-svn"
["Snapshot" magit-stash-snapshot t]
"---"
["Branch..." magit-checkout t]
- ["Merge" magit-automatic-merge t]
+ ["Merge" magit-manual-merge t]
["Interactive resolve" magit-interactive-resolve-item t]
["Rebase" magit-rebase-step t]
("Rewrite"
@@ -2222,8 +2362,9 @@ Please see the manual for a complete description of Magit.
\\{magit-mode-map}"
(kill-all-local-variables)
(buffer-disable-undo)
- (setq buffer-read-only t)
- (setq major-mode 'magit-mode
+ (setq buffer-read-only t
+ truncate-lines t
+ major-mode 'magit-mode
mode-name "Magit"
mode-line-process "")
(add-hook 'pre-command-hook #'magit-remember-point nil t)
@@ -2425,6 +2566,43 @@ in the corresponding directories."
(setq magit-diff-context-lines 3)
(magit-refresh))
+(defun magit-toggle-diff-refine-hunk (&optional other)
+ (interactive "P")
+ "Turn diff-hunk refining on or off.
+
+If hunk refining is currently on, then hunk refining is turned off.
+If hunk refining is off, then hunk refining is turned on, in
+`selected' mode (only the currently selected hunk is refined).
+
+With a prefix argument, the \"third choice\" is used instead:
+If hunk refining is currently on, then refining is kept on, but
+the refining mode (`selected' or `all') is switched.
+If hunk refining is off, then hunk refining is turned on, in
+`all' mode (all hunks refined).
+
+Customize `magit-diff-refine-hunk' to change the default mode."
+ (let* ((old magit-diff-refine-hunk)
+ (new
+ (if other
+ (if (eq old 'all) t 'all)
+ (not old))))
+
+ ;; remove any old refining in currently highlighted section
+ (when (and magit-highlighted-section old (not (eq old 'all)))
+ (magit-unrefine-section magit-highlighted-section))
+
+ ;; set variable to new value locally
+ (set (make-local-variable 'magit-diff-refine-hunk) new)
+
+ ;; if now highlighting in "selected only" mode, turn refining back
+ ;; on in the current section
+ (when (and magit-highlighted-section new (not (eq new 'all)))
+ (magit-refine-section magit-highlighted-section))
+
+ ;; `all' mode being turned on or off needs a complete refresh
+ (when (or (eq old 'all) (eq new 'all))
+ (magit-refresh))))
+
(defun magit-diff-line-file ()
(cond ((looking-at "^diff --git ./\\(.*\\) ./\\(.*\\)$")
(match-string-no-properties 2))
@@ -2569,7 +2747,8 @@ in the corresponding directories."
(defun magit-wash-hunk ()
(cond ((looking-at "\\(^@+\\)[^@]*@+.*")
(let ((n-columns (1- (length (match-string 1))))
- (head (match-string 0)))
+ (head (match-string 0))
+ (hunk-start-pos (point)))
(magit-with-section head 'hunk
(add-text-properties (match-beginning 0) (match-end 0)
'(face magit-diff-hunk-header))
@@ -2585,7 +2764,12 @@ in the corresponding directories."
(magit-put-line-property 'face 'magit-diff-del))
(t
(magit-put-line-property 'face 'magit-diff-none))))
- (forward-line))))
+ (forward-line)))
+
+ (when (eq magit-diff-refine-hunk 'all)
+ (save-excursion
+ (goto-char hunk-start-pos)
+ (diff-refine-hunk))))
t)
(t
nil)))
@@ -2791,21 +2975,34 @@ either in another window or (with a prefix argument) in the current window."
"apply" (append args (list "-")))))
(defun magit-apply-hunk-item* (hunk reverse &rest args)
- (when (zerop magit-diff-context-lines)
- (setq args (cons "--unidiff-zero" args)))
- (with-magit-tmp-buffer tmp
- (if (magit-use-region-p)
- (magit-insert-hunk-item-region-patch
- hunk reverse (region-beginning) (region-end) tmp)
- (magit-insert-hunk-item-patch hunk tmp))
- (apply #'magit-run-git-with-input tmp
- "apply" (append args (list "-")))))
+ "Apply single hunk or part of a hunk to the index or working file.
+
+This function is the core of magit's stage, unstage, apply, and
+revert operations. HUNK (or the portion of it selected by the
+region) will be applied to either the index, if \"--cached\" is a
+member of ARGS, or to the working file otherwise."
+ (let ((zero-context (zerop magit-diff-context-lines))
+ (use-region (magit-use-region-p)))
+ (when zero-context
+ (setq args (cons "--unidiff-zero" args)))
+ (when reverse
+ (setq args (cons "--reverse" args)))
+ (when (and use-region zero-context)
+ (error (concat "Not enough context to partially apply hunk. "
+ "Use `+' to increase context.")))
+ (with-magit-tmp-buffer tmp
+ (if use-region
+ (magit-insert-hunk-item-region-patch
+ hunk reverse (region-beginning) (region-end) tmp)
+ (magit-insert-hunk-item-patch hunk tmp))
+ (apply #'magit-run-git-with-input tmp
+ "apply" (append args (list "-"))))))
(defun magit-apply-hunk-item (hunk &rest args)
(apply #'magit-apply-hunk-item* hunk nil args))
(defun magit-apply-hunk-item-reverse (hunk &rest args)
- (apply #'magit-apply-hunk-item* hunk t (cons "--reverse" args)))
+ (apply #'magit-apply-hunk-item* hunk t args))
(magit-define-inserter unstaged-changes (title)
(let ((magit-hide-diffs t)
@@ -2832,7 +3029,9 @@ either in another window or (with a prefix argument) in the current window."
; Note: making this a plain defcustom would probably let users break
; the parser too easily
(defvar magit-git-log-options
- '("--pretty=format:* %H %s"))
+ (list
+ "--pretty=format:* %h %s"
+ (format "--abbrev=%s" magit-sha1-abbrev-length)))
; --decorate=full otherwise some ref prefixes are stripped
; '("--pretty=format:* %H%d %s" "--decorate=full"))
@@ -2886,12 +3085,10 @@ Evaluate (man \"git-check-ref-format\") for details")
(defconst magit-log-oneline-re
(concat
- "^\\([_\\*|/ -.]+\\)?" ; graph (1)
- "\\(?:commit \\)?" ; this happens in long mode
+ "^\\([_\\*|/ -.]+\\)?" ; graph (1)
"\\(?:"
- "\\([0-9a-fA-F]\\{40\\}\\)" ; sha1 (2)
-
- "\\(?:" ; refs (3)
+ "\\([0-9a-fA-F]+\\)" ; sha1 (2)
+ "\\(?:" ; refs (3)
" "
"\\("
"("
@@ -2900,12 +3097,29 @@ Evaluate (man \"git-check-ref-format\") for details")
"\\)"
"\\)?"
"\\)?"
+ " ?\\(.*\\)$" ; msg (4)
+ ))
- " ?\\(.*\\)$" ; msg (4)
- )
- "Regexp used to extract elements of git log output.
-Those output are generated by --pretty=oneline with graph, or 'magit-git-log-options above.
-This is also made compatible with long log lines.")
+(defconst magit-log-longline-re
+ (concat
+ ;; use \0 delimiter (from -z option) to identify commits. this prevents
+ ;; commit messages containing lines like "commit 00000" from polluting the
+ ;; display
+ "\\(?:\\(?:\\`\\|\0\\)"
+ "\\([_\\*|/ -.]+\\)?" ; graph (1)
+ "commit "
+ "\\([0-9a-fA-F]+\\)" ; sha1 (2)
+ "\\(?:" ; refs (3)
+ " "
+ "\\("
+ "("
+ magit-refname-re "\\(?:, " magit-refname-re "\\)*"
+ ")"
+ "\\)"
+ "\\)?"
+ "$\\)?"
+ " ?\\(.*\\)$" ; msg (4)
+ ))
(defvar magit-present-log-line-function 'magit-present-log-line
"The function to use when generating a log line.
@@ -2938,22 +3152,25 @@ must return a string which will represent the log line.")
("bisect" magit-log-get-bisect-state-color)))
(defun magit-ref-get-label-color (r)
- (let* ((ref-re "\\(?:tag: \\)?refs/\\(?:\\([^/]+\\)/\\)?\\(.+\\)")
- (label (and (string-match ref-re r)
- (match-string 2 r)))
- (res (let ((colorizer
- (cdr (assoc (match-string 1 r)
- magit-refs-namespaces))))
- (cond ((null colorizer)
- (list r 'magit-log-head-label-default))
- ((symbolp colorizer)
- (list label colorizer))
- ((listp colorizer)
- (funcall (car colorizer)
- (match-string 2 r)))
- (t
- (list r 'magit-log-head-label-default))))))
- res))
+ (let ((uninteresting (loop for re in magit-uninteresting-refs
+ thereis (string-match re r))))
+ (if uninteresting (list nil nil)
+ (let* ((ref-re "\\(?:tag: \\)?refs/\\(?:\\([^/]+\\)/\\)?\\(.+\\)")
+ (label (and (string-match ref-re r)
+ (match-string 2 r)))
+ (res (let ((colorizer
+ (cdr (assoc (match-string 1 r)
+ magit-refs-namespaces))))
+ (cond ((null colorizer)
+ (list r 'magit-log-head-label-default))
+ ((symbolp colorizer)
+ (list label colorizer))
+ ((listp colorizer)
+ (funcall (car colorizer)
+ (match-string 2 r)))
+ (t
+ (list r 'magit-log-head-label-default))))))
+ res))))
(defun magit-present-log-line (graph sha1 refs message)
"The default log line generator."
@@ -2973,8 +3190,8 @@ must return a string which will represent the log line.")
(concat
(if sha1
- (propertize (substring sha1 0 8) 'face 'magit-log-sha1)
- (insert-char ? 8))
+ (propertize sha1 'face 'magit-log-sha1)
+ (insert-char ? magit-sha1-abbrev-length))
" "
(when graph
(propertize graph 'face 'magit-log-graph))
@@ -2999,11 +3216,12 @@ insert a line to tell how to insert more of them"
(magit-with-section "longer" 'longer
(insert "type \"e\" to show more logs\n")))))))
-(defun magit-wash-log-line ()
+(defun magit-wash-log-line (style)
(beginning-of-line)
- (let ((line-re magit-log-oneline-re))
+ (let ((line-re (cond ((eq style 'long) magit-log-longline-re)
+ (t magit-log-oneline-re))))
(cond
- ((looking-at magit-log-oneline-re)
+ ((looking-at line-re)
(let ((chart (match-string 1))
(sha1 (match-string 2))
(msg (match-string 4))
@@ -3029,9 +3247,9 @@ insert a line to tell how to insert more of them"
(forward-line)))
t))
-(defun magit-wash-log ()
+(defun magit-wash-log (&optional style)
(let ((magit-old-top-section nil))
- (magit-wash-sequence #'magit-wash-log-line)))
+ (magit-wash-sequence (apply-partially 'magit-wash-log-line style))))
(defvar magit-currently-shown-commit nil)
@@ -3253,30 +3471,34 @@ for this argument.)"
(list
(format "%s..HEAD" (magit-remote-branch-name remote branch)))))))
-(defun magit-remote-branch-for (local-branch &optional prepend-remote-name)
+(defun magit-remote-branch-for (local-branch &optional fully-qualified-name)
"Guess the remote branch name that LOCAL-BRANCH is tracking.
-Prepend \"remotes/\", the remote's name and \"/\" if
-PREPEND-REMOTE-NAME is non-nil."
+Gives a fully qualified name (e.g., refs/remotes/origin/master) if
+FULLY-QUALIFIED-NAME is non-nil."
(let ((merge (magit-get "branch" local-branch "merge")))
(save-match-data
(if (and merge (string-match "^refs/heads/\\(.+\\)" merge))
- (concat (if prepend-remote-name
- (concat "remotes/"
- (magit-get "branch" local-branch "remote")
- "/"))
+ (concat (if fully-qualified-name
+ (let ((remote-name (magit-get "branch" local-branch "remote")))
+ (if (string= "." remote-name)
+ "refs/heads/"
+ (concat "refs/remotes/" remote-name "/"))))
(match-string 1 merge))))))
;;; Status
(defvar magit-remote-string-hook nil)
-(defun magit-remote-string (remote remote-branch)
+(defun magit-remote-string (remote remote-branch remote-rebase)
(cond
((string= "." remote)
- (format "branch %s"
- (propertize remote-branch 'face 'magit-branch)))
+ (concat
+ (when remote-rebase "onto ")
+ "branch "
+ (propertize remote-branch 'face 'magit-branch)))
(remote
(concat
+ (when remote-rebase "onto ")
(propertize remote-branch 'face 'magit-branch)
" @ "
remote
@@ -3293,10 +3515,15 @@ PREPEND-REMOTE-NAME is non-nil."
(magit-with-section 'status nil
(let* ((branch (magit-get-current-branch))
(remote (and branch (magit-get "branch" branch "remote")))
+ (remote-rebase (and branch (magit-get-boolean "branch" branch "rebase")))
(remote-branch (or (and branch (magit-remote-branch-for branch)) branch))
- (remote-string (magit-remote-string remote remote-branch))
+ (remote-string (magit-remote-string remote remote-branch remote-rebase))
(head (magit-git-string
- "log" "--max-count=1" "--abbrev-commit" "--pretty=oneline"))
+ "log"
+ "--max-count=1"
+ "--abbrev-commit"
+ (format "--abbrev=%s" magit-sha1-abbrev-length)
+ "--pretty=oneline"))
(no-commit (not head)))
(when remote-string
(insert "Remote: " remote-string "\n"))
@@ -3306,7 +3533,8 @@ PREPEND-REMOTE-NAME is non-nil."
(abbreviate-file-name default-directory)))
(insert (format "Head: %s\n"
(if no-commit "nothing commited (yet)" head)))
- (let ((merge-heads (magit-file-lines ".git/MERGE_HEAD")))
+ (let ((merge-heads (magit-file-lines (concat (magit-git-dir)
+ "MERGE_HEAD"))))
(if merge-heads
(insert (format "Merging: %s\n"
(mapconcat 'identity
@@ -3332,18 +3560,20 @@ PREPEND-REMOTE-NAME is non-nil."
(defun magit-init (dir)
"Initialize git repository in the DIR directory."
(interactive (list (read-directory-name "Directory for Git repository: ")))
- (let ((topdir (magit-get-top-dir dir)))
+ (let* ((dir (file-name-as-directory (expand-file-name dir)))
+ (topdir (magit-get-top-dir dir)))
(when (or (not topdir)
(yes-or-no-p
(format
- (if (string-equal topdir (expand-file-name dir))
+ (if (string-equal topdir dir)
"There is already a Git repository in %s. Reinitialize? "
"There is a Git repository in %s. Create another in %s? ")
topdir dir)))
(unless (file-directory-p dir)
(and (y-or-n-p (format "Directory %s does not exists. Create it? " dir))
(make-directory dir)))
- (magit-run* (list magit-git-executable "init" dir)))))
+ (let ((default-directory dir))
+ (magit-run* (list magit-git-executable "init"))))))
(define-derived-mode magit-status-mode magit-mode "Magit"
"Mode for looking at git status.
@@ -3427,6 +3657,18 @@ user input."
(if revision
(magit-run-git "merge" (magit-rev-to-git revision))))
+(magit-define-command manual-merge (revision)
+ "Merge REVISION into the current 'HEAD'; commit unless merge fails.
+\('git merge REVISION')."
+ (interactive (list (magit-read-rev "Merge" (magit-guess-branch))))
+ (when revision
+ (apply 'magit-run-git
+ "merge" "--no-commit"
+ (magit-rev-to-git revision)
+ magit-custom-options)
+ (when (file-exists-p ".git/MERGE_MSG")
+ (magit-log-edit))))
+
;;; Staging and Unstaging
(defun magit-stage-item (&optional ask)
@@ -3598,46 +3840,85 @@ Fails if working tree or staging area contain uncommitted changes.
(magit-rev-to-git parent)))
(magit-update-vc-modeline default-directory)))
-(defun magit-delete-branch (branch)
- "Asks for a branch and deletes it.
+(defun magit-delete-branch (branch &optional force)
+ "Deletes a branch.
If the branch is the current one, offers to switch to `master' first.
-\('git branch -d BRANCH')."
- (interactive (list (magit-read-rev "Branch to delete" (magit-default-rev))))
- (when (and branch (string= branch (magit-get-current-branch)))
- (if (y-or-n-p "Cannot delete current branch. Switch to master first? ")
- (magit-checkout "master")
- (setq branch nil)))
- (when branch
- (magit-run-git "branch" "-d" (append magit-custom-options
- (magit-rev-to-git branch)))))
-
-(defun magit-delete-branch-forced (branch)
- "Asks for a branch and deletes it, irrespective of its merged status.
-If the branch is the current one, offers to switch to `master' first.
-\('git branch -D BRANCH')."
- (interactive (list (magit-read-rev "Branch to force delete" (magit-default-rev))))
- (when (and branch (string= branch (magit-get-current-branch)))
- (if (y-or-n-p "Cannot delete current branch. Switch to master first? ")
- (magit-checkout "master")
- (setq branch nil)))
- (when branch
- (magit-run-git "branch" "-D" (append magit-custom-options
- (magit-rev-to-git branch)))))
-
-(defun magit-move-branch (old new)
+With prefix, forces the removal even if it hasn't been merged.
+Works with local or remote branches.
+\('git branch [-d|-D] BRANCH' or 'git push <remote-part-of-BRANCH> :refs/heads/BRANCH')."
+ (interactive (list (magit-read-rev "Branch to delete" (magit-default-rev 'notrim))
+ current-prefix-arg))
+ (let* ((remote (magit-remote-part-of-branch branch))
+ (is-current (string= branch (magit-get-current-branch)))
+ (args (list "branch"
+ (if force "-D" "-d")
+ branch)))
+ (cond
+ (remote
+ (magit-run-git "push" remote (concat ":refs/heads/" (magit-branch-no-remote branch))))
+ (is-current
+ (when (y-or-n-p "Cannot delete current branch. Switch to master first? ")
+ (progn
+ (magit-checkout "master")
+ (apply 'magit-run-git args))
+ (message "The current branch was not deleted.")))
+ (t
+ (apply 'magit-run-git args)))))
+
+(defun magit-move-branch (old new &optional force)
"Renames or moves a branch.
-\('git branch -m OLD NEW')."
+With prefix, forces the move even if NEW already exists.
+\('git branch [-m|-M] OLD NEW')."
(interactive (list (magit-read-rev "Old name" (magit-default-rev))
- (read-string "New name: ")))
- (magit-run-git "branch" "-m" (magit-rev-to-git old) new))
+ (read-string "New name: ")
+ current-prefix-arg))
+ (magit-run-git "branch" (if force
+ "-M"
+ "-m")
+ (magit-rev-to-git old) new))
(defun magit-guess-branch ()
(magit-section-case (item info)
+ ((branch)
+ (magit-section-info (magit-current-section)))
((wazzup commit)
(magit-section-info (magit-section-parent item)))
- ((commit) (magit-name-rev (substring info 0 8)))
+ ((commit) (magit-name-rev (substring info 0 magit-sha1-abbrev-length)))
((wazzup) info)))
+;;; Remotes
+
+(defun magit-add-remote (remote url)
+ "Adds a remote and fetches it.
+\('git remote add REMOTE URL')."
+ (interactive (list (read-string "Add remote: ")
+ (read-string "URL: ")))
+ (magit-run-git "remote" "add" "-f" remote url))
+
+(defun magit-remove-remote (remote)
+ "Deletes a remote.
+\('git remote rm REMOTE')."
+ (interactive (list (magit-read-remote "Remote to delete")))
+ (magit-run-git "remote" "rm" remote))
+
+(defun magit-rename-remote (old new)
+ "Renames a remote.
+\('git remote rename OLD NEW')."
+ (interactive (list (magit-read-remote "Old name")
+ (read-string "New name: ")))
+ (magit-run-git "remote" "rename" old new))
+
+(defun magit-guess-remote ()
+ (magit-section-case (item info)
+ ((branch)
+ (magit-section-info (magit-section-parent item)))