Update magit
authorJoerg Jaspert <joerg@debian.org>
Sun, 11 May 2014 11:59:39 +0000 (13:59 +0200)
committerJoerg Jaspert <joerg@debian.org>
Sun, 11 May 2014 12:00:53 +0000 (14:00 +0200)
24 files changed:
.emacs.d/config/emacs.org
.emacs.d/config/gkar.ganneff.de.org
.emacs.d/elisp/git-commit-mode/git-commit-mode-autoloads.el [new file with mode: 0644]
.emacs.d/elisp/git-commit-mode/git-commit-mode-pkg.el [new file with mode: 0644]
.emacs.d/elisp/git-commit-mode/git-commit-mode.el [new file with mode: 0644]
.emacs.d/elisp/git-rebase-mode/git-rebase-mode-autoloads.el [new file with mode: 0644]
.emacs.d/elisp/git-rebase-mode/git-rebase-mode-pkg.el [new file with mode: 0644]
.emacs.d/elisp/git-rebase-mode/git-rebase-mode.el [new file with mode: 0644]
.emacs.d/elisp/magit/AUTHORS.md [new file with mode: 0644]
.emacs.d/elisp/magit/README.md [new file with mode: 0644]
.emacs.d/elisp/magit/dir [new file with mode: 0644]
.emacs.d/elisp/magit/magit-autoloads.el
.emacs.d/elisp/magit/magit-bisect.el [deleted file]
.emacs.d/elisp/magit/magit-blame.el
.emacs.d/elisp/magit/magit-key-mode.el
.emacs.d/elisp/magit/magit-pkg.el
.emacs.d/elisp/magit/magit-stgit.el [deleted file]
.emacs.d/elisp/magit/magit-svn.el [deleted file]
.emacs.d/elisp/magit/magit-topgit.el [deleted file]
.emacs.d/elisp/magit/magit-wip.el
.emacs.d/elisp/magit/magit.el
.emacs.d/elisp/magit/magit.info [new file with mode: 0644]
.emacs.d/elisp/magit/magitload.el [deleted file]
.emacs.d/elisp/magit/rebase-mode.el [deleted file]

index 7b8063c..daf848f 100644 (file)
@@ -81,7 +81,7 @@ one variable and go over that in a loop.
                            cedet/eieio ecb jdee/lisp sunrise multiple-cursors
                            auto-complete yasnippet magit mmm emms/lisp
                            elpy find-file-in-project fuzzy idomenu nose
                            cedet/eieio ecb jdee/lisp sunrise multiple-cursors
                            auto-complete yasnippet magit mmm emms/lisp
                            elpy find-file-in-project fuzzy idomenu nose
-                           popup pyvenv)
+                           popup pyvenv git-rebase-mode git-commit-mode)
   "List of subdirectories in jj-elisp-dir to add to load-path")
 
 (let (dirval)
   "List of subdirectories in jj-elisp-dir to add to load-path")
 
 (let (dirval)
index 3020d6f..7c2516e 100644 (file)
@@ -16,26 +16,26 @@ No need to run an smtpd on this host, my router does that. So use it.
 First specific point is how I access my mail. I am using gnus, and I
 have two hosts to get data from.
 #+BEGIN_SRC emacs-lisp
 First specific point is how I access my mail. I am using gnus, and I
 have two hosts to get data from.
 #+BEGIN_SRC emacs-lisp
-  (setq gnus-secondary-select-methods
-        '((nnml "")
-          (nnimap "gkar"
-                  (nnimap-address "localhost")
-                  (nnimap-server-port 993)
-                  (nnimap-nov-is-evil t)
-                  (nnimap-stream ssl)
-                  (nnimap-fetch-partial-articles "text/")
-                  ;(nnimap-stream shell)
-                  ;(nnir-search-engine imap)
-                      )
-          (nnimap "fry"
-                  (nnimap-address "fry.nsb-software.de")
-                  (nnimap-server-port 993)
-                  (nnimap-stream ssl)
-                  (nnimap-nov-is-evil t)
-                  (nnimap-fetch-partial-articles "text/")
-                  (nnir-search-engine imap)
-                  )
-          ))
+(setq gnus-secondary-select-methods
+      '((nnml "")
+        (nnimap "gkar"
+                (nnimap-address "localhost")
+                (nnimap-server-port 993)
+                (nnimap-nov-is-evil t)
+                (nnimap-stream ssl)
+                ;(nnimap-fetch-partial-articles "text/")
+                ;(nnimap-stream shell)
+                ;(nnir-search-engine imap)
+                    )
+        (nnimap "fry"
+                (nnimap-address "fry.nsb-software.de")
+                (nnimap-server-port 993)
+                (nnimap-stream ssl)
+                (nnimap-nov-is-evil t)
+                ;(nnimap-fetch-partial-articles "text/")
+                (nnir-search-engine imap)
+                )
+        ))
 #+END_SRC
 
 Together with the above I do have a =~/.authinfo= file which has lines
 #+END_SRC
 
 Together with the above I do have a =~/.authinfo= file which has lines
diff --git a/.emacs.d/elisp/git-commit-mode/git-commit-mode-autoloads.el b/.emacs.d/elisp/git-commit-mode/git-commit-mode-autoloads.el
new file mode 100644 (file)
index 0000000..ff5c548
--- /dev/null
@@ -0,0 +1,28 @@
+;;; git-commit-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+\f
+;;;### (autoloads nil "git-commit-mode" "git-commit-mode.el" (21359
+;;;;;;  22739 213099 475000))
+;;; Generated autoloads from git-commit-mode.el
+
+(autoload 'git-commit-mode "git-commit-mode" "\
+Major mode for editing git commit messages.
+
+This mode helps with editing git commit messages both by
+providing commands to do common tasks, and by highlighting the
+basic structure of and errors in git commit messages.
+
+\(fn)" t nil)
+
+(dolist (pattern '("/COMMIT_EDITMSG\\'" "/NOTES_EDITMSG\\'" "/MERGE_MSG\\'" "/TAG_EDITMSG\\'" "/PULLREQ_EDITMSG\\'")) (add-to-list 'auto-mode-alist (cons pattern 'git-commit-mode)))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; git-commit-mode-autoloads.el ends here
diff --git a/.emacs.d/elisp/git-commit-mode/git-commit-mode-pkg.el b/.emacs.d/elisp/git-commit-mode/git-commit-mode-pkg.el
new file mode 100644 (file)
index 0000000..d760329
--- /dev/null
@@ -0,0 +1 @@
+(define-package "git-commit-mode" "20140313.1504" "Major mode for editing git commit messages" 'nil)
diff --git a/.emacs.d/elisp/git-commit-mode/git-commit-mode.el b/.emacs.d/elisp/git-commit-mode/git-commit-mode.el
new file mode 100644 (file)
index 0000000..65842c0
--- /dev/null
@@ -0,0 +1,663 @@
+;;; git-commit-mode.el --- Major mode for editing git commit messages -*- lexical-binding: t; -*-
+
+;; Copyright (c) 2010-2012  Florian Ragwitz
+;; Copyright (c) 2012-2013  Sebastian Wiesner
+;; Copyright (C) 2010-2014  The Magit Project Developers
+
+;; Authors: Jonas Bernoulli <jonas@bernoul.li>
+;;     Sebastian Wiesner <lunaryorn@gmail.com>
+;;     Florian Ragwitz <rafl@debian.org>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;; Version: 20140313.1504
+;; X-Original-Version: 0.14.0
+;; Homepage: https://github.com/magit/git-modes
+;; Keywords: convenience vc git
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this file.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A major mode for editing Git commit messages.
+
+;;;; Formatting
+
+;; Highlight the formatting of git commit messages and indicate errors according
+;; to the guidelines for commit messages (see
+;; http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
+;;
+;; Highlight the first line (aka "summary") specially if it exceeds 50
+;; characters (configurable using `git-commit-summary-max-length').
+;;
+;; Enable `auto-fill-mode' and set the `fill-column' to 72 according to the
+;; aforementioned guidelines (configurable using `git-commit-fill-column').
+
+;;;; Headers
+
+;; Provide commands to insert standard headers into commit messages.
+;;
+;; - C-c C-s inserts Signed-off-by (`git-commit-signoff').
+;; - C-C C-a inserts Acked-by (`git-commit-ack').
+;; - C-c C-t inserts Tested-by (`git-commit-test').
+;; - C-c C-r inserts Reviewed-by (`git-commit-review').
+;; - C-c C-o inserts Cc (`git-commit-cc').
+;; - C-c C-p inserts Reported-by (`git-commit-reported').
+
+;;;; Committing
+
+;; C-c C-c finishes a commit.
+;;
+;; Check a buffer for stylistic errors before committing, and ask for
+;; confirmation before committing with style errors.
+
+;;; Code:
+
+(require 'log-edit)
+(require 'ring)
+(require 'server)
+
+;;; Options
+;;;; Variables
+
+(defgroup git-commit nil
+  "Edit Git commit messages."
+  :prefix "git-commit-"
+  :group 'tools)
+
+(defcustom git-commit-confirm-commit nil
+  "Whether to ask for confirmation before committing.
+
+If t, ask for confirmation before creating a commit with style
+errors, unless the commit is forced.  If nil, never ask for
+confirmation before committing."
+  :group 'git-commit
+  :type '(choice (const :tag "On style errors" t)
+                 (const :tag "Never" nil)))
+
+(defcustom git-commit-mode-hook '(turn-on-auto-fill flyspell-mode)
+  "Hook run when entering Git Commit mode."
+  :options '(turn-on-auto-fill flyspell-mode git-commit-save-message)
+  :type 'hook
+  :group 'git-commit)
+
+(defcustom git-commit-kill-buffer-hook '(git-commit-save-message)
+  "Hook run when killing a Git Commit mode buffer.
+This hook is run by both `git-commit-commit'
+and `git-commit-abort'."
+  :options '(git-commit-save-message)
+  :type 'hook
+  :group 'git-commit)
+
+(defcustom git-commit-summary-max-length 50
+  "Fontify characters beyond this column in summary lines as errors."
+  :group 'git-commit
+  :type 'number)
+
+(defcustom git-commit-fill-column 72
+  "Automatically wrap commit message lines beyond this column."
+  :group 'git-commit
+  :type 'number)
+
+(defcustom git-commit-known-pseudo-headers
+  '("Signed-off-by" "Acked-by" "Cc"
+    "Suggested-by" "Reported-by" "Tested-by" "Reviewed-by")
+  "A list of git pseudo headers to be highlighted."
+  :group 'git-commit
+  :type '(repeat string))
+
+;;;; Faces
+
+(defgroup git-commit-faces nil
+  "Faces for highlighting Git commit messages."
+  :prefix "git-commit-"
+  :group 'git-commit
+  :group 'faces)
+
+(defface git-commit-summary-face
+  '((t :inherit font-lock-type-face))
+  "Face used to highlight the summary in git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-overlong-summary-face
+  '((t :inherit font-lock-warning-face))
+  "Face used to highlight overlong parts of git commit message summaries"
+  :group 'git-commit-faces)
+
+(defface git-commit-nonempty-second-line-face
+  '((t :inherit font-lock-warning-face))
+  "Face used to highlight text on the second line of git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-note-face
+  '((t :inherit font-lock-string-face))
+  "Face used to highlight notes in git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-pseudo-header-face
+  '((t :inherit font-lock-string-face))
+  "Font used to hightlight pseudo headers in git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-known-pseudo-header-face
+  '((t :inherit font-lock-keyword-face))
+  "Face used to hightlight common pseudo headers in git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-branch-face
+  '((t :inherit font-lock-variable-name-face))
+  "Face used to highlight the branch name in comments in git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-no-branch-face
+  '((t :inherit git-commit-branch-face))
+  "Face used when a commit is going to be made outside of any branches"
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-heading-face
+  '((t :inherit git-commit-known-pseudo-header-face))
+  "Face used to highlight section headings in the default
+comments in git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-file-face
+  '((t :inherit git-commit-pseudo-header-face))
+  "Face used to highlight file names in the default comments in
+git commit messages"
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-action-face
+  '((t :inherit git-commit-branch-face))
+  "Face used to highlight what has happened to files in the
+default comments in git commit messages"
+  :group 'git-commit-faces)
+
+;;; Keymap
+
+(defvar git-commit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-c") 'git-commit-commit)
+    (define-key map (kbd "C-c C-k") 'git-commit-abort)
+    (define-key map (kbd "C-c C-s") 'git-commit-signoff)
+    (define-key map (kbd "C-c C-a") 'git-commit-ack)
+    (define-key map (kbd "C-c C-t") 'git-commit-test)
+    (define-key map (kbd "C-c C-r") 'git-commit-review)
+    (define-key map (kbd "C-c C-o") 'git-commit-cc)
+    (define-key map (kbd "C-c C-p") 'git-commit-reported)
+    (define-key map (kbd "C-c C-i") 'git-commit-suggested)
+    (define-key map (kbd "C-c M-s") 'git-commit-save-message)
+    (define-key map (kbd "M-p")     'git-commit-prev-message)
+    (define-key map (kbd "M-n")     'git-commit-next-message)
+    (define-key map [remap server-edit]          'git-commit-commit)
+    (define-key map [remap kill-buffer]          'git-commit-abort)
+    (define-key map [remap ido-kill-buffer]      'git-commit-abort)
+    (define-key map [remap iswitchb-kill-buffer] 'git-commit-abort)
+    ;; Old bindings to avoid confusion
+    (define-key map (kbd "C-c C-x s") 'git-commit-signoff)
+    (define-key map (kbd "C-c C-x a") 'git-commit-ack)
+    (define-key map (kbd "C-c C-x t") 'git-commit-test)
+    (define-key map (kbd "C-c C-x r") 'git-commit-review)
+    (define-key map (kbd "C-c C-x o") 'git-commit-cc)
+    (define-key map (kbd "C-c C-x p") 'git-commit-reported)
+    map)
+  "Key map used by `git-commit-mode'.")
+
+;;; Menu
+
+(require 'easymenu)
+(easy-menu-define git-commit-mode-menu git-commit-mode-map
+  "Git Commit Mode Menu"
+  '("Commit"
+    ["Previous" git-commit-prev-message t]
+    ["Next" git-commit-next-message t]
+    "-"
+    ["Ack" git-commit-ack :active t
+     :help "Insert an 'Acked-by' header"]
+    ["Sign-Off" git-commit-signoff :active t
+     :help "Insert a 'Signed-off-by' header"]
+    ["Tested-by" git-commit-test :active t
+     :help "Insert a 'Tested-by' header"]
+    ["Reviewed-by" git-commit-review :active t
+     :help "Insert a 'Reviewed-by' header"]
+    ["CC" git-commit-cc t
+     :help "Insert a 'Cc' header"]
+    ["Reported" git-commit-reported :active t
+     :help "Insert a 'Reported-by' header"]
+    ["Suggested" git-commit-suggested t
+     :help "Insert a 'Suggested-by' header"]
+    "-"
+    ["Save" git-commit-save-message t]
+    ["Cancel" git-commit-abort t]
+    ["Commit" git-commit-commit t]))
+
+;;; Committing
+
+(defvar git-commit-commit-hook nil
+  "Hook run by `git-commit-commit' unless clients exist.
+Only use this if you know what you are doing.")
+
+(defvar git-commit-previous-winconf nil)
+
+(defmacro git-commit-restore-previous-winconf (&rest body)
+  "Run BODY and then restore `git-commit-previous-winconf'.
+When `git-commit-previous-winconf' is nil or was created from
+another frame do nothing."
+  (declare (indent 0))
+  (let ((winconf (make-symbol "winconf"))
+        (frame   (make-symbol "frame")))
+    `(let ((,winconf git-commit-previous-winconf)
+           (,frame (selected-frame)))
+       ,@body
+       (when (and ,winconf
+                  (equal ,frame (window-configuration-frame ,winconf)))
+         (set-window-configuration ,winconf)
+         (setq git-commit-previous-winconf nil)))))
+
+(defun git-commit-commit (&optional force)
+  "Finish editing the commit message and commit.
+
+Check for stylistic errors in the current commit, and ask the
+user for confirmation depending on `git-commit-confirm-commit'.
+If FORCE is non-nil or if a raw prefix arg is given, commit
+immediately without asking.
+
+Return t, if the commit was successful, or nil otherwise."
+  (interactive "P")
+  (if (and git-commit-confirm-commit
+           (git-commit-has-style-errors-p)
+           (not force)
+           (not (y-or-n-p "Commit despite stylistic errors?")))
+      (message "Commit canceled due to stylistic errors.")
+    (save-buffer)
+    (run-hooks 'git-commit-kill-buffer-hook)
+    (remove-hook 'kill-buffer-query-functions
+                 'git-commit-kill-buffer-noop t)
+    (git-commit-restore-previous-winconf
+      (if (git-commit-buffer-clients)
+          (server-edit)
+        (run-hook-with-args 'git-commit-commit-hook)
+        (kill-buffer)))))
+
+(defun git-commit-abort ()
+  "Abort the commit.
+The commit message is saved to the kill ring."
+  (interactive)
+  (when (< emacs-major-version 24)
+    ;; Emacsclient doesn't exit with non-zero when -error is used.
+    ;; Instead cause Git to error out by feeding it an empty file.
+    (erase-buffer))
+  (save-buffer)
+  (run-hooks 'git-commit-kill-buffer-hook)
+  (remove-hook 'kill-buffer-hook 'server-kill-buffer t)
+  (remove-hook 'kill-buffer-query-functions 'git-commit-kill-buffer-noop t)
+  (git-commit-restore-previous-winconf
+    (let ((buffer  (current-buffer))
+          (clients (git-commit-buffer-clients)))
+      (if clients
+          (progn
+            (dolist (client clients)
+              (ignore-errors
+                (server-send-string client "-error Commit aborted by user"))
+              (delete-process client))
+            (when (buffer-live-p buffer)
+              (kill-buffer buffer)))
+        (kill-buffer))))
+  (accept-process-output nil 0.1)
+  (message (concat "Commit aborted."
+                   (when (memq 'git-commit-save-message
+                               git-commit-kill-buffer-hook)
+                     "  Message saved to `log-edit-comment-ring'."))))
+
+(defun git-commit-buffer-clients ()
+  (and (fboundp 'server-edit)
+       (boundp 'server-buffer-clients)
+       server-buffer-clients))
+
+;;; History
+
+(defun git-commit-save-message ()
+  "Save current message to `log-edit-comment-ring'."
+  (interactive)
+  (let ((message (buffer-substring
+                  (point-min)
+                  (git-commit-find-pseudo-header-position))))
+    (when (and (string-match "^\\s-*\\sw" message)
+               (or (ring-empty-p log-edit-comment-ring)
+                   (not (ring-member log-edit-comment-ring message))))
+      ;; if index is nil, we end up cycling back to message we just saved!
+      (unless log-edit-comment-ring-index
+        (setq log-edit-comment-ring-index 0))
+      (ring-insert log-edit-comment-ring message))))
+
+(defun git-commit-prev-message (arg)
+  "Cycle backward through message history, after saving current message.
+With a numeric prefix ARG, go back ARG comments."
+  (interactive "*p")
+  (git-commit-save-message)
+  (save-restriction
+    (narrow-to-region (point-min) (git-commit-find-pseudo-header-position))
+    (log-edit-previous-comment arg)))
+
+(defun git-commit-next-message (arg)
+  "Cycle forward through message history, after saving current message.
+With a numeric prefix ARG, go forward ARG comments."
+  (interactive "*p")
+  (git-commit-prev-message (- arg)))
+
+;;; Headers
+
+(defun git-commit-find-pseudo-header-position ()
+  "Find the position at which commit pseudo headers should be inserted.
+
+Those headers usually live at the end of a commit message, but
+before any trailing comments git or the user might have
+inserted."
+  (save-excursion
+    (goto-char (point-max))
+    (if (re-search-backward "^[^#\n]" nil t)
+        ;; we found last non-empty non-comment line, headers go after
+        (forward-line 1)
+      ;; there's only blanks & comments, headers go before comments
+      (goto-char (point-min))
+      (and (re-search-forward "^#" nil t) (forward-line 0)))
+    (skip-chars-forward "\n")
+    (point)))
+
+(defun git-commit-determine-pre-for-pseudo-header ()
+  "Find the characters to insert before the pseudo header.
+Returns either zero, one or two newlines after computation.
+
+`point' either points to an empty line (with a non-empty previous
+line) or the end of a non-empty line."
+  (let ((pre "")
+        (prev-line nil))
+    (if (not (eq (point) (point-at-bol)))
+        (progn
+          (setq pre (concat pre "\n"))
+          (setq prev-line (thing-at-point 'line)))
+      ;; else: (point) is at an empty line
+      (when (not (eq (point) (point-min)))
+        (setq prev-line
+              (save-excursion
+                (forward-line -1)
+                (thing-at-point 'line)))))
+
+    ;; we have prev-line now; if it doesn't match any known pseudo
+    ;; header, add a newline
+    (when prev-line
+      (if (not (delq nil (mapcar (lambda (pseudo-header)
+                                   (string-match pseudo-header prev-line))
+                                 git-commit-known-pseudo-headers)))
+          (setq pre (concat pre "\n"))))
+    pre))
+
+(defun git-commit-insert-header (type name email)
+  "Insert a header into the commit message.
+The inserted header has the format 'TYPE: NAME <EMAIL>'.
+
+The header is inserted at the position returned by
+`git-commit-find-pseudo-header-position'.  When this position
+isn't after an existing header or a newline, an extra newline is
+inserted before the header."
+  (let ((header-at (git-commit-find-pseudo-header-position)))
+    (save-excursion
+      (goto-char header-at)
+      (let ((pre (git-commit-determine-pre-for-pseudo-header)))
+        (insert (format "%s%s: %s <%s>\n" pre type name email))))))
+
+(defun git-commit-insert-header-as-self (type)
+  "Insert a header with the name and email of the current user.
+The inserted header has the format 'TYPE: NAME <EMAIL>'.
+Also see `git-commit-insert-header'."
+  (git-commit-insert-header
+   type
+   (or (getenv "GIT_AUTHOR_NAME")
+       (getenv "GIT_COMMITTER_NAME")
+       (ignore-errors (car (process-lines "git" "config" "user.name")))
+       user-full-name)
+   (or (getenv "GIT_AUTHOR_EMAIL")
+       (getenv "GIT_COMMITTER_EMAIL")
+       (getenv "EMAIL")
+       (ignore-errors (car (process-lines "git" "config" "user.email")))
+       user-mail-address)))
+
+(defmacro git-define-git-commit-self (action header)
+  "Create function git-commit-ACTION.
+ACTION will be part of the function name.
+HEADER is the actual header to be inserted into the comment."
+  (let ((func-name (intern (concat "git-commit-" action))))
+    `(defun ,func-name ()
+       ,(format "Insert a '%s' header at the end of the commit message.
+
+The author name and email address used for the header are
+retrieved automatically with the same mechanism git uses."
+                header)
+       (interactive)
+       (git-commit-insert-header-as-self ,header))))
+
+(git-define-git-commit-self "ack"     "Acked-by")
+(git-define-git-commit-self "review"  "Reviewed-by")
+(git-define-git-commit-self "signoff" "Signed-off-by")
+(git-define-git-commit-self "test"    "Tested-by")
+
+(defmacro git-define-git-commit (action header)
+  "Create interactive function git-commit-ACTION.
+ACTION will be part of the function name.
+HEADER is the actual header to be inserted into the comment."
+  (let ((func-name (intern (concat "git-commit-" action))))
+    `(defun ,func-name (name email)
+       ,(format "Insert a '%s' header at the end of the commit message.
+The value of the header is determined by NAME and EMAIL.
+
+When called interactively, both NAME and EMAIL are read from the
+minibuffer."
+                header)
+       (interactive
+        (list (read-string "Name: ")
+              (read-string "Email: ")))
+       (git-commit-insert-header ,header name email))))
+
+(git-define-git-commit "cc"        "Cc")
+(git-define-git-commit "reported"  "Reported-by")
+(git-define-git-commit "suggested" "Suggested-by")
+
+(defconst git-commit-comment-headings-alist
+  '(("Not currently on any branch."   . git-commit-no-branch-face)
+    ("Changes to be committed:"       . git-commit-comment-heading-face)
+    ("Untracked files:"               . git-commit-comment-heading-face)
+    ("Changed but not updated:"       . git-commit-comment-heading-face)
+    ("Changes not staged for commit:" . git-commit-comment-heading-face)
+    ("Unmerged paths:"                . git-commit-comment-heading-face))
+  "Headings in message comments.
+
+The `car' of each cell is the heading text, the `cdr' the face to
+use for fontification.")
+
+(defun git-commit-summary-regexp ()
+  (concat
+   ;; Skip empty lines or comments before the summary
+   "\\`\\(?:^\\(?:\\s-*\\|\\s<.*\\)\n\\)*"
+   ;; The summary line
+   (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length)
+   ;; Non-empty non-comment second line
+   ;;
+   ;; For instant highlighting of non-empty second lines in font-lock,
+   ;; the last capturing group must capture the empty string ("") in
+   ;; "summary line\n".
+   ;; That's why the simpler regex "\\(?:\n\\([^\n#].*\\)\\)?",
+   ;; which captures 'nil', can't be used.
+   "\\(?:\n\\#\\|\n\\(.*\\)\\)?"))
+
+(defun git-commit-has-style-errors-p ()
+  "Check whether the current buffer has style errors.
+
+Return t, if the current buffer has style errors, or nil
+otherwise."
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward (git-commit-summary-regexp) nil t)
+      (or (string-match-p ".+" (or (match-string 2) ""))
+          (string-match-p "^.+$" (or (match-string 3) ""))))))
+
+;;; Font-Lock
+
+(defun git-commit-mode-summary-font-lock-keywords (&optional errors)
+  "Create font lock keywords to fontify the Git summary.
+
+If ERRORS is non-nil create keywords that highlight errors in the
+summary line, not the summary line itself."
+  (if errors
+      `(,(git-commit-summary-regexp)
+        (2 'git-commit-overlong-summary-face t t)
+        (3 'git-commit-nonempty-second-line-face t t))
+    `(,(git-commit-summary-regexp)
+      (1 'git-commit-summary-face t))))
+
+(defun git-commit-mode-heading-keywords ()
+  "Create font lock keywords to fontify comment headings.
+
+Known comment headings are provided by `git-commit-comment-headings'."
+  (mapcar (lambda (cell) `(,(format "^\\s<\\s-+\\(%s\\)$"
+                                    (regexp-quote (car cell)))
+                           (1 ',(cdr cell) t)))
+          git-commit-comment-headings-alist))
+
+(defun git-commit-mode-font-lock-keywords ()
+  (append
+   `(("^\\s<.*$" . 'font-lock-comment-face)
+     ("^\\s<\\s-On branch \\(.*\\)$" (1 'git-commit-branch-face t))
+     ("^\\s<\t\\(?:\\([^:]+\\):\\s-+\\)?\\(.*\\)$"
+      (1 'git-commit-comment-action-face t t)
+      (2 'git-commit-comment-file-face t))
+     (,(concat "^\\("
+               (regexp-opt git-commit-known-pseudo-headers)
+               ":\\)\\(\s.*\\)$")
+      (1 'git-commit-known-pseudo-header-face)
+      (2 'git-commit-pseudo-header-face))
+     ("^\\<\\S-+:\\s-.*$" . 'git-commit-pseudo-header-face)
+     (eval . (git-commit-mode-summary-font-lock-keywords))
+     ("\\[[^\n]+?\\]" (0 'git-commit-note-face t)) ; Notes override summary line
+     ;; Warnings from overlong lines and nonempty second line override
+     ;; everything
+     (eval . (git-commit-mode-summary-font-lock-keywords t)))
+   (git-commit-mode-heading-keywords)))
+
+(defun git-commit-font-lock-diff ()
+  "Add font lock on diff."
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward "^diff --git" nil t)
+      (let ((beg (match-beginning 0)))
+        (let* ((buffer (current-buffer))
+               (font-lock-verbose nil)
+               (font-lock-support-mode nil)
+               (text (with-temp-buffer
+                       (insert
+                        (with-current-buffer buffer
+                          (buffer-substring-no-properties beg (point-max))))
+                       (diff-mode)
+                       (font-lock-fontify-buffer)
+                       (let ((pos (point-min))
+                             next)
+                         (while (setq next (next-single-property-change pos 'face))
+                           (put-text-property pos next 'font-lock-face
+                                              (get-text-property pos 'face))
+                           (setq pos next)))
+                       (buffer-string))))
+          (delete-region beg (point-max))
+          (insert text))))))
+
+;;; Mode
+
+(defvar git-commit-mode-syntax-table
+  (let ((table (make-syntax-table text-mode-syntax-table)))
+    (modify-syntax-entry ?#  "<" table)
+    (modify-syntax-entry ?\n ">" table)
+    (modify-syntax-entry ?\r ">" table)
+    table)
+  "Syntax table used by `git-commit-mode'.")
+
+;;;###autoload
+(define-derived-mode git-commit-mode text-mode "Git Commit"
+  "Major mode for editing git commit messages.
+
+This mode helps with editing git commit messages both by
+providing commands to do common tasks, and by highlighting the
+basic structure of and errors in git commit messages."
+  ;; Font locking
+  (setq font-lock-defaults (list (git-commit-mode-font-lock-keywords) t))
+  (set (make-local-variable 'font-lock-multiline) t)
+  (git-commit-font-lock-diff)
+  ;; Filling according to the guidelines
+  (setq fill-column git-commit-fill-column)
+  ;; Recognize changelog-style paragraphs
+  (set (make-local-variable 'paragraph-start)
+       (concat paragraph-start "\\|*\\|("))
+  ;; Treat lines starting with a hash/pound as comments
+  (set (make-local-variable 'comment-start) "#")
+  (set (make-local-variable 'comment-start-skip)
+       (concat "^" (regexp-quote comment-start) "+"
+               "\\s-*"))
+  (set (make-local-variable 'comment-use-syntax) nil)
+  ;; Do not remember point location in commit messages
+  (when (boundp 'save-place)
+    (setq save-place nil))
+  ;; If the commit summary is empty, insert a newline after point
+  (when (string= "" (buffer-substring-no-properties
+                     (line-beginning-position)
+                     (line-end-position)))
+    (open-line 1))
+  ;; Make sure `git-commit-abort' cannot be by-passed
+  (add-hook 'kill-buffer-query-functions
+            'git-commit-kill-buffer-noop nil t)
+  ;; Make the wrong usage info from `server-execute' go way
+  (run-with-timer 0.01 nil (lambda (m) (message "%s" m))
+                  (substitute-command-keys
+                   (concat "Type \\[git-commit-commit] "
+                           (let ((n (buffer-file-name)))
+                             (cond ((equal n "TAG_EDITMSG") "to tag")
+                                   ((or (equal n "NOTES_EDITMSG")
+                                        (equal n "PULLREQ_EDITMSG"))
+                                    "when done")
+                                   (t "to commit")))
+                           " (\\[git-commit-abort] to abort)."))))
+
+(defun git-commit-kill-buffer-noop ()
+  (message
+   (substitute-command-keys
+    "Don't kill this buffer.  Instead abort using \\[git-commit-abort]."))
+  nil)
+
+(defun git-commit-mode-flyspell-verify ()
+  (not (nth 4 (syntax-ppss)))) ; not inside a comment
+
+(eval-after-load 'flyspell
+  '(put 'git-commit-mode 'flyspell-mode-predicate
+        'git-commit-mode-flyspell-verify))
+
+;;;###autoload
+(dolist (pattern '("/COMMIT_EDITMSG\\'" "/NOTES_EDITMSG\\'"
+                   "/MERGE_MSG\\'" "/TAG_EDITMSG\\'"
+                   "/PULLREQ_EDITMSG\\'"))
+  (add-to-list 'auto-mode-alist (cons pattern 'git-commit-mode)))
+
+(defun git-commit-auto-mode-enable ()
+  (message "git-commit-auto-mode-enable is obsolete and doesn't do anything"))
+(make-obsolete 'git-commit-auto-mode-enable "This mode is a noop now" "")
+
+(provide 'git-commit-mode)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; git-commit-mode.el ends here
diff --git a/.emacs.d/elisp/git-rebase-mode/git-rebase-mode-autoloads.el b/.emacs.d/elisp/git-rebase-mode/git-rebase-mode-autoloads.el
new file mode 100644 (file)
index 0000000..1a27e7c
--- /dev/null
@@ -0,0 +1,29 @@
+;;; git-rebase-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+\f
+;;;### (autoloads nil "git-rebase-mode" "git-rebase-mode.el" (21359
+;;;;;;  22737 937093 148000))
+;;; Generated autoloads from git-rebase-mode.el
+
+(autoload 'git-rebase-mode "git-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\\'" . git-rebase-mode))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; git-rebase-mode-autoloads.el ends here
diff --git a/.emacs.d/elisp/git-rebase-mode/git-rebase-mode-pkg.el b/.emacs.d/elisp/git-rebase-mode/git-rebase-mode-pkg.el
new file mode 100644 (file)
index 0000000..770dc1f
--- /dev/null
@@ -0,0 +1 @@
+(define-package "git-rebase-mode" "20140313.1504" "Major mode for editing git rebase files" 'nil)
diff --git a/.emacs.d/elisp/git-rebase-mode/git-rebase-mode.el b/.emacs.d/elisp/git-rebase-mode/git-rebase-mode.el
new file mode 100644 (file)
index 0000000..e7bc9f2
--- /dev/null
@@ -0,0 +1,379 @@
+;;; git-rebase-mode.el --- Major mode for editing git rebase files
+
+;; Copyright (C) 2010-2014  The Magit Project Developers
+
+;; Author: Phil Jackson <phil@shellarchive.co.uk>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;; Version: 20140313.1504
+;; X-Original-Version: 0.14.0
+;; Homepage: https://github.com/magit/git-modes
+;; Keywords: convenience vc git
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this file.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Allows the editing of a git rebase file (which you might get when
+;; using 'git rebase -i' or hitting 'E' in Magit). Assumes editing is
+;; happening in a server.
+
+;;; Code:
+
+(require 'easymenu)
+(require 'server)
+(require 'thingatpt)
+
+;;; Options
+;;;; Variables
+
+(defgroup git-rebase nil
+  "Edit Git rebase sequences."
+  :group 'tools)
+
+(defcustom git-rebase-auto-advance nil
+  "If non-nil, moves point forward a line after running an action."
+  :group 'git-rebase
+  :type 'boolean)
+
+(defcustom git-rebase-remove-instructions nil
+  "Whether to remove the instructions from the rebase buffer.
+Because you have seen them before and can still remember."
+  :group 'git-rebase
+  :type 'boolean)
+
+;;;; Faces
+
+(defgroup git-rebase-faces nil
+  "Faces used by Git-Rebase mode."
+  :group 'faces
+  :group 'git-rebase)
+
+(defface git-rebase-hash
+  '((((class color) (background light))
+     :foreground "firebrick")
+    (((class color) (background dark))
+     :foreground "tomato"))
+  "Face for commit hashes."
+  :group 'git-rebase-faces)
+
+(defface git-rebase-description nil
+  "Face for commit descriptions."
+  :group 'git-rebase-faces)
+
+(defface git-rebase-killed-action
+  '((((class color))
+     :inherit font-lock-comment-face
+     :strike-through t))
+  "Face for commented action and exec lines."
+  :group 'git-rebase-faces)
+
+(define-obsolete-face-alias 'git-rebase-description-face
+  'git-rebase-description "1.0.0")
+(define-obsolete-face-alias 'git-rebase-killed-action-face
+  'git-rebase-killed-action "1.0.0")
+
+;;; Regexps
+
+(defconst git-rebase-action-line-re
+  (concat "^#?"
+          "\\([efprs]\\|pick\\|reword\\|edit\\|squash\\|fixup\\) "
+          "\\([a-z0-9]\\{4,40\\}\\) "
+          "\\(.*\\)")
+  "Regexp matching action lines in rebase buffers.")
+
+(defconst git-rebase-exec-line-re
+  "^#?\\(x\\|exec\\)[[:space:]]\\(.*\\)"
+  "Regexp matching exec lines in rebase buffer.")
+
+(defconst git-rebase-dead-line-re
+  (format "^#\\(?:%s\\|%s\\)"
+          (substring git-rebase-action-line-re 1)
+          (substring git-rebase-exec-line-re 1))
+  "Regexp matching commented action and exex lines in rebase buffers.")
+
+;;; Keymaps
+
+(defvar git-rebase-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map special-mode-map)
+    (define-key map (kbd "q")       'git-rebase-server-edit)
+    (define-key map (kbd "C-c C-c") 'git-rebase-server-edit)
+    (define-key map (kbd "a")       'git-rebase-abort)
+    (define-key map (kbd "C-c C-k") 'git-rebase-abort)
+    (define-key map [remap undo]    'git-rebase-undo)
+    (define-key map (kbd "RET") 'git-rebase-show-commit)
+    (define-key map (kbd "x")   'git-rebase-exec)
+    (define-key map (kbd "c")   'git-rebase-pick)
+    (define-key map (kbd "r")   'git-rebase-reword)
+    (define-key map (kbd "e")   'git-rebase-edit)
+    (define-key map (kbd "s")   'git-rebase-squash)
+    (define-key map (kbd "f")   'git-rebase-fixup)
+    (define-key map (kbd "k")   'git-rebase-kill-line)
+    (define-key map (kbd "C-k") 'git-rebase-kill-line)
+    (define-key map (kbd "p")   'git-rebase-backward-line)
+    (define-key map (kbd "n")   'forward-line)
+    (define-key map (kbd "M-p") 'git-rebase-move-line-up)
+    (define-key map (kbd "M-n") 'git-rebase-move-line-down)
+    (define-key map (kbd "M-<up>") 'git-rebase-move-line-up)
+    (define-key map (kbd "M-<down>") 'git-rebase-move-line-down)
+    map)
+  "Keymap for Git-Rebase mode.")
+
+(easy-menu-define git-rebase-mode-menu git-rebase-mode-map
+  "Git-Rebase mode menu"
+  '("Rebase"
+    ["Pick" git-rebase-pick t]
+    ["Reword" git-rebase-reword t]
+    ["Edit" git-rebase-edit t]
+    ["Squash" git-rebase-squash t]
+    ["Fixup" git-rebase-fixup t]
+    ["Kill" git-rebase-kill-line t]
+    ["Move Down" git-rebase-move-line-down t]
+    ["Move Up" git-rebase-move-line-up t]
+    ["Execute" git-rebase-exec t]
+    "---"
+    ["Abort" git-rebase-abort t]
+    ["Done" git-rebase-server-edit t]))
+
+;;; Utilities
+
+(defun git-rebase-edit-line (change-to)
+  (when (git-rebase-looking-at-action)
+    (let ((buffer-read-only nil)
+          (start (point)))
+      (goto-char (point-at-bol))
+      (delete-region (point) (progn (forward-word 1) (point)))
+      (insert change-to)
+      (goto-char start)
+      (when git-rebase-auto-advance
+        (forward-line)))))
+
+(defmacro git-rebase-define-action (sym)
+  (declare (indent defun))
+  (let ((fn (intern (format "git-rebase-%s" sym))))
+    `(progn
+       (defun ,fn ()
+        (interactive)
+        (git-rebase-edit-line ,(symbol-name sym)))
+       (put ',fn 'definition-name ',sym))))
+
+(defun git-rebase-looking-at-action ()
+  "Return non-nil if looking at an action line."
+  (save-excursion
+    (goto-char (point-at-bol))
+    (looking-at git-rebase-action-line-re)))
+
+(defun git-rebase-looking-at-action-or-exec ()
+  "Return non-nil if looking at an action line or exec line."
+  (save-excursion
+    (goto-char (point-at-bol))
+    (or (looking-at git-rebase-action-line-re)
+        (looking-at git-rebase-exec-line-re))))
+
+(defun git-rebase-looking-at-exec ()
+  "Return non-nil if cursor is on an exec line."
+  (string-match git-rebase-exec-line-re (thing-at-point 'line)))
+
+(defun git-rebase-looking-at-killed-exec ()
+  "Return non-nil if looking at an exec line that has been commented out."
+  (let ((line (thing-at-point 'line)))
+    (and (eq (aref line 0) ?#)
+         (string-match git-rebase-exec-line-re line))))
+
+;;; Commands
+
+(git-rebase-define-action pick)
+(git-rebase-define-action reword)
+(git-rebase-define-action edit)
+(git-rebase-define-action squash)
+(git-rebase-define-action fixup)
+
+(defun git-rebase-move-line-up ()
+  "Move the current action line up."
+  (interactive)
+  (when (git-rebase-looking-at-action-or-exec)
+    (let ((buffer-read-only nil)
+          (col (current-column)))
+      (goto-char (point-at-bol))
+      (unless (bobp)
+        (transpose-lines 1)
+        (forward-line -2))
+      (move-to-column col))))
+
+(defun git-rebase-move-line-down ()
+  "Assuming the next line is also an action line, move the current line down."
+  (interactive)
+  ;; if we're on an action and the next line is also an action
+  (when (and (git-rebase-looking-at-action-or-exec)
+             (save-excursion
+               (forward-line)
+               (git-rebase-looking-at-action-or-exec)))
+    (let ((buffer-read-only nil)
+          (col (current-column)))
+      (forward-line 1)
+      (transpose-lines 1)
+      (forward-line -1)
+      (move-to-column col))))
+
+(defun git-rebase-server-edit ()
+  "Save the action buffer and end the session."
+  (interactive)
+  (save-buffer)
+  (server-edit))
+
+(defun git-rebase-abort ()
+  "Abort this rebase.
+This is dune by emptying the buffer, saving and closing server
+connection."
+  (interactive)
+  (when (or (not (buffer-modified-p))
+            (y-or-n-p "Abort this rebase? "))
+    (let ((buffer-read-only nil))
+      (erase-buffer)
+      (save-buffer)
+      (server-edit))))
+
+(defun git-rebase-kill-line ()
+  "Kill the current action line."
+  (interactive)
+  (when (and (not (eq (char-after (point-at-bol)) ?#))
+             (git-rebase-looking-at-action-or-exec))
+    (beginning-of-line)
+    (let ((inhibit-read-only t))
+      (insert "#"))
+    (forward-line)))
+
+(defun git-rebase-exec (edit)
+  "Prompt the user for a shell command to be executed, and
+add it to the todo list.
+
+If the cursor is on a commented-out exec line, uncomment the
+current line instead of prompting.
+
+When the prefix argument EDIT is non-nil and the cursor is on an
+exec line, edit that line instead of inserting a new one.  If the
+exec line was commented out, also uncomment it."
+  (interactive "P")
+  (cond
+   ((and edit (git-rebase-looking-at-exec))
+    (let ((new-line (git-rebase-read-exec-line
+                     (match-string-no-properties 2 (thing-at-point 'line))))
+          (inhibit-read-only t))
+      (delete-region (point-at-bol) (point-at-eol))
+      (if (not (equal "" new-line))
+          (insert "exec " new-line)
+        (delete-char -1)
+        (forward-line))
+      (move-beginning-of-line nil)))
+   ((git-rebase-looking-at-killed-exec)
+    (save-excursion
+      (beginning-of-line)
+      (let ((buffer-read-only nil))
+        (delete-char 1))))
+   (t
+    (let ((inhibit-read-only t)
+          (line (git-rebase-read-exec-line)))
+      (unless (equal "" line)
+        (move-end-of-line nil)
+        (newline)
+        (insert (concat "exec " line))))
+    (move-beginning-of-line nil))))
+
+(defun git-rebase-read-exec-line (&optional initial-line)
+  (read-shell-command "Execute: " initial-line))
+
+(defun git-rebase-undo (&optional arg)
+  "A thin wrapper around `undo', which allows undoing in read-only buffers."
+  (interactive "P")
+  (let ((inhibit-read-only t))
+    (undo arg)))
+
+(defun git-rebase-show-commit (&optional arg)
+  "Show the commit on the current line if any."
+  (interactive "P")
+  (save-excursion
+    (goto-char (point-at-bol))
+    (when (looking-at git-rebase-action-line-re)
+      (let ((commit (match-string 2)))
+        (if (fboundp 'magit-show-commit)
+            (let ((default-directory (expand-file-name "../../")))
+              (magit-show-commit commit))
+          (shell-command (concat "git show " commit)))))))
+
+(defun git-rebase-backward-line (&optional n)
+  "Move N lines backward (forward if N is negative).
+Like `forward-line' but go into the opposite direction."
+  (interactive "p")
+  (forward-line (* n -1)))
+
+;;; Mode
+
+;;;###autoload
+(define-derived-mode git-rebase-mode special-mode "Git Rebase"
+  "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."
+  (setq font-lock-defaults '(git-rebase-mode-font-lock-keywords t t))
+  (when git-rebase-remove-instructions
+    (let ((inhibit-read-only t))
+      (flush-lines "^\\($\\|#\\)"))))
+
+(defvar git-rebase-mode-font-lock-keywords
+  `((,git-rebase-action-line-re
+     (1 font-lock-keyword-face)
+     (2 'git-rebase-hash)
+     (3 'git-rebase-description))
+    (,git-rebase-exec-line-re 1 font-lock-keyword-face)
+    ("^#.*"                   0 font-lock-comment-face)
+    (,git-rebase-dead-line-re 0 'git-rebase-killed-action t))
+  "Font lock keywords for Git-Rebase mode.")
+
+(defun git-rebase-mode-show-keybindings ()
+  "Modify the \"Commands:\" section of the comment Git generates
+at the bottom of the file so that in place of the one-letter
+abbreviation for the command, it shows the command's keybinding.
+By default, this is the same except for the \"pick\" command."
+  (save-excursion
+    (goto-char (point-min))
+    (while (search-forward-regexp "^#  \\(.\\), \\([[:alpha:]]+\\) = " nil t)
+      (let ((start (match-beginning 1))
+            (end (match-end 1))
+            (command (intern (concat "git-rebase-" (match-string 2)))))
+        (when (fboundp command)
+          (let ((overlay (make-overlay start end)))
+            (overlay-put
+             overlay 'display
+             (key-description (where-is-internal command nil t)))))))))
+
+(add-hook 'git-rebase-mode-hook 'git-rebase-mode-show-keybindings t)
+
+(defun git-rebase-mode-disable-before-save-hook ()
+  (set (make-local-variable 'before-save-hook) nil))
+
+(add-hook 'git-rebase-mode-hook 'git-rebase-mode-disable-before-save-hook)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist
+             '("/git-rebase-todo\\'" . git-rebase-mode))
+
+(provide 'git-rebase-mode)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; git-rebase-mode.el ends here
diff --git a/.emacs.d/elisp/magit/AUTHORS.md b/.emacs.d/elisp/magit/AUTHORS.md
new file mode 100644 (file)
index 0000000..e68eb3f
--- /dev/null
@@ -0,0 +1,170 @@
+Authors
+=======
+
+Also see https://github.com/magit/magit/graphs/contributors.
+Names below are sorted alphabetically.
+
+Author
+------
+
+- Marius Vollmer <marius.vollmer@gmail.com>
+
+Maintainer
+----------
+
+- Jonas Bernoulli <jonas@bernoul.li>
+
+Retired Maintainers
+-------------------
+
+- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
+- Peter J. Weisberg <pj@irregularexpressions.net>
+- Phil Jackson <phil@shellarchive.co.uk>
+- Rémi Vanicat <vanicat@debian.org>
+- Yann Hodique <yann.hodique@gmail.com>
+
+Contributors
+------------
+
+- aaa707 <aaa707b@gmail.com>
+- Aaron Culich <aculich@gmail.com>
+- Abdo Roig-Maranges <abdo.roig@gmail.com>
+- acple <silentsphere110@gmail.com>
+- Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+- Alan Falloon <alan.falloon@gmail.com>
+- Alexey Voinov <alexey.v.voinov@gmail.com>
+- Alex Ott <alexott@gmail.com>
+- Andreas Fuchs <asf@boinkor.net>
+- Andreas Liljeqvist <andreas.liljeqvist@robacks.se>
+- Andreas Rottmann <a.rottmann@gmx.at>
+- Andrei Chițu <andrei.chitu1@gmail.com>
+- Andrew Kirkpatrick <andrew.kirkpatrick@adelaide.edu.au>
+- Andrey Smirnov <andrew.smirnov@gmail.com>
+- Bastian Beischer <beischer@physik.rwth-aachen.de>
+- Ben Walton <bwalton@artsci.utoronto.ca>
+- Bradley Wright <brad@intranation.com>
+- Brandon W Maister <quodlibetor@gmail.com>
+- Brian Warner <warner@lothar.com>
+- Bryan Shell <bryan.shell@orbitz.com>
+- Chris Bernard <cebernard@gmail.com>
+- Chris Done <chrisdone@gmail.com>
+- Chris Moore <dooglus@gmail.com>
+- Chris Ring <chris@ringthis.com>
+- Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
+- Christian Kluge <ckfrakturfreak@web.de>
+- Christopher Monsanto <chris@monsan.to>
+- Cornelius Mika <cornelius.mika@gmail.com>
+- Craig Andera <candera@wangdera.com>
+- Dale Hagglund <dale.hagglund@gmail.com>
+- Damien Cassou <damien.cassou@gmail.com>
+- Daniel Brockman <daniel@gointeractive.se>
+- Daniel Farina <drfarina@acm.org>
+- Daniel Hackney <dan@haxney.org>
+- Dan LaManna <dan.lamanna@gmail.com>
+- David Abrahams <dave@boostpro.com>
+- David Hull <david.hull@openx.com>
+- David Wallin <david.wallin@gmail.com>
+- Divye Kapoor <divye@google.com>
+- Dominique Quatravaux <domq@google.com>
+- Eli Barzilay <eli@barzilay.org>
+- Eric Davis <ed@npri.org>
+- Eric Schulte <schulte.eric@gmail.com>
+- Evgkeni Sampelnikof <esabof@gmail.com>
+- Felix Geller <fgeller@gmail.com>
+- Feng Li <fengli@blackmagicdesign.com>
+- George Kadianakis <desnacked@gmail.com>
+- Graham Clark <grclark@gmail.com>
+- Greg A. Woods <woods@planix.com>
+- Greg Sexton <gregsexton@gmail.com>
+- Hannu Koivisto <azure@iki.fi>
+- Hans-Peter Deifel <hpdeifel@gmx.de>
+- Ian Eure <ian.eure@gmail.com>
+- Jasper St. Pierre <jstpierre@mecheye.net>
+- Jeff Bellegarde <jbellegarde@whitepages.com>
+- Jesse Alama <jesse.alama@gmail.com>
+- John Wiegley <johnw@newartisans.com>
+- Jonas Bernoulli <jonas@bernoul.li>
+- Jonathan Roes <jroes@jroes.net>
+- Julien Danjou <julien@danjou.info>
+- Justin Caratzas <justin.caratzas@gmail.com>
+- Kimberly Wolk <kimwolk@hotmail.com>
+- Kyle Meyer <kyle@kyleam.com>
+- Laurent Laffont <laurent.laffont@gmail.com>
+- Lele Gaifax <lele@metapensiero.it>
+- Leo Liu <sdl.web@gmail.com>
+- Leonardo Etcheverry <leo@kalio.net>
+- Lluís Vilanova <vilanova@ac.upc.edu>
+- Luís Borges de Oliveira <lbo@siscog.pt>
+- Luke Amdor <luke.amdor@gmail.com>
+- Manuel Vázquez Acosta <mva.led@gmail.com>
+- Marcel Wolf <mwolf@ml1.net>
+- Marc Herbert <marc.herbert@gmail.com>
+- Marcin Bachry <hegel666@gmail.com>
+- Marco Craveiro <marco.craveiro@gmail.com>
+- Marius Vollmer <marius.vollmer@gmail.com>
+- Mark Hepburn <Mark.Hepburn@csiro.au>
+- Matus Goljer <dota.keys@gmail.com>
+- Miles Bader <miles@gnu.org>
+- Mitchel Humpherys <mitch.special@gmail.com>
+- Moritz Bunkus <moritz@bunkus.org>
+- Nathan Weizenbaum <nex342@gmail.com>
+- Nguyễn Tuấn Anh <ubolonton@gmail.com>
+- Nic Ferier <nic@ferrier.me.uk>
+- Nick Alcock <nick.alcock@oracle.com>
+- Nick Alexander <nalexander@mozilla.com>
+- Nick Dimiduk <ndimiduk@gmail.com>
+- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
+- Nicolas Richard <theonewiththeevillook@yahoo.fr>
+- Noam Postavsky <npostavs@users.sourceforge.net>
+- Ole Arndt <oliver.arndt@cegedim.com>
+- Óscar Fuentes <ofv@wanadoo.es>
+- Paul Stadig <paul@stadig.name>
+- Pavel Holejsovsky <pavel.holejsovsky@upek.com>
+- Pekka Pessi <nospam@pessi.fi>
+- Peter J. Weisberg <pj@irregularexpressions.net>
+- Philippe Vaucher <philippe@stvs.ch>
+- Philipp Haselwarter <philipp@haselwarter.org>
+- Philip Weaver <philip.weaver@gmail.com>
+- Phil Jackson <phil@shellarchive.co.uk>
+- Pieter Praet <pieter@praet.org>
+- Prathamesh Sonpatki <csonpatki@gmail.com>
+- rabio <rabiodev@o2.pl>
+- Raimon Grau <raimonster@gmail.com>
+- Ramkumar Ramachandra <artagnon@gmail.com>
+- Remco van 't Veer <rwvtveer@xs4all.nl>
+- Rémi Vanicat <vanicat@debian.org>
+- René Stadler <mail@renestadler.de>
+- Robert Boone <robo4288@gmail.com>
+- Robin Green <greenrd@greenrd.org>
+- Roger Crew <crew@cs.stanford.edu>
+- Romain Francoise <romain@orebokech.com>
+- Ron Parker <rparker@a123systems.com>
+- Roy Crihfield <rscrihf@gmail.com>
+- Rüdiger Sonderfeld <ruediger@c-plusplus.de>
+- Ryan C. Thompson <rct@thompsonclan.org>
+- Samuel Bronson <naesten@gmail.com>
+- Sanjoy Das <sanjoy@playingwithpointers.com>
+- Sean Bryant <sbryant@hackinggibsons.com>
+- Sebastian Wiesner <lunaryorn@gmail.com>
+- Sébastien Gross <seb@chezwam.org>
+- Seong-Kook Shin <cinsky@gmail.com>
+- Sergey Pashinin <sergey@pashinin.com>
+- Sergey Vinokurov <serg.foo@gmail.com>
+- Servilio Afre Puentes <afrepues@mcmaster.ca>
+- Štěpán Němec <stepnem@gmail.com>
+- Steven Chow <steve@myfreestuffapp.com>
+- Steven Thomas <sthomas314@gmail.com>
+- Steve Purcell <steve@sanityinc.com>
+- Suhail Shergill <suhailshergill@gmail.com>
+- Takafumi Arakaki <aka.tkf@gmail.com>
+- Teruki Shigitani <teruki.shigitani@gmail.com>
+- Thierry Volpiatto <thierry.volpiatto@gmail.com>
+- Thomas Frössman <thomasf@jossystem.se>
+- Thomas Jost <thomas.jost@gmail.com>
+- Thomas Riccardi <riccardi.thomas@gmail.com>
+- Tibor Simko <tibor.simko@cern.ch>
+- Timo Juhani Lindfors <timo.lindfors@iki.fi>
+- Ting-Yu Lin <aethanyc@gmail.com>
+- Tom Feist <shabble@metavore.org>
+- Wilfred Hughes <me@wilfred.me.uk>
+- Yann Hodique <yann.hodique@gmail.com>
diff --git a/.emacs.d/elisp/magit/README.md b/.emacs.d/elisp/magit/README.md
new file mode 100644 (file)
index 0000000..330b5d8
--- /dev/null
@@ -0,0 +1,325 @@
+[![Build Status](https://travis-ci.org/magit/magit.svg?branch=master)](https://travis-ci.org/magit/magit)
+[![Gittip](http://img.shields.io/gittip/magit.png)](https://www.gittip.com/magit)
+
+It's Magit!  An Emacs mode for Git
+==================================
+
+Magit is an interface to the version control system [Git][git],
+implemented as an [Emacs][emacs] extension.
+
+Unlike Emacs' native [Version Control][vc] package which strives to
+provide a unified interface to various version control systems, Magit
+only supports Git and can therefore better take advantage of its native
+features.
+
+Magit supports GNU Emacs 23.2 or later; 24.1 or later is recommended.
+Magit supports Git 1.7.2.5 or later; 1.8.2 or later is recommended.
+The minimal versions are those available in Debian oldstable.
+
+### Table of Contents
+
+* [Getting Started](#getting-started)
+* [Getting Help](#getting-help)
+* [Contributions](#contributions)
+* [Installation](#installation)
+  * [Installing from Melpa](#installing-from-melpa)
+  * [Installing from Marmalade](#installing-from-marmalade)
+  * [Installing from Git](#installing-from-git)
+  * [Installing from Tarball](#installing-from-tarball)
+* [Dependencies](#dependencies)
+
+Getting Started
+===============
+
+To get started with Magit, run <kbd>M-x magit-status</kbd>.  If you
+are inside a Git repository this opens a buffer that summarizes its
+status.  Otherwise you are first prompted for a repository.  Read the
+short help for `magit-status-mode` (<kbd>C-h m</kbd> in the status
+buffer).
+
+Then edit and save some files, refresh the status buffer
+(<kbd>g</kbd>), stage changes (<kbd>s</kbd>) and commit (<kbd>c</kbd>)
+them.
+
+For more details consult the Magit user manual.  You can read it with
+<kbd>C-u C-h i magit.info</kbd> or [on the web][manual].
+
+We can also strongly recommend [this][mastering-intro] introduction
+from the Mastering Emacs blog.  It even describes some new features
+that are not yet documented in the manual.
+
+Magit also has a [website][website].
+
+Getting Help
+============
+
+When something breaks *please* see the
+[curated list of known issues][knownissues] and the [FAQ][faq].
+If that doesn't help check the list of [all open issues][issues].
+
+If everything else fails please open a [new issue][issues] or ask for
+help on the [mailing list][group].
+
+Contributions
+=============
+
+Magit is [hosted on Github][development].  Please contribute by
+suggesting features on the [issue tracker][issues] or by making code
+contributions using [pull requests][pulls].  Before opening a pull
+request make sure to read the brief [guidelines][contributing].
+
+Please also consider supporting development using [gittip][gittip].
+Thank you!
+
+Magit was started by [Marius Vollmer][marius] and is now maintained
+by [Jonas Bernoulli][jonas].  Other Magitians (former maintainers)
+are [Nicolas Dudebout][nicolas], [Peter J. Weisberg][peter],
+[Phil Jackson][phil], [Rémi Vanicat][remi], and [Yann Hodique][yann].
+
+Many more people have [contributed code][contributors] and suggested
+features.
+
+Thanks to all of you, may (the history of) the source be with you!
+
+Installation
+============
+
+Beginning with version 24.1 Emacs includes a package management
+facility known as Elpa or `package.el`.  Using an Elpa package
+repository is the easiest and recommended way to install and update
+Magit and its dependencies.  Among other things using `package.el`
+is recommended because that automatically takes care of installing
+dependencies.
+
+Magit is available from both of the two popular Elpa repositories,
+[Marmalade][marmalade] (stable releases) and [Melpa][melpa]
+(snapshots).
+
+### Installing from Melpa
+
+If you have already used Melpa to install some other package then
+all you have to do is:
+
+<kbd>M-x package-install RET magit RET</kbd>
+
+This installs Magit as well as all of its dependencies and makes
+them available in the current and future Emacs sessions.
+
+If this is the first time you are using Melpa, then you have to
+configure `package.el` once.
+
+```lisp
+(require 'package)
+(add-to-list 'package-archives
+             '("melpa" . "http://melpa.milkbox.net/packages/") t)
+```
+
+Then evaluate these forms, update the package cache, and install
+Magit as above.  To update the cache use:
+
+<kbd>M-x package-refresh-contents RET</kbd>
+
+You might also want to have a look at the more detailed
+[instructions][melpa-intro] provided by the Melpa project.  Among
+other things it explains how to install only some packages from Melpa
+and others from Marmalade, and how to use `package.el` with older
+versions of Emacs.
+
+### Installing from Marmalade
+
+For the time being we recommend that you install the development
+version available from Melpa, because the latest Magit release (which
+is what you get from Marmalade) is very outdated.  If you are using
+the development version of Emacs, then you have to do so, because it
+contains an incompatible change that breaks the last Magit release.
+
+### Installing from Git
+
+If you want to contribute to Magit you should run it directly from the
+Git repository.
+
+First get the repository:
+
+```sh
+$ git clone git://github.com/magit/magit.git
+```
+
+Then you should byte compile the libraries and generate the
+documentation, though that is not required:
+
+```sh
+$ make lisp docs
+```
+
+Unless all dependencies are installed at `../DEPENDENCY` you have to
+tell `make` where to find them, e.g.:
+
+```sh
+$ EFLAGS="-L /path/to/git-modes" make lisp docs
+```
+
+Then add this to you init file:
+
+```lisp
+(add-to-list 'load-path "/path/to/git-modes")
+(add-to-list 'load-path "/path/to/magit")
+(eval-after-load 'info
+  '(progn (info-initialize)
+          (add-to-list 'Info-directory-list "/path/to/magit/")))
+(require 'magit)
+```
+
+If you are using an Emacs version before 24.3, then you also have to
+install `cl-lib` and tell `make` as well as Emacs where to find it.
+
+To view available make targets use:
+
+```sh
+$ make help
+```
+
+To update use:
+
+```sh
+$ git pull
+$ make lisp docs
+```
+
+Before creating a pull request always run:
+
+```sh
+$ make lisp test
+```
+
+You may also build Magit manually:
+
+```sh
+$ emacs -Q --batch -L . -L /path/to/DEPENCENCY -f batch-byte-compile *.el
+$ makeinfo -o magit.info magit.texi
+$ install-info --dir=dir magit.info
+```
+
+### Installing from Tarball
+
+This is only intended for users who have been doing this sort of thing
+for years.  Installing from a tarball isn't particularly difficult but
+because we are only providing this as an alternative method we are a
+bit light on documentation, so it helps to have done this before.
+
+Also most steps have to be repeated every time you want to update.
+
+Because the latest Magit release is very outdated, please consider
+installing the development version even if tarballs are your thing.
+
+Download and unpack [magit-1.2.0.tar.gz][download]. Then build and
+install as usual:
+
+```sh
+$ wget https://github.com/downloads/magit/magit/magit-1.2.0.tar.gz
+$ tar -xf magit-1.2.0.tar.gz
+$ cd magit-1.2.0
+$ make
+$ sudo make install
+```
+
+This installs the Emacs lisp libraries, as well as the prebuilt
+documentation from the tarball.  You may alternatively build the
+documentation yourself:
+
+```sh
+$ make docs
+$ sudo make install-docs
+```
+
+By default the Emacs lisp libraries are installed in
+`/usr/local/share/emacs/site-lisp/magit/`.  Unless Emacs itself is
+also installed in `/usr/local/` you have to add that directory to the
+`load-path`.
+
+```lisp
+(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/magit")
+```
+
+Then `magit` can be loaded:
+
+```lisp
+(require 'magit)
+```
+
+Add the above lines to your init file and restart Emacs.
+
+Dependencies
+============
+
+If you install Magit using `package.el` then dependencies are
+automatically being taken care of.  Otherwise you have to track down
+dependencies and install them manually.
+
+* `cl-lib` is a new library in Emacs 24.3.  Like the old `cl` it
+  provides various Common Lisp forms, but differs in that symbols are
+  prefixed with `cl-`.  A forward compatibility `cl-lib` for older
+  versions of Emacs is available from the GNU Elpa repository.  You
+  can install it using `package.el` or get it [here][cl-lib].
+
+* `git-commit-mode` which is part of the [git-modes][git-modes]
+  repository and available as a separate package from Melpa.
+
+* `git-rebase-mode` which is part of the [git-modes][git-modes]
+  repository and available as a separate package from Melpa.
+
+### Optional Dependencies
+
+The following libraries build on third-party tools or git subcommands
+that are not installed by the Git base-package on some distributions:
+
+* `magit-stgit.el` requires [`stgit`][stgit].
+* `magit-svn.el` requires the official Git subcommand `svn`.
+* `magit-topgit.el` requires [`topgit`][topgit].
+* `magit-wip.el` requires [`git-wip`][git-wip].
+
+### Dependencies of Tests
+
+To run tests the following libraries are also required:
+
+* `ert` is a tool for automated testing.  It is part of Emacs
+  starting with version 24.1.  You can also obtain an old version from
+  the former development [repository][ert].
+
+
+[contributing]: https://github.com/magit/magit/blob/master/CONTRIBUTING.md
+[contributors]: https://github.com/magit/magit/contributors
+[development]: http://github.com/magit/magit
+[download]: https://github.com/downloads/magit/magit/magit-1.2.0.tar.gz
+[faq]: https://github.com/magit/magit/wiki/FAQ
+[group]: https://groups.google.com/forum/?fromgroups#!forum/magit
+[issues]: https://github.com/magit/magit/issues
+[knownissues]: https://github.com/magit/magit/wiki/Known-issues
+[manual]: http://magit.github.io/documentation.html
+[owners]: https://github.com/magit?tab=members
+[pulls]: https://github.com/magit/magit/pulls
+[screencast]: http://vimeo.com/2871241
+[website]: http://magit.github.io
+
+[jonas]: https://github.com/tarsius
+[marius]: https://github.com/mvollmer
+[nicolas]: https://github.com/dudebout
+[peter]: https://github.com/pjweisberg
+[phil]: https://github.com/philjackson
+[remi]: https://github.com/vanicat
+[yann]: https://github.com/sigma
+
+[cl-lib]: http://elpa.gnu.org/packages/cl-lib.html
+[emacs]: http://www.gnu.org/software/emacs
+[ert]: https://github.com/ohler/ert
+[git-wip]: https://github.com/bartman/git-wip
+[git]: http://git-scm.com
+[gitflow]: https://github.com/nvie/gitflow
+[gittip]: https://www.gittip.com/magit
+[git-modes]: https://github.com/magit/git-modes
+[marmalade]: http://marmalade-repo.org
+[mastering-intro]: http://www.masteringemacs.org/articles/2013/12/06/introduction-magit-emacs-mode-git
+[melpa]: http://melpa.milkbox.net
+[melpa-intro]: http://melpa.milkbox.net/#/getting-started
+[stgit]: http://www.procode.org/stgit
+[topgit]: https://github.com/greenrd/topgit
+[vc]: http://www.gnu.org/software/emacs/manual/html_node/emacs/Version-Control.html
diff --git a/.emacs.d/elisp/magit/dir b/.emacs.d/elisp/magit/dir
new file mode 100644 (file)
index 0000000..5fec543
--- /dev/null
@@ -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.
+\1f
+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.
index 62f2741..c26bbc5 100644 (file)
 ;;; Code:
 (add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
 \f
 ;;; Code:
 (add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
 \f
-;;;### (autoloads nil "magit" "magit.el" (21012 47854 0 0))
+;;;### (autoloads nil "magit" "magit.el" (21359 22975 806272 677000))
 ;;; Generated autoloads from magit.el
 
 ;;; Generated autoloads from magit.el
 
+(autoload 'magit-git-command "magit" "\
+Execute a Git subcommand asynchronously, displaying the output.
+With a prefix argument run Git in the root of the current
+repository.  Non-interactively run Git in DIRECTORY with ARGS.
+
+\(fn ARGS DIRECTORY)" t nil)
+
+(autoload 'magit-show-commit "magit" "\
+Show information about COMMIT.
+
+\(fn COMMIT &optional NOSELECT)" t nil)
+
 (autoload 'magit-status "magit" "\
 (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.
+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
 
 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.
+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)
+Depending on option `magit-status-buffer-switch-function' the
+status buffer is shown in another window (the default) or the
+current window.  Non-interactively optional SWITCH-FUNCTION
+can be used to override this.
 
 
-;;;***
-\f
-;;;### (autoloads nil "magit-blame" "magit-blame.el" (21012 47854
-;;;;;;  0 0))
-;;; Generated autoloads from magit-blame.el
+\(fn DIR &optional SWITCH-FUNCTION)" t nil)
 
 
-(autoload 'magit-blame-mode "magit-blame" "\
-Display blame information inline.
+(autoload 'magit-stage-all "magit" "\
+Add all remaining changes in tracked files to staging area.
+With a prefix argument, add remaining untracked files as well.
+\('git add [-u] .').
 
 
-\(fn &optional ARG)" t nil)
+\(fn &optional INCLUDING-UNTRACKED)" t nil)
 
 
-;;;***
-\f
-;;;### (autoloads nil "magit-stgit" "magit-stgit.el" (21012 47854
-;;;;;;  0 0))
-;;; Generated autoloads from magit-stgit.el
+(autoload 'magit-unstage-all "magit" "\
+Remove all changes from staging area.
+\('git reset --mixed HEAD').
 
 
-(autoload 'magit-stgit-mode "magit-stgit" "\
-StGit support for Magit
+\(fn)" t nil)
 
 
-\(fn &optional ARG)" t nil)
+(autoload 'magit-dired-jump "magit" "\
+Visit current item in dired.
+With a prefix argument, visit in other window.
 
 
-(autoload 'turn-on-magit-stgit "magit-stgit" "\
-Unconditionally turn on `magit-stgit-mode'.
+\(fn &optional OTHER-WINDOW)" t nil)
 
 
-\(fn)" nil nil)
+(autoload 'magit-show "magit" "\
+Display and select a buffer containing FILE as stored in REV.
 
 
-;;;***
-\f
-;;;### (autoloads nil "magit-svn" "magit-svn.el" (21012 47854 0 0))
-;;; Generated autoloads from magit-svn.el
+Insert the contents of FILE as stored in the revision REV into a
+buffer.  Then select the buffer using `pop-to-buffer' or with a
+prefix argument using `switch-to-buffer'.  Non-interactivity use
+SWITCH-FUNCTION to switch to the buffer, if that is nil simply
+return the buffer, without displaying it.
 
 
-(autoload 'magit-svn-mode "magit-svn" "\
-SVN support for Magit
+\(fn REV FILE &optional SWITCH-FUNCTION)" t nil)
 
 
-\(fn &optional ARG)" t nil)
+(autoload 'magit-merge "magit" "\
+Merge REVISION into the current 'HEAD', leaving changes uncommitted.
+With a prefix argument, skip editing the log message and commit.
+\('git merge [--no-commit] REVISION').
 
 
-(autoload 'turn-on-magit-svn "magit-svn" "\
-Unconditionally turn on `magit-svn-mode'.
+\(fn REVISION &optional DO-COMMIT)" t nil)
 
 
-\(fn)" nil nil)
+(autoload 'magit-merge-abort "magit" "\
+Abort the current merge operation.
 
 
-;;;***
-\f
-;;;### (autoloads nil "magit-topgit" "magit-topgit.el" (21012 47854
-;;;;;;  0 0))
-;;; Generated autoloads from magit-topgit.el
+\(fn)" t nil)
+
+(autoload 'magit-checkout "magit" "\
+Switch 'HEAD' to REVISION and update working tree.
+Fails if working tree or staging area contain uncommitted changes.
+If REVISION is a remote branch, offer to create a local tracking branch.
+\('git checkout [-b] REVISION').
+
+\(fn REVISION)" t nil)
+
+(autoload 'magit-create-branch "magit" "\
+Switch 'HEAD' to new BRANCH at revision PARENT and update working tree.
+Fails if working tree or staging area contain uncommitted changes.
+\('git checkout -b BRANCH REVISION').
+
+\(fn BRANCH PARENT)" t nil)
+
+(autoload 'magit-delete-branch "magit" "\
+Delete the BRANCH.
+If the branch is the current one, offers to switch to `master' first.
+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').
 
 
-(autoload 'magit-topgit-mode "magit-topgit" "\
-Topgit support for Magit
+\(fn BRANCH &optional FORCE)" t nil)
+
+(autoload 'magit-rename-branch "magit" "\
+Rename branch OLD to NEW.
+With prefix, forces the rename even if NEW already exists.
+\('git branch [-m|-M] OLD NEW').
+
+\(fn OLD NEW &optional FORCE)" t nil)
+
+(autoload 'magit-add-remote "magit" "\
+Add the REMOTE and fetch it.
+\('git remote add REMOTE URL').
+
+\(fn REMOTE URL)" t nil)
+
+(autoload 'magit-remove-remote "magit" "\
+Delete the REMOTE.
+\('git remote rm REMOTE').
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-rename-remote "magit" "\
+Rename remote OLD to NEW.
+\('git remote rename OLD NEW').
+
+\(fn OLD NEW)" t nil)
+
+(autoload 'magit-interactive-rebase "magit" "\
+Start a git rebase -i session, old school-style.
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-head "magit" "\
+Switch 'HEAD' to REVISION, keeping prior working tree and staging area.
+Any differences from REVISION become new changes to be committed.
+With prefix argument, all uncommitted changes in working tree
+and staging area are lost.
+\('git reset [--soft|--hard] REVISION').
+
+\(fn REVISION &optional HARD)" t nil)
+
+(autoload 'magit-reset-head-hard "magit" "\
+Switch 'HEAD' to REVISION, losing all changes.
+Uncomitted changes in both working tree and staging area are lost.
+\('git reset --hard REVISION').
+
+\(fn REVISION)" t nil)
+
+(autoload 'magit-reset-working-tree "magit" "\
+Revert working tree and clear changes from staging area.
+\('git reset --hard HEAD').
+
+With a prefix arg, also remove untracked files.
+With two prefix args, remove ignored files as well.
 
 \(fn &optional ARG)" t nil)
 
 
 \(fn &optional ARG)" t nil)
 
-(autoload 'turn-on-magit-topgit "magit-topgit" "\
-Unconditionally turn on `magit-topgit-mode'.
+(autoload 'magit-fetch "magit" "\
+Fetch from REMOTE.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-fetch-current "magit" "\
+Run fetch for default remote.
+
+If there is no default remote, ask for one.
+
+\(fn)" t nil)
+
+(autoload 'magit-remote-update "magit" "\
+Update all remotes.
+
+\(fn)" t nil)
+
+(autoload 'magit-pull "magit" "\
+Run git pull.
+
+If there is no default remote, the user is prompted for one and
+its values is saved with git config.  If there is no default
+merge branch, the user is prompted for one and its values is
+saved with git config.  With a prefix argument, the default
+remote is not used and the user is prompted for a remote.  With
+two prefix arguments, the default merge branch is not used and
+the user is prompted for a merge branch.  Values entered by the
+user because of prefix arguments are not saved with git config.
+
+\(fn)" t nil)
+
+(autoload 'magit-push-tags "magit" "\
+Push tags to a remote repository.
+
+Push tags to the current branch's remote.  If that isn't set push
+to \"origin\" or if that remote doesn't exit but only a single
+remote is defined use that.  Otherwise or with a prefix argument
+ask the user what remote to use.
+
+\(fn)" t nil)
+
+(autoload 'magit-push "magit" "\
+Push the current branch to a remote repository.
+
+This command runs the `magit-push-remote' hook.  By default that
+means running `magit-push-dwim'.  So unless you have customized
+the hook this command behaves like this:
+
+With a single prefix argument ask the user what branch to push
+to.  With two or more prefix arguments also ask the user what
+remote to push to.  Otherwise use the remote and branch as
+configured using the Git variables `branch.<name>.remote' and
+`branch.<name>.merge'.  If the former is undefined ask the user.
+If the latter is undefined push without specifing the remote
+branch explicitly.
+
+Also see option `magit-set-upstream-on-push'.
+
+\(fn)" t nil)
+
+(autoload 'magit-commit "magit" "\
+Create a new commit on HEAD.
+With a prefix argument amend to the commit at HEAD instead.
+\('git commit [--amend]').
+
+\(fn &optional AMENDP)" t nil)
+
+(autoload 'magit-commit-amend "magit" "\
+Amend the last commit.
+\('git commit --amend').
+
+\(fn)" t nil)
+
+(autoload 'magit-commit-extend "magit" "\
+Amend the last commit, without editing the message.
+With a prefix argument do change the committer date, otherwise
+don't.  The option `magit-commit-extend-override-date' can be
+used to inverse the meaning of the prefix argument.
+\('git commit --no-edit --amend [--keep-date]').
+
+\(fn &optional OVERRIDE-DATE)" t nil)
+
+(autoload 'magit-commit-reword "magit" "\
+Reword the last commit, ignoring staged changes.
+
+With a prefix argument do change the committer date, otherwise
+don't.  The option `magit-commit-rewrite-override-date' can be
+used to inverse the meaning of the prefix argument.
+
+Non-interactively respect the optional OVERRIDE-DATE argument
+and ignore the option.
+
+\('git commit --only --amend').
 
 
-\(fn)" nil nil)
+\(fn &optional OVERRIDE-DATE)" t nil)
+
+(autoload 'magit-commit-fixup "magit" "\
+Create a fixup commit.
+With a prefix argument the user is always queried for the commit
+to be fixed.  Otherwise the current or marked commit may be used
+depending on the value of option `magit-commit-squash-commit'.
+\('git commit [--no-edit] --fixup=COMMIT').
+
+\(fn &optional COMMIT)" t nil)
+
+(autoload 'magit-commit-squash "magit" "\
+Create a squash commit.
+With a prefix argument the user is always queried for the commit
+to be fixed.  Otherwise the current or marked commit may be used
+depending on the value of option `magit-commit-squash-commit'.
+\('git commit [--no-edit] --fixup=COMMIT').
+
+\(fn &optional COMMIT FIXUP)" t nil)
+
+(autoload 'magit-tag "magit" "\
+Create a new tag with the given NAME at REV.
+With a prefix argument annotate the tag.
+\('git tag [--annotate] NAME REV').
+
+\(fn NAME REV &optional ANNOTATE)" t nil)
+
+(autoload 'magit-delete-tag "magit" "\
+Delete the tag with the given NAME.
+\('git tag -d NAME').
+
+\(fn NAME)" t nil)
+
+(autoload 'magit-stash "magit" "\
+Create new stash of working tree and staging area named DESCRIPTION.
+Working tree and staging area revert to the current 'HEAD'.
+With prefix argument, changes in staging area are kept.
+\('git stash save [--keep-index] DESCRIPTION')
+
+\(fn DESCRIPTION)" t nil)
+
+(autoload 'magit-stash-snapshot "magit" "\
+Create new stash of working tree and staging area; keep changes in place.
+\('git stash save \"Snapshot...\"; git stash apply stash@{0}')
+
+\(fn)" t nil)
+
+(autoload 'magit-submodule-update "magit" "\
+Update the submodule of the current git repository.
+With a prefix arg, do a submodule update --init.
+
+\(fn &optional INIT)" t nil)
+
+(autoload 'magit-submodule-update-init "magit" "\
+Update and init the submodule of the current git repository.
+
+\(fn)" t nil)
+
+(autoload 'magit-submodule-init "magit" "\
+Initialize the submodules.
+
+\(fn)" t nil)
+
+(autoload 'magit-submodule-sync "magit" "\
+Synchronizes submodule's remote URL configuration.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-start "magit" "\
+Start a bisect session.
+
+Bisecting a bug means to find the commit that introduced it.
+This command starts such a bisect session by asking for a know
+good and a bad commit.  To move the session forward use the
+other actions from the bisect popup (\\<magit-status-mode-map>\\[magit-key-mode-popup-bisecting]).
+
+\(fn BAD GOOD)" t nil)
+
+(autoload 'magit-bisect-reset "magit" "\
+After bisecting cleanup bisection state and return to original HEAD.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-good "magit" "\
+While bisecting, mark the current commit as good.
+Use this after you have asserted that the commit does not contain
+the bug in question.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-bad "magit" "\
+While bisecting, mark the current commit as bad.
+Use this after you have asserted that the commit does contain the
+bug in question.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-skip "magit" "\
+While bisecting, skip the current commit.
+Use this if for some reason the current commit is not a good one
+to test.  This command lets Git choose a different one.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-run "magit" "\
+Bisect automatically by running commands after each step.
+
+\(fn CMDLINE)" t nil)
+
+(autoload 'magit-log "magit" "\
+
+
+\(fn &optional RANGE)" t nil)
+
+(autoload 'magit-log-ranged "magit" "\
+
+
+\(fn RANGE)" t nil)
+
+(autoload 'magit-log-long "magit" "\
+
+
+\(fn &optional RANGE)" t nil)
+
+(autoload 'magit-log-long-ranged "magit" "\
+
+
+\(fn RANGE)" t nil)
+
+(autoload 'magit-file-log "magit" "\
+Display the log for the currently visited file or another one.
+With a prefix argument show the log graph.
+
+\(fn FILE &optional USE-GRAPH)" t nil)
+
+(autoload 'magit-reflog "magit" "\
+Display the reflog of the current branch.
+With a prefix argument another branch can be chosen.
+
+\(fn REF)" t nil)
+
+(autoload 'magit-reflog-head "magit" "\
+Display the HEAD reflog.
+
+\(fn)" t nil)
+
+(autoload 'magit-cherry "magit" "\
+Show commits in a branch that are not merged in the upstream branch.
+
+\(fn HEAD UPSTREAM)" t nil)
+
+(autoload 'magit-save-index "magit" "\
+Add the content of current file as if it was the index.
+
+\(fn)" t nil)
+
+(autoload 'magit-interactive-resolve "magit" "\
+Resolve a merge conflict using Ediff.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-diff "magit" "\
+Show differences between in a range.
+You can also show the changes in a single commit by omitting the
+range end, but for that `magit-show-commit' is a better option.
+
+\(fn RANGE &optional WORKING ARGS)" t nil)
+
+(autoload 'magit-diff-working-tree "magit" "\
+Show differences between a commit and the current working tree.
+
+\(fn REV)" t nil)
+
+(autoload 'magit-diff-staged "magit" "\
+Show differences between the index and the HEAD commit.
+
+\(fn)" t nil)
+
+(autoload 'magit-diff-unstaged "magit" "\
+Show differences between the current working tree and index.
+
+\(fn)" t nil)
+
+(autoload 'magit-diff-stash "magit" "\
+Show changes in a stash.
+A Stash consist of more than just one commit.  This command uses
+a special diff range so that the stashed changes actually were a
+single commit.
+
+\(fn STASH &optional NOSELECT)" t nil)
+
+(autoload 'magit-wazzup "magit" "\
+Show a list of branches in a dedicated buffer.
+Unlike in the buffer created by `magit-branch-manager' each
+branch can be expanded to show a list of commits not merged
+into the selected branch.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-branch-manager "magit" "\
+Show a list of branches in a dedicated buffer.
+
+\(fn)" t nil)
+
+(autoload 'magit-init "magit" "\
+Create or reinitialize a Git repository.
+Read directory name and initialize it as new Git repository.
+
+If the directory is below an existing repository, then the user
+has to confirm that a new one should be created inside; or when
+the directory is the root of the existing repository, whether
+it should be reinitialized.
+
+Non-interactively DIRECTORY is always (re-)initialized.
+
+\(fn DIRECTORY)" t nil)
+
+(autoload 'magit-add-change-log-entry "magit" "\
+Find change log file and add date entry and item for current change.
+This differs from `add-change-log-entry' (which see) in that
+it acts on the current hunk in a Magit buffer instead of on
+a position in a file-visiting buffer.
+
+\(fn &optional WHOAMI FILE-NAME OTHER-WINDOW)" t nil)
+
+(autoload 'magit-add-change-log-entry-other-window "magit" "\
+Find change log file in other window and add entry and item.
+This differs from `add-change-log-entry-other-window' (which see)
+in that it acts on the current hunk in a Magit buffer instead of
+on a position in a file-visiting buffer.
+
+\(fn &optional WHOAMI FILE-NAME)" t nil)
+
+(autoload 'magit-run-git-gui "magit" "\
+Run `git gui' for the current git repository.
+
+\(fn)" t nil)
+
+(autoload 'magit-run-git-gui-blame "magit" "\
+Run `git gui blame' on the given FILENAME and COMMIT.
+Interactively run it for the current file and the HEAD, with a
+prefix or when the current file cannot be determined let the user
+choose.  When the current buffer is visiting FILENAME instruct
+blame to center around the line point is on.
+
+\(fn COMMIT FILENAME &optional LINENUM)" t nil)
+
+(autoload 'magit-run-gitk "magit" "\
+Run Gitk for the current git repository.
+Without a prefix argument run `gitk --all', with
+a prefix argument run gitk without any arguments.
+
+\(fn ARG)" t nil)
 
 ;;;***
 \f
 
 ;;;***
 \f
-;;;### (autoloads nil "magit-wip" "magit-wip.el" (21012 47854 0 0))
-;;; Generated autoloads from magit-wip.el
+;;;### (autoloads nil "magit-blame" "magit-blame.el" (21359 22975
+;;;;;;  710272 201000))
+;;; Generated autoloads from magit-blame.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'.")
+(autoload 'magit-blame-mode "magit-blame" "\
+Display blame information inline.
 
 
-(custom-autoload 'magit-wip-mode "magit-wip" nil)
+\(fn &optional ARG)" t nil)
 
 
-(autoload 'magit-wip-mode "magit-wip" "\
-In Magit log buffers; give wip refs a special appearance.
+;;;***
+\f
+;;;### (autoloads nil "magit-key-mode" "magit-key-mode.el" (21359
+;;;;;;  22975 590271 606000))
+;;; Generated autoloads from magit-key-mode.el
 
 
-\(fn &optional ARG)" t nil)
+(defvar magit-key-mode-groups '((dispatch (actions ("b" "Branching" magit-key-mode-popup-branching) ("B" "Bisecting" magit-key-mode-popup-bisecting) ("c" "Committing" magit-key-mode-popup-committing) ("d" "Diff worktree" magit-diff-working-tree) ("D" "Diff" magit-diff) ("f" "Fetching" magit-key-mode-popup-fetching) ("F" "Pulling" magit-key-mode-popup-pulling) ("g" "Refresh Buffers" magit-refresh-all) ("l" "Logging" magit-key-mode-popup-logging) ("m" "Merging" magit-key-mode-popup-merging) ("M" "Remoting" magit-key-mode-popup-remoting) ("P" "Pushing" magit-key-mode-popup-pushing) ("o" "Submoduling" magit-key-mode-popup-submodule) ("r" "Rewriting" magit-key-mode-popup-rewriting) ("R" "Rebasing" magit-rebase-step) ("s" "Show Status" magit-status) ("S" "Stage all" magit-stage-all) ("t" "Tagging" magit-key-mode-popup-tagging) ("U" "Unstage all" magit-unstage-all) ("v" "Show Commit" magit-show-commit) ("V" "Show File" magit-show) ("w" "Wazzup" magit-wazzup) ("X" "Reset worktree" magit-reset-working-tree) ("y" "Cherry" magit-cherry) ("z" "Stashing" magit-key-mode-popup-stashing) ("!" "Running" magit-key-mode-popup-running) ("$" "Show Process" magit-display-process))) (logging (man-page "git-log") (actions ("l" "Short" magit-log) ("L" "Long" magit-log-long) ("h" "Head Reflog" magit-reflog-head) ("f" "File log" magit-file-log) ("rl" "Ranged short" magit-log-ranged) ("rL" "Ranged long" magit-log-long-ranged) ("rh" "Reflog" magit-reflog)) (switches ("-m" "Only merge commits" "--merges") ("-s" "No merge commits" "--no-merges") ("-do" "Date Order" "--date-order") ("-f" "First parent" "--first-parent") ("-i" "Case insensitive patterns" "-i") ("-pr" "Pickaxe regex" "--pickaxe-regex") ("-g" "Show Graph" "--graph") ("-n" "Name only" "--name-only") ("-am" "All match" "--all-match") ("-al" "All" "--all")) (arguments ("=r" "Relative" "--relative=" read-directory-name) ("=c" "Committer" "--committer=" read-from-minibuffer) ("=>" "Since" "--since=" read-from-minibuffer) ("=<" "Before" "--before=" read-from-minibuffer) ("=a" "Author" "--author=" read-from-minibuffer) ("=g" "Grep messages" "--grep=" read-from-minibuffer) ("=G" "Grep patches" "-G" read-from-minibuffer) ("=L" "Trace evolution of line range [long log only]" "-L" magit-read-file-trace) ("=s" "Pickaxe search" "-S" read-from-minibuffer) ("=b" "Branches" "--branches=" read-from-minibuffer) ("=R" "Remotes" "--remotes=" read-from-minibuffer))) (running (actions ("!" "Git Subcommand (from root)" magit-git-command-topdir) (":" "Git Subcommand (from pwd)" magit-git-command) ("g" "Git Gui" magit-run-git-gui) ("k" "Gitk" magit-run-gitk))) (fetching (man-page "git-fetch") (actions ("f" "Current" magit-fetch-current) ("a" "All" magit-remote-update) ("o" "Other" magit-fetch)) (switches ("-p" "Prune" "--prune"))) (pushing (man-page "git-push") (actions ("P" "Push" magit-push) ("t" "Push tags" magit-push-tags)) (switches ("-f" "Force" "--force") ("-d" "Dry run" "-n") ("-u" "Set upstream" "-u"))) (pulling (man-page "git-pull") (actions ("F" "Pull" magit-pull)) (switches ("-f" "Force" "--force") ("-r" "Rebase" "--rebase"))) (branching (man-page "git-branch") (actions ("v" "Branch manager" magit-branch-manager) ("b" "Checkout" magit-checkout) ("c" "Create" magit-create-branch) ("r" "Rename" magit-rename-branch) ("k" "Delete" magit-delete-branch)) (switches ("-t" "Set upstream configuration" "--track") ("-m" "Merged to HEAD" "--merged") ("-M" "Merged to master" "--merged=master") ("-n" "Not merged to HEAD" "--no-merged") ("-N" "Not merged to master" "--no-merged=master")) (arguments ("=c" "Contains" "--contains=" magit-read-rev-with-default) ("=m" "Merged" "--merged=" magit-read-rev-with-default) ("=n" "Not merged" "--no-merged=" magit-read-rev-with-default))) (remoting (man-page "git-remote") (actions ("v" "Remote 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 ("t" "Create" magit-tag) ("k" "Delete" magit-delete-tag)) (switches ("-a" "Annotate" "--annotate") ("-f" "Force" "--force") ("-s" "Sign" "--sign"))) (stashing (man-page "git-stash") (actions ("v" "View" magit-diff-stash) ("z" "Save" magit-stash) ("s" "Snapshot" magit-stash-snapshot) ("a" "Apply" magit-stash-apply) ("p" "Pop" magit-stash-pop) ("k" "Drop" magit-stash-drop)) (switches ("-k" "Keep index" "--keep-index") ("-u" "Include untracked files" "--include-untracked") ("-a" "Include all files" "--all"))) (committing (man-page "git-commit") (actions ("c" "Commit" magit-commit) ("a" "Amend" magit-commit-amend) ("e" "Extend" magit-commit-extend) ("r" "Reword" magit-commit-reword) ("f" "Fixup" magit-commit-fixup) ("s" "Squash" magit-commit-squash)) (switches ("-a" "Stage all modified and deleted files" "--all") ("-e" "Allow empty commit" "--allow-empty") ("-v" "Show diff of changes to be committed" "--verbose") ("-n" "Bypass git hooks" "--no-verify") ("-s" "Add Signed-off-by line" "--signoff") ("-R" "Claim authorship and reset author date" "--reset-author")) (arguments ("=A" "Override the author" "--author=" read-from-minibuffer) ("=S" "Sign using gpg" "--gpg-sign=" magit-read-gpg-secret-key))) (merging (man-page "git-merge") (actions ("m" "Merge" magit-merge) ("A" "Abort" magit-merge-abort)) (switches ("-ff" "Fast-forward only" "--ff-only") ("-nf" "No fast-forward" "--no-ff") ("-sq" "Squash" "--squash")) (arguments ("-st" "Strategy" "--strategy=" read-from-minibuffer))) (rewriting (actions ("b" "Begin" magit-rewrite-start) ("s" "Stop" magit-rewrite-stop) ("a" "Abort" magit-rewrite-abort) ("f" "Finish" magit-rewrite-finish) ("d" "Diff pending" magit-rewrite-diff-pending) ("*" "Set unused" magit-rewrite-set-unused) ("." "Set used" magit-rewrite-set-used))) (apply-mailbox (man-page "git-am") (actions ("J" "Apply Mailbox" magit-apply-mailbox)) (switches ("-s" "add a Signed-off-by line to the commit message" "--signoff") ("-3" "allow fall back on 3way merging if needed" "--3way") ("-k" "pass -k flag to git-mailinfo" "--keep") ("-c" "strip everything before a scissors line" "--scissors") ("-p" "pass it through git-apply" "-p") ("-r" "override error message when patch failure occurs" "--resolvemsg") ("-d" "lie about committer date" "--committer-date-is-author-date") ("-D" "use current timestamp for author date" "--ignore-date") ("-b" "pass -b flag to git-mailinfo" "--keep-non-patch")) (arguments ("=p" "format the patch(es) are in" "--patch-format=" read-from-minibuffer))) (submodule (man-page "git-submodule") (actions ("u" "Update" magit-submodule-update) ("b" "Both update and init" magit-submodule-update-init) ("i" "Init" magit-submodule-init) ("s" "Sync" magit-submodule-sync))) (bisecting (man-page "git-bisect") (actions ("b" "Bad" magit-bisect-bad) ("g" "Good" magit-bisect-good) ("k" "Skip" magit-bisect-skip) ("r" "Reset" magit-bisect-reset) ("s" "Start" magit-bisect-start) ("u" "Run" magit-bisect-run))) (diff-options (actions ("s" "Set" magit-set-diff-options) ("d" "Set default" magit-set-default-diff-options) ("c" "Save default" magit-save-default-diff-options) ("r" "Reset to default" magit-reset-diff-options) ("h" "Toggle Hunk Refinement" magit-diff-toggle-refine-hunk)) (switches ("-m" "Show smallest possible diff" "--minimal") ("-p" "Use patience diff algorithm" "--patience") ("-h" "Use histogram diff algorithm" "--histogram") ("-b" "Ignore whitespace changes" "--ignore-space-change") ("-w" "Ignore all whitespace" "--ignore-all-space") ("-W" "Show surrounding functions" "--function-context")))) "\
+Holds the key, help, function mapping for the log-mode.
+If you modify this make sure you reset `magit-key-mode-keymaps'
+to nil.")
+ (mapc (lambda (g) (eval `(autoload ',(intern (concat "magit-key-mode-popup-" (symbol-name (car g)))) "magit-key-mode" ,(concat "Key menu for " (symbol-name (car g))) t))) magit-key-mode-groups)
+
+;;;***
+\f
+;;;### (autoloads nil "magit-wip" "magit-wip.el" (21359 22975 746272
+;;;;;;  380000))
+;;; Generated autoloads from magit-wip.el
 
 (autoload 'magit-wip-save-mode "magit-wip" "\
 Magit support for committing to a work-in-progress ref.
 
 
 (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.
+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)
 
 
 \(fn &optional ARG)" t nil)
 
@@ -127,26 +565,7 @@ See `magit-wip-save-mode' for more information on Magit-Wip-Save mode.
 
 ;;;***
 \f
 
 ;;;***
 \f
-;;;### (autoloads nil "rebase-mode" "rebase-mode.el" (21012 47854
-;;;;;;  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))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("magit-bisect.el" "magit-key-mode.el"
-;;;;;;  "magit-pkg.el") (21012 47854 582944 232000))
+;;;### (autoloads nil nil ("magit-pkg.el") (21359 22975 997803 39000))
 
 ;;;***
 \f
 
 ;;;***
 \f
diff --git a/.emacs.d/elisp/magit/magit-bisect.el b/.emacs.d/elisp/magit/magit-bisect.el
deleted file mode 100644 (file)
index cdb6455..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-(require 'magit)
-
-(defvar magit--bisect-last-pos)
-(defvar magit--bisect-tmp-file)
-(defvar magit--bisect-info nil)
-(make-variable-buffer-local 'magit--bisect-info)
-(put 'magit--bisect-info 'permanent-local t)
-
-(defun magit--bisecting-p (&optional required-status)
-  "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-git-dir) "BISECT_LOG"))
-       (or (not required-status)
-           (eq (plist-get (magit--bisect-info) :status)
-               required-status))))
-
-(defun magit--bisect-info ()
-  (with-current-buffer (magit-find-status-buffer)
-    (or (if (local-variable-p 'magit--bisect-info) magit--bisect-info)
-        (list :status (if (magit--bisecting-p) 'running 'not-running)))))
-
-(defun magit--bisect-cmd (&rest args)
-  "Run `git bisect ...' and update the status buffer"
-  (with-current-buffer (magit-find-status-buffer)
-    (let* ((output (apply 'magit-git-lines (append '("bisect") args)))
-           (cmd (car args))
-           (first-line (car output)))
-      (save-match-data
-        (setq magit--bisect-info
-              (cond ((string= cmd "reset")
-                     (list :status 'not-running))
-                    ;; Bisecting: 78 revisions left to test after this (roughly 6 steps)
-                    ((string-match "^Bisecting:\\s-+\\([0-9]+\\).+roughly\\s-+\\([0-9]+\\)" first-line)
-                     (list :status 'running
-                           :revs (match-string 1 first-line)
-                           :steps (match-string 2 first-line)))
-                    ;; e2596955d9253a80aec9071c18079705597fa102 is the first bad commit
-                    ((string-match "^\\([a-f0-9]+\\)\\s-.*first bad commit" first-line)
-                     (list :status 'finished
-                           :bad (match-string 1 first-line)))
-                    (t
-                     (list :status 'error)))))))
-  (magit-refresh))
-
-(defun magit--bisect-info-for-status (branch)
-  "Return bisect info suitable for display in the status buffer"
-  (let* ((info (magit--bisect-info))
-         (status (plist-get info :status)))
-    (cond ((eq status 'not-running)
-           (or branch "(detached)"))
-          ((eq status 'running)
-           (format "(bisecting; %s revisions & %s steps left)"
-                   (or (plist-get info :revs) "unknown number of")
-                   (or (plist-get info :steps) "unknown number of")))
-          ((eq status 'finished)
-           (format "(bisected: first bad revision is %s)" (plist-get info :bad)))
-          (t
-           "(bisecting; unknown error occured)"))))
-
-(defun magit-bisect-start ()
-  "Start a bisect session"
-  (interactive)
-  (if (magit--bisecting-p)
-      (error "Already bisecting"))
-  (let ((bad (magit-read-rev "Start bisect with known bad revision" "HEAD"))
-        (good (magit-read-rev "Good revision" (magit-default-rev))))
-    (magit--bisect-cmd "start" bad good)))
-
-(defun magit-bisect-reset ()
-  "Quit a bisect session"
-  (interactive)
-  (unless (magit--bisecting-p)
-    (error "Not bisecting"))
-  (magit--bisect-cmd "reset"))
-
-(defun magit-bisect-good ()
-  "Tell git that the current revision is good during a bisect session"
-  (interactive)
-  (unless (magit--bisecting-p 'running)
-    (error "Not bisecting"))
-  (magit--bisect-cmd "good"))
-
-(defun magit-bisect-bad ()
-  "Tell git that the current revision is bad during a bisect session"
-  (interactive)
-  (unless (magit--bisecting-p 'running)
-    (error "Not bisecting"))
-  (magit--bisect-cmd "bad"))
-
-(defun magit-bisect-skip ()
-  "Tell git to skip the current revision during a bisect session."
-  (interactive)
-  (unless (magit--bisecting-p 'running)
-    (error "Not bisecting"))
-  (magit--bisect-cmd "skip"))
-
-(defun magit-bisect-log ()
-  "Show the bisect log"
-  (interactive)
-  (unless (magit--bisecting-p)
-    (error "Not bisecting"))
-  (magit-run-git "bisect" "log")
-  (magit-display-process))
-
-(defun magit-bisect-visualize ()
-  "Show the remaining suspects with gitk"
-  (interactive)
-  (unless (magit--bisecting-p)
-    (error "Not bisecting"))
-  (magit-run-git "bisect" "visualize")
-  (unless (getenv "DISPLAY")
-    (magit-display-process)))
-
-(easy-mmode-defmap magit-bisect-minibuffer-local-map
-  '(("\C-i" . comint-dynamic-complete-filename))
-  "Keymap for minibuffer prompting of rebase command."
-  :inherit minibuffer-local-map)
-
-(defvar magit-bisect-mode-history nil
-  "Previously run bisect commands.")
-
-(defun magit-bisect-run (command)
-  "Bisect automatically by running commands after each step"
-  (interactive
-   (list
-    (read-from-minibuffer "Run command (like this): "
-                          ""
-                          magit-bisect-minibuffer-local-map
-                          nil
-                          'magit-bisect-mode-history)))
-  (unless (magit--bisecting-p)
-    (error "Not bisecting"))
-  (let ((file (make-temp-file "magit-bisect-run"))
-        buffer)
-    (with-temp-buffer
-      (insert "#!/bin/sh\n" command "\n")
-      (write-region (point-min) (point-max) file))
-    (set-file-modes file #o755)
-    (magit-run-git-async "bisect" "run" file)
-    (magit-display-process)
-    (setq buffer (get-buffer magit-process-buffer-name))
-    (with-current-buffer buffer
-      (set (make-local-variable 'magit--bisect-last-pos) 0)
-      (set (make-local-variable 'magit--bisect-tmp-file) file))
-    (set-process-filter (get-buffer-process buffer) 'magit--bisect-run-filter)
-    (set-process-sentinel (get-buffer-process buffer) 'magit--bisect-run-sentinel)))
-
-(defun magit--bisect-run-filter (process output)
-  (with-current-buffer (process-buffer process)
-    (save-match-data
-      (let ((inhibit-read-only t)
-            line new-info)
-        (insert output)
-        (goto-char magit--bisect-last-pos)
-        (beginning-of-line)
-        (while (< (point) (point-max))
-          (cond ( ;; Bisecting: 78 revisions left to test after this (roughly 6 steps)
-                 (looking-at "^Bisecting:\\s-+\\([0-9]+\\).+roughly\\s-+\\([0-9]+\\)")
-                 (setq new-info (list :status 'running
-                                      :revs (match-string 1)
-                                      :steps (match-string 2))))
-                ( ;; e2596955d9253a80aec9071c18079705597fa102 is the first bad commit
-                 (looking-at "^\\([a-f0-9]+\\)\\s-.*first bad commit")
-                 (setq new-info (list :status 'finished
-                                      :bad (match-string 1)))))
-          (forward-line 1))
-        (goto-char (point-max))
-        (setq magit--bisect-last-pos (point))
-        (if new-info
-            (with-current-buffer (magit-find-status-buffer)
-              (setq magit--bisect-info new-info)
-              (magit--bisect-update-status-buffer)))))))
-
-(defun magit--bisect-run-sentinel (process event)
-  (if (string-match-p "^finish" event)
-      (with-current-buffer (process-buffer process)
-        (delete-file magit--bisect-tmp-file)))
-  (magit-process-sentinel process event))
-
-(defun magit--bisect-update-status-buffer ()
-  (with-current-buffer (magit-find-status-buffer)
-    (save-excursion
-      (save-match-data
-        (let ((inhibit-read-only t))
-          (goto-char (point-min))
-          (when (search-forward-regexp "Local:" nil t)
-            (beginning-of-line)
-            (kill-line)
-            (insert (format "Local:    %s %s"
-                            (propertize (magit--bisect-info-for-status (magit-get-current-branch))
-                                        'face 'magit-branch)
-                            (abbreviate-file-name default-directory)))))))))
-
-(provide 'magit-bisect)
index 8518dcb..839b906 100644 (file)
@@ -1,15 +1,16 @@
-;;; magit-blame.el --- blame support for magit
+;;; 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
+;; Copyright (C) 2012-2014  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: Yann Hodique <yann.hodique@gmail.com>
 
 ;; Author: Yann Hodique <yann.hodique@gmail.com>
-;; Keywords:
+;; Package: magit
+
+;; Contains code from Egg (Emacs Got Git) <https://github.com/byplayer/egg>,
+;; released under the GNU General Public License version 3 or later.
 
 ;; Magit is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published by
 
 ;; Magit is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published by
 
 ;;; Commentary:
 
 
 ;;; Commentary:
 
-;; This code has been backported from Egg (Magit fork) to Magit
+;; Control git-blame from Magit.
+;; This code has been backported from Egg (Magit fork) to Magit.
 
 ;;; Code:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
 (require 'magit)
 (require 'magit)
+(require 'easymenu)
+
+;;; Options
+
+(defgroup magit-blame nil
+  "Git-blame support for Magit."
+  :group 'magit-extensions)
+
+(defcustom magit-blame-ignore-whitespace t
+  "Ignore whitespace when determining blame information."
+  :group 'magit-blame
+  :type 'boolean)
+
+(defcustom magit-time-format-string "%Y-%m-%dT%T%z"
+  "How to format time in magit-blame header."
+  :group 'magit-blame
+  :type 'string)
 
 (defface magit-blame-header
 
 (defface magit-blame-header
-  '((t :inherit magit-header))
+  '((t :inherit magit-section-title))
   "Face for blame header."
   :group 'magit-faces)
 
 (defface magit-blame-sha1
   "Face for blame header."
   :group 'magit-faces)
 
 (defface magit-blame-sha1
-  '((t :inherit (magit-log-sha1
-                 magit-blame-header)))
+  '((t :inherit (magit-log-sha1 magit-blame-header)))
   "Face for blame sha1."
   :group 'magit-faces)
 
   "Face for blame sha1."
   :group 'magit-faces)
 
   "Face for blame tag line."
   :group 'magit-faces)
 
   "Face for blame tag line."
   :group 'magit-faces)
 
-(defconst magit-blame-map
-  (let ((map (make-sparse-keymap "Magit:Blame")))
+;;; Keymaps
+
+(defvar magit-blame-map
+  (let ((map (make-sparse-keymap)))
     (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 "l") 'magit-blame-locate-commit)
     (define-key map (kbd "RET") 'magit-blame-locate-commit)
     (define-key map (kbd "q") 'magit-blame-mode)
     map)
   "Keymap for an annotated section.\\{magit-blame-map}")
 
     map)
   "Keymap for an annotated section.\\{magit-blame-map}")
 
-(defvar magit-blame-buffer-read-only)
-(make-variable-buffer-local 'magit-blame-buffer-read-only)
+(easy-menu-define magit-blame-mode-menu magit-blame-map
+  "Magit blame menu"
+  '("Blame"
+    ["Locate Commit" magit-blame-locate-commit t]
+    ["Next" magit-blame-next-chunk t]
+    ["Previous" magit-blame-previous-chunk t]
+    "---"
+    ["Quit" magit-blame-mode t]))
+
+;;; Mode
+
+(defvar-local magit-blame-buffer-read-only nil)
 
 ;;;###autoload
 (define-minor-mode magit-blame-mode
 
 ;;;###autoload
 (define-minor-mode magit-blame-mode
   :keymap magit-blame-map
   :lighter " blame"
   (unless (buffer-file-name)
   :keymap magit-blame-map
   :lighter " blame"
   (unless (buffer-file-name)
-    (error "Current buffer has no associated file!"))
+    (user-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))
 
   (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)))
+  (cond (magit-blame-mode
+         (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))
+        (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
 
 (defun magit-blame-file-off (buffer)
   (save-excursion
       (with-current-buffer buffer
         (widen)
         (mapc (lambda (ov)
       (with-current-buffer buffer
         (widen)
         (mapc (lambda (ov)
-                (if (overlay-get ov :blame)
-                    (delete-overlay ov)))
+                (when (overlay-get ov :blame)
+                  (delete-overlay ov)))
               (overlays-in (point-min) (point-max)))))))
 
 (defun magit-blame-file-on (buffer)
               (overlays-in (point-min) (point-max)))))))
 
 (defun magit-blame-file-on (buffer)
     (with-current-buffer buffer
       (save-restriction
         (with-temp-buffer
     (with-current-buffer buffer
       (save-restriction
         (with-temp-buffer
-          (magit-git-insert (list "blame" "--porcelain" "--"
-                                  (file-name-nondirectory
-                                   (buffer-file-name buffer))))
+          (apply 'magit-git-insert "blame" "--porcelain"
+                 `(,@(and magit-blame-ignore-whitespace (list "-w")) "--"
+                   ,(file-name-nondirectory (buffer-file-name buffer))))
           (magit-blame-parse buffer (current-buffer)))))))
 
           (magit-blame-parse buffer (current-buffer)))))))
 
+;;; Commands
+
 (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)
 (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)
+      (when (overlay-get ov :blame)
+        (setq sha1 (plist-get (nth 3 (overlay-get ov :blame)) :sha1))))
+    (when sha1
+      (magit-show-commit sha1))))
+
+(defun magit-blame-next-chunk ()
   "Go to the next blame chunk."
   "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))))
+  (interactive)
+  (let ((next (next-single-property-change (point) :blame)))
+    (when next
+      (goto-char next))))
 
 
-(defun magit-blame-previous-chunk (pos)
+(defun magit-blame-previous-chunk ()
   "Go to the previous blame chunk."
   "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))))
+  (interactive)
+  (let ((prev (previous-single-property-change (point) :blame)))
+    (when prev
+      (goto-char prev))))
 
 
-(defcustom magit-time-format-string "%Y-%m-%dT%T%z"
-  "How to format time in magit-blame header."
-  :group 'magit
-  :type 'string)
+;;; Parse
 
 (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
 
 (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."
+containing seconds since epoch or Emacs's (HIGH LOW . IGNORED)
+format."
   (when (numberp tz)
     (unless (numberp unixtime)
       (setq unixtime (float-time unixtime)))
   (when (numberp tz)
     (unless (numberp unixtime)
       (setq unixtime (float-time unixtime)))
@@ -221,7 +220,9 @@ officially supported at the moment."
       (with-current-buffer blame-buf
         (goto-char (point-min))
         ;; search for a ful commit info
       (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)
+        (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))
           (setq commit (match-string-no-properties 1)
                 old-line (string-to-number
                           (match-string-no-properties 2))
@@ -300,4 +301,7 @@ officially supported at the moment."
           (overlay-put ov 'before-string blame))))))
 
 (provide 'magit-blame)
           (overlay-put ov 'before-string blame))))))
 
 (provide 'magit-blame)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
 ;;; magit-blame.el ends here
 ;;; magit-blame.el ends here
index 2fcf296..e486fc3 100644 (file)
+;;; magit-key-mode.el --- interactively tune git invocation
+
+;; Copyright (C) 2010-2014  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: Phil Jackson <phil@shellarchive.co.uk>
+;; Package: magit
+
+;; 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 library implements `magit-key-mode' which is used throughout
+;; Magit to let the user interactively select the command, switches
+;; and options to call Git with.  It can be though of as a way to
+;; provide "postfix" arguments.
+
+;;; Code:
+
 (require 'magit)
 
 (require 'magit)
 
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl-lib))
 
 
-(defvar magit-key-mode-key-maps '()
-  "This will be filled lazily with proper `define-key' built
-  keymaps as they're requested.")
+(defvar magit-key-mode-keymaps)
+(defvar magit-key-mode-last-buffer)
+(defvar magit-pre-key-mode-window-conf)
 
 
-(defvar magit-key-mode-buf-name "*magit-key*"
-  "Name of the buffer.")
+;;; Options
 
 
-(defvar magit-key-mode-current-args '()
-  "Will contain the arguments to be passed to git.")
+(defcustom magit-key-mode-show-usage t
+  "Whether to show usage information when entering a popup."
+  :group 'magit
+  :type 'boolean)
 
 
-(defvar magit-key-mode-current-options '()
-  "Will contain the arguments to be passed to git.")
+;;; Faces
 
 
-(defvar magit-log-mode-window-conf nil
-  "Will hold the pre-menu configuration of magit.")
+(defface magit-key-mode-header-face
+  '((t :inherit font-lock-keyword-face))
+  "Face for key mode header lines."
+  :group 'magit-faces)
+
+(defface magit-key-mode-button-face
+  '((t :inherit font-lock-builtin-face))
+  "Face for key mode buttons."
+  :group 'magit-faces)
 
 
+(defface magit-key-mode-switch-face
+  '((t :inherit font-lock-warning-face))
+  "Face for key mode switches."
+  :group 'magit-faces)
+
+(defface magit-key-mode-args-face
+  '((t :inherit widget-field))
+  "Face for key mode switch arguments."
+  :group 'magit-faces)
+
+;;; Keygroups
+;;;###autoload
 (defvar magit-key-mode-groups
 (defvar magit-key-mode-groups
-  '((logging
+  '((dispatch
+     (actions
+      ("b" "Branching"       magit-key-mode-popup-branching)
+      ("B" "Bisecting"       magit-key-mode-popup-bisecting)
+      ("c" "Committing"      magit-key-mode-popup-committing)
+      ("d" "Diff worktree"   magit-diff-working-tree)
+      ("D" "Diff"            magit-diff)
+      ("f" "Fetching"        magit-key-mode-popup-fetching)
+      ("F" "Pulling"         magit-key-mode-popup-pulling)
+      ("g" "Refresh Buffers" magit-refresh-all)
+      ("l" "Logging"         magit-key-mode-popup-logging)
+      ("m" "Merging"         magit-key-mode-popup-merging)
+      ("M" "Remoting"        magit-key-mode-popup-remoting)
+      ("P" "Pushing"         magit-key-mode-popup-pushing)
+      ("o" "Submoduling"     magit-key-mode-popup-submodule)
+      ("r" "Rewriting"       magit-key-mode-popup-rewriting)
+      ("R" "Rebasing"        magit-rebase-step)
+      ("s" "Show Status"     magit-status)
+      ("S" "Stage all"       magit-stage-all)
+      ("t" "Tagging"         magit-key-mode-popup-tagging)
+      ("U" "Unstage all"     magit-unstage-all)
+      ("v" "Show Commit"     magit-show-commit)
+      ("V" "Show File"       magit-show)
+      ("w" "Wazzup"          magit-wazzup)
+      ("X" "Reset worktree"  magit-reset-working-tree)
+      ("y" "Cherry"          magit-cherry)
+      ("z" "Stashing"        magit-key-mode-popup-stashing)
+      ("!" "Running"         magit-key-mode-popup-running)
+      ("$" "Show Process"    magit-display-process)))
+
+    (logging
      (man-page "git-log")
      (actions
       ("l" "Short" magit-log)
       ("L" "Long" magit-log-long)
      (man-page "git-log")
      (actions
       ("l" "Short" magit-log)
       ("L" "Long" magit-log-long)
-      ("h" "Reflog" magit-reflog)
+      ("h" "Head Reflog" magit-reflog-head)
+      ("f" "File log" magit-file-log)
       ("rl" "Ranged short" magit-log-ranged)
       ("rL" "Ranged long" magit-log-long-ranged)
       ("rl" "Ranged short" magit-log-ranged)
       ("rL" "Ranged long" magit-log-long-ranged)
-      ("rh" "Ranged reflog" magit-reflog-ranged))
+      ("rh" "Reflog" magit-reflog))
      (switches
       ("-m" "Only merge commits" "--merges")
      (switches
       ("-m" "Only merge commits" "--merges")
+      ("-s" "No merge commits" "--no-merges")
+      ("-do" "Date Order" "--date-order")
       ("-f" "First parent" "--first-parent")
       ("-i" "Case insensitive patterns" "-i")
       ("-pr" "Pickaxe regex" "--pickaxe-regex")
       ("-f" "First parent" "--first-parent")
       ("-i" "Case insensitive patterns" "-i")
       ("-pr" "Pickaxe regex" "--pickaxe-regex")
+      ("-g" "Show Graph" "--graph")
       ("-n" "Name only" "--name-only")
       ("-am" "All match" "--all-match")
       ("-al" "All" "--all"))
       ("-n" "Name only" "--name-only")
       ("-am" "All match" "--all-match")
       ("-al" "All" "--all"))
       ("=c" "Committer" "--committer=" read-from-minibuffer)
       ("=>" "Since" "--since=" read-from-minibuffer)
       ("=<" "Before" "--before=" read-from-minibuffer)
       ("=c" "Committer" "--committer=" read-from-minibuffer)
       ("=>" "Since" "--since=" read-from-minibuffer)
       ("=<" "Before" "--before=" read-from-minibuffer)
-      ("=s" "Pickaxe search" "-S" read-from-minibuffer)
       ("=a" "Author" "--author=" read-from-minibuffer)
       ("=a" "Author" "--author=" read-from-minibuffer)
-      ("=g" "Grep" "--grep=" read-from-minibuffer)))
+      ("=g" "Grep messages" "--grep=" read-from-minibuffer)
+      ("=G" "Grep patches" "-G" read-from-minibuffer)
+      ("=L" "Trace evolution of line range [long log only]"
+       "-L" magit-read-file-trace)
+      ("=s" "Pickaxe search" "-S" read-from-minibuffer)
+      ("=b" "Branches" "--branches=" read-from-minibuffer)
+      ("=R" "Remotes" "--remotes=" read-from-minibuffer)))
 
     (running
      (actions
 
     (running
      (actions
-      ("!" "Command from root" magit-shell-command)
-      (":" "Git command" magit-git-command)
-      ("g" "git gui" magit-run-git-gui)
-      ("k" "gitk" magit-run-gitk)))
+      ("!" "Git Subcommand (from root)" magit-git-command-topdir)
+      (":" "Git Subcommand (from pwd)" magit-git-command)
+      ("g" "Git Gui" magit-run-git-gui)
+      ("k" "Gitk" magit-run-gitk)))
 
     (fetching
      (man-page "git-fetch")
 
     (fetching
      (man-page "git-fetch")
      (actions
       ("F" "Pull" magit-pull))
      (switches
      (actions
       ("F" "Pull" magit-pull))
      (switches
+      ("-f" "Force" "--force")
       ("-r" "Rebase" "--rebase")))
 
     (branching
      (man-page "git-branch")
      (actions
       ("v" "Branch manager" magit-branch-manager)
       ("-r" "Rebase" "--rebase")))
 
     (branching
      (man-page "git-branch")
      (actions
       ("v" "Branch manager" magit-branch-manager)
+      ("b" "Checkout" magit-checkout)
       ("c" "Create" magit-create-branch)
       ("c" "Create" magit-create-branch)
-      ("r" "Rename" magit-move-branch)
-      ("k" "Delete" magit-delete-branch)
-      ("b" "Checkout" magit-checkout)))
+      ("r" "Rename" magit-rename-branch)
+      ("k" "Delete" magit-delete-branch))
+     (switches
+      ("-t" "Set upstream configuration" "--track")
+      ("-m" "Merged to HEAD" "--merged")
+      ("-M" "Merged to master" "--merged=master")
+      ("-n" "Not merged to HEAD" "--no-merged")
+      ("-N" "Not merged to master" "--no-merged=master"))
+     (arguments
+      ("=c" "Contains" "--contains=" magit-read-rev-with-default)
+      ("=m" "Merged" "--merged=" magit-read-rev-with-default)
+      ("=n" "Not merged" "--no-merged=" magit-read-rev-with-default)))
 
     (remoting
      (man-page "git-remote")
      (actions
 
     (remoting
      (man-page "git-remote")
      (actions
-      ("v" "Branch manager" magit-branch-manager)
+      ("v" "Remote manager" magit-branch-manager)
       ("a" "Add" magit-add-remote)
       ("r" "Rename" magit-rename-remote)
       ("k" "Remove" magit-remove-remote)))
       ("a" "Add" magit-add-remote)
       ("r" "Rename" magit-rename-remote)
       ("k" "Remove" magit-remove-remote)))
     (tagging
      (man-page "git-tag")
      (actions
     (tagging
      (man-page "git-tag")
      (actions
-      ("t" "Lightweight" magit-tag)
-      ("a" "Annotated" magit-annotated-tag))
+      ("t" "Create" magit-tag)
+      ("k" "Delete" magit-delete-tag))
      (switches
      (switches
-      ("-f" "Force" "-f")))
+      ("-a" "Annotate" "--annotate")
+      ("-f" "Force" "--force")
+      ("-s" "Sign" "--sign")))
 
     (stashing
      (man-page "git-stash")
      (actions
 
     (stashing
      (man-page "git-stash")
      (actions
+      ("v" "View" magit-diff-stash)
       ("z" "Save" magit-stash)
       ("z" "Save" magit-stash)
-      ("s" "Snapshot" magit-stash-snapshot))
+      ("s" "Snapshot" magit-stash-snapshot)
+      ("a" "Apply" magit-stash-apply)
+      ("p" "Pop" magit-stash-pop)
+      ("k" "Drop" magit-stash-drop))
      (switches
       ("-k" "Keep index" "--keep-index")
       ("-u" "Include untracked files" "--include-untracked")
       ("-a" "Include all files" "--all")))
 
      (switches
       ("-k" "Keep index" "--keep-index")
       ("-u" "Include untracked files" "--include-untracked")
       ("-a" "Include all files" "--all")))
 
+    (committing
+     (man-page "git-commit")
+     (actions
+      ("c" "Commit" magit-commit)
+      ("a" "Amend"  magit-commit-amend)
+      ("e" "Extend" magit-commit-extend)
+      ("r" "Reword" magit-commit-reword)
+      ("f" "Fixup"  magit-commit-fixup)
+      ("s" "Squash" magit-commit-squash))
+     (switches
+      ("-a" "Stage all modified and deleted files" "--all")
+      ("-e" "Allow empty commit" "--allow-empty")
+      ("-v" "Show diff of changes to be committed" "--verbose")
+      ("-n" "Bypass git hooks" "--no-verify")
+      ("-s" "Add Signed-off-by line" "--signoff")
+      ("-R" "Claim authorship and reset author date" "--reset-author"))
+     (arguments
+      ("=A" "Override the author" "--author=" read-from-minibuffer)
+      ("=S" "Sign using gpg" "--gpg-sign=" magit-read-gpg-secret-key)))
+
     (merging
      (man-page "git-merge")
      (actions
     (merging
      (man-page "git-merge")
      (actions
-      ("m" "Merge" magit-manual-merge))
+      ("m" "Merge" magit-merge)
+      ("A" "Abort" magit-merge-abort))
      (switches
       ("-ff" "Fast-forward only" "--ff-only")
       ("-nf" "No fast-forward" "--no-ff")
      (switches
       ("-ff" "Fast-forward only" "--ff-only")
       ("-nf" "No fast-forward" "--no-ff")
       ("s" "Stop" magit-rewrite-stop)
       ("a" "Abort" magit-rewrite-abort)
       ("f" "Finish" magit-rewrite-finish)
       ("s" "Stop" magit-rewrite-stop)
       ("a" "Abort" magit-rewrite-abort)
       ("f" "Finish" magit-rewrite-finish)
+      ("d" "Diff pending" magit-rewrite-diff-pending)
       ("*" "Set unused" magit-rewrite-set-unused)
       ("." "Set used" magit-rewrite-set-used)))
 
       ("*" "Set unused" magit-rewrite-set-unused)
       ("." "Set used" magit-rewrite-set-used)))
 
+    (apply-mailbox
+     (man-page "git-am")
+     (actions
+      ("J" "Apply Mailbox" magit-apply-mailbox))
+     (switches
+      ("-s" "add a Signed-off-by line to the commit message" "--signoff")
+      ("-3" "allow fall back on 3way merging if needed" "--3way")
+      ("-k" "pass -k flag to git-mailinfo" "--keep")
+      ("-c" "strip everything before a scissors line" "--scissors")
+      ("-p" "pass it through git-apply" "-p")
+      ("-r" "override error message when patch failure occurs" "--resolvemsg")
+      ("-d" "lie about committer date" "--committer-date-is-author-date")
+      ("-D" "use current timestamp for author date" "--ignore-date")
+      ("-b" "pass -b flag to git-mailinfo" "--keep-non-patch"))
+     (arguments
+      ("=p" "format the patch(es) are in" "--patch-format=" read-from-minibuffer)))
+
     (submodule
      (man-page "git-submodule")
      (actions
     (submodule
      (man-page "git-submodule")
      (actions
       ("b" "Bad" magit-bisect-bad)
       ("g" "Good" magit-bisect-good)
       ("k" "Skip" magit-bisect-skip)
       ("b" "Bad" magit-bisect-bad)
       ("g" "Good" magit-bisect-good)
       ("k" "Skip" magit-bisect-skip)
-      ("l" "Log" magit-bisect-log)
       ("r" "Reset" magit-bisect-reset)
       ("s" "Start" magit-bisect-start)
       ("r" "Reset" magit-bisect-reset)
       ("s" "Start" magit-bisect-start)
-      ("u" "Run" magit-bisect-run)
-      ("v" "Visualize" magit-bisect-visualize))))
-  "Holds the key, help, function mapping for the log-mode. If you
-  modify this make sure you reset `magit-key-mode-key-maps' to
-  nil.")
+      ("u" "Run" magit-bisect-run)))
+
+    (diff-options
+     (actions
+      ("s" "Set" magit-set-diff-options)
+      ("d" "Set default" magit-set-default-diff-options)
+      ("c" "Save default" magit-save-default-diff-options)
+      ("r" "Reset to default" magit-reset-diff-options)
+      ("h" "Toggle Hunk Refinement" magit-diff-toggle-refine-hunk))
+     (switches
+      ("-m" "Show smallest possible diff" "--minimal")
+      ("-p" "Use patience diff algorithm" "--patience")
+      ("-h" "Use histogram diff algorithm" "--histogram")
+      ("-b" "Ignore whitespace changes" "--ignore-space-change")
+      ("-w" "Ignore all whitespace" "--ignore-all-space")
+      ("-W" "Show surrounding functions" "--function-context"))
+     ))
+  "Holds the key, help, function mapping for the log-mode.
+If you modify this make sure you reset `magit-key-mode-keymaps'
+to nil.")
 
 (defun magit-key-mode-delete-group (group)
 
 (defun magit-key-mode-delete-group (group)
-  "Delete a group from `magit-key-mode-key-maps'."
+  "Delete a group from `magit-key-mode-keymaps'."
   (let ((items (assoc group magit-key-mode-groups)))
     (when items
       ;; reset the cache
   (let ((items (assoc group magit-key-mode-groups)))
     (when items
       ;; reset the cache
-      (setq magit-key-mode-key-maps nil)
+      (setq magit-key-mode-keymaps nil)
       ;; delete the whole group
       (setq magit-key-mode-groups
             (delq items magit-key-mode-groups))
       ;; delete the whole group
       (setq magit-key-mode-groups
             (delq items magit-key-mode-groups))
     magit-key-mode-groups))
 
 (defun magit-key-mode-add-group (group)
     magit-key-mode-groups))
 
 (defun magit-key-mode-add-group (group)
-  "Add a new group to `magit-key-mode-key-maps'. If there's
-already a group of that name then this will completely remove it
-and put in its place an empty one of the same name."
+  "Add a new group to `magit-key-mode-keymaps'.
+If there already is a group of that name then this will
+completely remove it 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
   (when (assoc group magit-key-mode-groups)
     (magit-key-mode-delete-group group))
   (setq magit-key-mode-groups
-        (cons (list group (list 'actions)) magit-key-mode-groups)))
+        (cons (list group (list 'actions) (list 'switches) (list 'arguments))
+              magit-key-mode-groups)))
 
 (defun magit-key-mode-key-defined-p (for-group key)
 
 (defun magit-key-mode-key-defined-p (for-group key)
-  "If KEY is defined as any of switch, argument or action within
-FOR-GROUP then return t"
+  "Return t if KEY is defined as any option within FOR-GROUP.
+The option may be a switch, argument or action."
   (catch 'result
     (let ((options (magit-key-mode-options-for-group for-group)))
       (dolist (type '(actions switches arguments))
   (catch 'result
     (let ((options (magit-key-mode-options-for-group for-group)))
       (dolist (type '(actions switches arguments))
@@ -188,7 +351,7 @@ FOR-GROUP then return t"
           (throw 'result t))))))
 
 (defun magit-key-mode-update-group (for-group thing &rest args)
           (throw 'result t))))))
 
 (defun magit-key-mode-update-group (for-group thing &rest args)
-  "Abstraction for setting values in `magit-key-mode-key-maps'."
+  "Abstraction for setting values in `magit-key-mode-keymaps'."
   (let* ((options (magit-key-mode-options-for-group for-group))
          (things (assoc thing options))
          (key (car args)))
   (let* ((options (magit-key-mode-options-for-group for-group))
          (things (assoc thing options))
          (key (car args)))
@@ -197,41 +360,43 @@ FOR-GROUP then return t"
             (error "%s is already defined in the %s group." key for-group)
           (setcdr (cdr things) (cons args (cddr things))))
       (setcdr things (list args)))
             (error "%s is already defined in the %s group." key for-group)
           (setcdr (cdr things) (cons args (cddr things))))
       (setcdr things (list args)))
-    (setq magit-key-mode-key-maps nil)
+    (setq magit-key-mode-keymaps nil)
     things))
 
 (defun magit-key-mode-insert-argument (for-group key desc arg read-func)
     things))
 
 (defun magit-key-mode-insert-argument (for-group key desc arg read-func)
-  "Add a new binding (KEY) in FOR-GROUP which will use READ-FUNC
-to receive input to apply to argument ARG git is run. DESC should
+  "Add a new binding KEY in FOR-GROUP which will use READ-FUNC
+to receive input to apply to argument ARG git is run.  DESC should
 be a brief description of the binding."
   (magit-key-mode-update-group for-group 'arguments key desc arg read-func))
 
 (defun magit-key-mode-insert-switch (for-group key desc switch)
 be a brief description of the binding."
   (magit-key-mode-update-group for-group 'arguments key desc arg read-func))
 
 (defun magit-key-mode-insert-switch (for-group key desc switch)
-  "Add a new binding (KEY) in FOR-GROUP which will add SWITCH to git's
-command line when it runs. DESC should be a brief description of
+  "Add a new binding KEY in FOR-GROUP which will add SWITCH to git's
+command line when it runs.  DESC should be a brief description of
 the binding."
   (magit-key-mode-update-group for-group 'switches key desc switch))
 
 (defun magit-key-mode-insert-action (for-group key desc func)
 the binding."
   (magit-key-mode-update-group for-group 'switches key desc switch))
 
 (defun magit-key-mode-insert-action (for-group key desc func)
-  "Add a new binding (KEY) in FOR-GROUP which will run command
-FUNC. DESC should be a brief description of the binding."
+  "Add a new binding KEY in FOR-GROUP which will run command FUNC.
+DESC should be a brief description of the binding."
   (magit-key-mode-update-group for-group 'actions key desc func))
 
 (defun magit-key-mode-options-for-group (for-group)
   (magit-key-mode-update-group for-group 'actions key desc func))
 
 (defun magit-key-mode-options-for-group (for-group)
-  "Retrieve the options (switches, commands and arguments) for
-the group FOR-GROUP."
+  "Retrieve the options for the group FOR-GROUP.
+This includes switches, commands and arguments."
   (or (cdr (assoc for-group magit-key-mode-groups))
       (error "Unknown group '%s'" for-group)))
 
   (or (cdr (assoc for-group magit-key-mode-groups))
       (error "Unknown group '%s'" for-group)))
 
+;;; Commands
+
 (defun magit-key-mode-help (for-group)
 (defun magit-key-mode-help (for-group)
-  "Provide help for a key (which the user is prompted for) within
-FOR-GROUP."
+  "Provide help for a key within FOR-GROUP.
+The user is prompted for the key."
   (let* ((opts (magit-key-mode-options-for-group for-group))
          (man-page (cadr (assoc 'man-page opts)))
          (seq (read-key-sequence
                (format "Enter command prefix%s: "
                        (if man-page
   (let* ((opts (magit-key-mode-options-for-group for-group))
          (man-page (cadr (assoc 'man-page opts)))
          (seq (read-key-sequence
                (format "Enter command prefix%s: "
                        (if man-page
-                         (format ", `?' for man `%s'" man-page)
+                           (format ", `?' for man `%s'" man-page)
                          ""))))
          (actions (cdr (assoc 'actions opts))))
     (cond
                          ""))))
          (actions (cdr (assoc 'actions opts))))
     (cond
@@ -240,17 +405,17 @@ FOR-GROUP."
       ;; if there is "?" show a man page if there is one
       ((equal seq "?")
        (if man-page
       ;; if there is "?" show a man page if there is one
       ((equal seq "?")
        (if man-page
-         (man man-page)
+           (man man-page)
          (error "No man page associated with `%s'" for-group)))
       (t (error "No help associated with `%s'" seq)))))
 
 (defun magit-key-mode-exec-at-point ()
   "Run action/args/option at point."
   (interactive)
          (error "No man page associated with `%s'" for-group)))
       (t (error "No help associated with `%s'" seq)))))
 
 (defun magit-key-mode-exec-at-point ()
   "Run action/args/option at point."
   (interactive)
-  (let* ((key (or (get-text-property (point) 'key-group-executor)
-                  (error "Nothing at point to do.")))
-         (def (lookup-key (current-local-map) key)))
-    (call-interactively def)))
+  (let ((key (or (get-text-property (point) 'key-group-executor)
+                 (error "Nothing at point to do."))))
+    (call-interactively (lookup-key (current-local-map) key))))
+
 (defun magit-key-mode-jump-to-next-exec ()
   "Jump to the next action/args/option point."
   (interactive)
 (defun magit-key-mode-jump-to-next-exec ()
   "Jump to the next action/args/option point."
   (interactive)
@@ -263,9 +428,15 @@ FOR-GROUP."
     (goto-char p)
     (skip-chars-forward " ")))
 
     (goto-char p)
     (skip-chars-forward " ")))
 
+;;; Keymaps
+
+(defvar magit-key-mode-keymaps nil
+  "This will be filled lazily with proper keymaps.
+These keymaps are created using `define-key' as they're requested.")
+
 (defun magit-key-mode-build-keymap (for-group)
 (defun magit-key-mode-build-keymap (for-group)
-  "Construct a normal looking keymap for the key mode to use and
-put it in magit-key-mode-key-maps for fast lookup."
+  "Construct a normal looking keymap for the key mode to use.
+Put it in `magit-key-mode-keymaps' for fast lookup."
   (let* ((options (magit-key-mode-options-for-group for-group))
          (actions (cdr (assoc 'actions options)))
          (switches (cdr (assoc 'switches options)))
   (let* ((options (magit-key-mode-options-for-group for-group))
          (actions (cdr (assoc 'actions options)))
          (switches (cdr (assoc 'switches options)))
@@ -289,92 +460,98 @@ put it in magit-key-mode-key-maps for fast lookup."
                                  (interactive)
                                  (magit-key-mode-help ',for-group)))
 
                                  (interactive)
                                  (magit-key-mode-help ',for-group)))
 
-    (flet ((defkey (k action)
-             (when (and (lookup-key map (car k))
-                        (not (numberp (lookup-key map (car k)))))
-               (message "Warning: overriding binding for `%s' in %S"
-                        (car k) for-group)
-               (ding)
-               (sit-for 2))
-             (define-key map (car k)
-               `(lambda () (interactive) ,action))))
-      (when actions
-        (dolist (k actions)
-          (defkey k `(magit-key-mode-command ',(nth 2 k)))))
-      (when switches
-        (dolist (k switches)
-          (defkey k `(magit-key-mode-add-option ',for-group ,(nth 2 k)))))
-      (when arguments
-        (dolist (k arguments)
-          (defkey k `(magit-key-mode-add-argument
-                      ',for-group ,(nth 2 k) ',(nth 3 k))))))
-
-    (push (cons for-group map) magit-key-mode-key-maps)
+    (let ((defkey (lambda (k action)
+                    (when (and (lookup-key map (car k))
+                               (not (numberp (lookup-key map (car k)))))
+                      (message "Warning: overriding binding for `%s' in %S"
+                               (car k) for-group)
+                      (ding)
+                      (sit-for 2))
+                    (define-key map (car k)
+                      `(lambda () (interactive) ,action)))))
+      (dolist (k actions)
+        (funcall defkey k `(magit-key-mode-command ',(nth 2 k))))
+      (dolist (k switches)
+        (funcall defkey k `(magit-key-mode-toggle-option ',for-group ,(nth 2 k))))
+      (dolist (k arguments)
+        (funcall defkey k `(magit-key-mode-add-argument
+                            ',for-group ,(nth 2 k) ',(nth 3 k)))))
+
+    (push (cons for-group map) magit-key-mode-keymaps)
     map))
 
     map))
 
+;;; Toggling and Running
+
 (defvar magit-key-mode-prefix nil
 (defvar magit-key-mode-prefix nil
-  "For internal use.  Holds the prefix argument to the command
-that brought up the key-mode window, so it can be used by the
-command that's eventually invoked.")
+  "Prefix argument to the command that brought up the key-mode window.
+For internal use.  Used by the command that's eventually invoked.")
+
+(defvar magit-key-mode-current-args nil
+  "A hash-table of current argument set.
+These will eventually make it to the git command-line.")
+
+(defvar magit-key-mode-current-options nil
+  "Current option set.
+These will eventually make it to the git command-line.")
+
+(defvar magit-custom-options nil
+  "List of custom options to pass to Git.
+Do not customize this (used in the `magit-key-mode' implementation).")
 
 (defun magit-key-mode-command (func)
 
 (defun magit-key-mode-command (func)
-  (let ((args '()))
-    ;; why can't maphash return a list?!
+  (let ((current-prefix-arg (or current-prefix-arg magit-key-mode-prefix))
+        (magit-custom-options magit-key-mode-current-options))
     (maphash (lambda (k v)
     (maphash (lambda (k v)
-               (push (concat k (shell-quote-argument v)) args))
+               (push (concat k v) magit-custom-options))
              magit-key-mode-current-args)
              magit-key-mode-current-args)
-    (let ((magit-custom-options (append args magit-key-mode-current-options))
-          (current-prefix-arg (or current-prefix-arg magit-key-mode-prefix)))
-      (set-window-configuration magit-log-mode-window-conf)
-      (when func
-        (call-interactively func))
-      (magit-key-mode-kill-buffer))))
-
-(defvar magit-key-mode-current-args nil
-  "A hash-table of current argument set (which will eventually
-  make it to the git command-line).")
+    (set-window-configuration magit-pre-key-mode-window-conf)
+    (kill-buffer magit-key-mode-last-buffer)
+    (when func
+      (setq this-command func)
+      (call-interactively this-command))))
 
 (defun magit-key-mode-add-argument (for-group arg-name input-func)
   (let ((input (funcall input-func (concat arg-name ": "))))
     (puthash arg-name input magit-key-mode-current-args)
 
 (defun magit-key-mode-add-argument (for-group arg-name input-func)
   (let ((input (funcall input-func (concat arg-name ": "))))
     (puthash arg-name input magit-key-mode-current-args)
-   (magit-key-mode-redraw for-group)))
-
-(defvar magit-key-mode-current-options '()
-  "Current option set (which will eventually make it to the git
-  command-line).")
-
-(defun magit-key-mode-add-option (for-group option-name)
-  "Toggles the appearance of OPTION-NAME in
-`magit-key-mode-current-options'."
-  (if (not (member option-name magit-key-mode-current-options))
-      (add-to-list 'magit-key-mode-current-options option-name)
-    (setq magit-key-mode-current-options
-          (delete option-name magit-key-mode-current-options)))
+    (magit-key-mode-redraw for-group)))
+
+(defun magit-key-mode-toggle-option (for-group option-name)
+  "Toggles the appearance of OPTION-NAME in `magit-key-mode-current-options'."
+  (if (member option-name magit-key-mode-current-options)
+      (setq magit-key-mode-current-options
+            (delete option-name magit-key-mode-current-options))
+    (add-to-list 'magit-key-mode-current-options option-name))
   (magit-key-mode-redraw for-group))
 
   (magit-key-mode-redraw for-group))
 
-(defun magit-key-mode-kill-buffer ()
-  (interactive)
-  (kill-buffer magit-key-mode-buf-name))
+;;; Mode
 
 
-(defvar magit-log-mode-window-conf nil
-  "Pre-popup window configuration.")
+(defvar magit-key-mode-buf-name "*magit-key: %s*"
+  "Format string to create the name of the magit-key buffer.")
+
+(defvar magit-key-mode-last-buffer nil
+  "Store the last magit-key buffer used.")
+
+(defvar magit-pre-key-mode-window-conf nil
+  "Will hold the pre-menu configuration of magit.")
 
 (defun magit-key-mode (for-group &optional original-opts)
 
 (defun magit-key-mode (for-group &optional original-opts)
-  "Mode for magit key selection. All commands, switches and
-options can be toggled/actioned with the key combination
-highlighted before the description."
+  "Mode for magit key selection.
+All commands, switches and options can be toggled/actioned with
+the key combination highlighted before the description."
   (interactive)
   ;; save the window config to restore it as was (no need to make this
   ;; buffer local)
   (interactive)
   ;; save the window config to restore it as was (no need to make this
   ;; buffer local)
-  (setq magit-log-mode-window-conf
+  (setq magit-pre-key-mode-window-conf
         (current-window-configuration))
   ;; setup the mode, draw the buffer
         (current-window-configuration))
   ;; setup the mode, draw the buffer
-  (let ((buf (get-buffer-create magit-key-mode-buf-name)))
-    (delete-other-windows)
+  (let ((buf (get-buffer-create (format magit-key-mode-buf-name
+                                        (symbol-name for-group)))))
+    (setq magit-key-mode-last-buffer buf)
     (split-window-vertically)
     (other-window 1)
     (switch-to-buffer buf)
     (kill-all-local-variables)
     (split-window-vertically)
     (other-window 1)
     (switch-to-buffer buf)
     (kill-all-local-variables)
+    (set (make-local-variable 'scroll-margin) 0)
     (set (make-local-variable
           'magit-key-mode-current-options)
          original-opts)
     (set (make-local-variable
           'magit-key-mode-current-options)
          original-opts)
@@ -383,19 +560,21 @@ highlighted before the description."
          (make-hash-table))
     (set (make-local-variable 'magit-key-mode-prefix) current-prefix-arg)
     (magit-key-mode-redraw for-group))
          (make-hash-table))
     (set (make-local-variable 'magit-key-mode-prefix) current-prefix-arg)
     (magit-key-mode-redraw for-group))
-  (message
-   (concat
-    "Type a prefix key to toggle it. Run 'actions' with their prefixes. "
-    "'?' for more help.")))
+  (when magit-key-mode-show-usage
+    (message (concat "Type a prefix key to toggle it. "
+                     "Run 'actions' with their prefixes. "
+                     "'?' for more help."))))
 
 (defun magit-key-mode-get-key-map (for-group)
   "Get or build the keymap for FOR-GROUP."
 
 (defun magit-key-mode-get-key-map (for-group)
   "Get or build the keymap for FOR-GROUP."
-  (or (cdr (assoc for-group magit-key-mode-key-maps))
+  (or (cdr (assoc for-group magit-key-mode-keymaps))
       (magit-key-mode-build-keymap for-group)))
 
 (defun magit-key-mode-redraw (for-group)
   "(re)draw the magit key buffer."
   (let ((buffer-read-only nil)
       (magit-key-mode-build-keymap for-group)))
 
 (defun magit-key-mode-redraw (for-group)
   "(re)draw the magit key buffer."
   (let ((buffer-read-only nil)
+        (current-exec (get-text-property (point) 'key-group-executor))
+        (new-exec-pos)
         (old-point (point))
         (is-first (zerop (buffer-size)))
         (actions-p nil))
         (old-point (point))
         (is-first (zerop (buffer-size)))
         (actions-p nil))
@@ -405,20 +584,40 @@ highlighted before the description."
     (setq actions-p (magit-key-mode-draw for-group))
     (delete-trailing-whitespace)
     (setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
     (setq actions-p (magit-key-mode-draw for-group))
     (delete-trailing-whitespace)
     (setq mode-name "magit-key-mode" major-mode 'magit-key-mode)
-    (if (and is-first actions-p)
-      (progn (goto-char actions-p)
-             (magit-key-mode-jump-to-next-exec))
-      (goto-char old-point)))
+    (when current-exec
+      (setq new-exec-pos
+            (cdr (assoc current-exec
+                        (magit-key-mode-build-exec-point-alist)))))
+    (cond ((and is-first actions-p)
+           (goto-char actions-p)
+           (magit-key-mode-jump-to-next-exec))
+          (new-exec-pos
+           (goto-char new-exec-pos)
+           (skip-chars-forward " "))
+          (t
+           (goto-char old-point))))
   (setq buffer-read-only t)
   (fit-window-to-buffer))
 
   (setq buffer-read-only t)
   (fit-window-to-buffer))
 
+(defun magit-key-mode-build-exec-point-alist ()
+  (save-excursion
+    (goto-char (point-min))
+    (let* ((exec (get-text-property (point) 'key-group-executor))
+           (exec-alist (and exec `((,exec . ,(point))))))
+      (cl-do nil ((eobp) (nreverse exec-alist))
+        (when (not (eq exec (get-text-property (point) 'key-group-executor)))
+          (setq exec (get-text-property (point) 'key-group-executor))
+          (when exec (push (cons exec (point)) exec-alist)))
+        (forward-char)))))
+
+;;; Draw Buffer
+
 (defun magit-key-mode-draw-header (header)
   "Draw a header with the correct face."
 (defun magit-key-mode-draw-header (header)
   "Draw a header with the correct face."
-  (insert (propertize header 'face 'font-lock-keyword-face) "\n"))
+  (insert (propertize header 'face 'magit-key-mode-header-face) "\n"))
 
 (defvar magit-key-mode-args-in-cols nil
 
 (defvar magit-key-mode-args-in-cols nil
-  "When true, draw arguments in columns as with switches and
-  options.")
+  "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."
 
 (defun magit-key-mode-draw-args (args)
   "Draw the args part of the menu."
@@ -429,7 +628,7 @@ highlighted before the description."
      (format "(%s) %s"
              (nth 2 x)
              (propertize (gethash (nth 2 x) magit-key-mode-current-args "")
      (format "(%s) %s"
              (nth 2 x)
              (propertize (gethash (nth 2 x) magit-key-mode-current-args "")
-                         'face 'widget-field)))
+                         'face 'magit-key-mode-args-face)))
    (not magit-key-mode-args-in-cols)))
 
 (defun magit-key-mode-draw-switches (switches)
    (not magit-key-mode-args-in-cols)))
 
 (defun magit-key-mode-draw-switches (switches)
@@ -440,7 +639,7 @@ highlighted before the description."
    (lambda (x)
      (format "(%s)" (let ((s (nth 2 x)))
                       (if (member s magit-key-mode-current-options)
    (lambda (x)
      (format "(%s)" (let ((s (nth 2 x)))
                       (if (member s magit-key-mode-current-options)
-                        (propertize s 'face 'font-lock-warning-face)
+                          (propertize s 'face 'magit-key-mode-switch-face)
                         s))))))
 
 (defun magit-key-mode-draw-actions (actions)
                         s))))))
 
 (defun magit-key-mode-draw-actions (actions)
@@ -453,7 +652,7 @@ highlighted before the description."
     (magit-key-mode-draw-header section)
     (magit-key-mode-draw-in-cols
      (mapcar (lambda (x)
     (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))
+               (let* ((head (propertize (car x) 'face 'magit-key-mode-button-face))
                       (desc (nth 1 x))
                       (more (and maker (funcall maker x)))
                       (text (format " %s: %s%s%s"
                       (desc (nth 1 x))
                       (more (and maker (funcall maker x)))
                       (text (format " %s: %s%s%s"
@@ -463,9 +662,9 @@ highlighted before the description."
      one-col-each)))
 
 (defun magit-key-mode-draw-in-cols (strings one-col-each)
      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."
+  "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."
   (let ((longest-act (apply 'max (mapcar 'length strings))))
     (while strings
       (let ((str (car strings)))
   (let ((longest-act (apply 'max (mapcar 'length strings))))
     (while strings
       (let ((str (car strings)))
@@ -483,9 +682,8 @@ item on one line."
   (insert "\n"))
 
 (defun magit-key-mode-draw (for-group)
   (insert "\n"))
 
 (defun magit-key-mode-draw (for-group)
-  "Function used to draw actions, switches and parameters.
-
-Returns the point before the actions part, if any."
+  "Draw actions, switches and parameters.
+Return the point before the actions part, if any, nil otherwise."
   (let* ((options (magit-key-mode-options-for-group for-group))
          (switches (cdr (assoc 'switches options)))
          (arguments (cdr (assoc 'arguments options)))
   (let* ((options (magit-key-mode-options-for-group for-group))
          (switches (cdr (assoc 'switches options)))
          (arguments (cdr (assoc 'arguments options)))
@@ -498,19 +696,29 @@ Returns the point before the actions part, if any."
     (insert "\n")
     p))
 
     (insert "\n")
     p))
 
+;;; Generate Groups
+
 (defun magit-key-mode-de-generate (group)
   "Unbind the function for GROUP."
   (fmakunbound
    (intern (concat "magit-key-mode-popup-" (symbol-name group)))))
 
 (defun magit-key-mode-generate (group)
 (defun magit-key-mode-de-generate (group)
   "Unbind the function for GROUP."
   (fmakunbound
    (intern (concat "magit-key-mode-popup-" (symbol-name group)))))
 
 (defun magit-key-mode-generate (group)
-  "Generate the key-group menu for GROUP"
+  "Generate the key-group menu for GROUP."
   (let ((opts (magit-key-mode-options-for-group group)))
     (eval
      `(defun ,(intern (concat "magit-key-mode-popup-" (symbol-name group))) nil
         ,(concat "Key menu for " (symbol-name group))
         (interactive)
   (let ((opts (magit-key-mode-options-for-group group)))
     (eval
      `(defun ,(intern (concat "magit-key-mode-popup-" (symbol-name group))) nil
         ,(concat "Key menu for " (symbol-name group))
         (interactive)
-        (magit-key-mode (quote ,group))))))
+        (magit-key-mode
+         (quote ,group)
+         ;; As a tempory kludge it is okay to do this here.
+         ,(cl-case group
+            (logging
+             '(list "--graph"))
+            (diff-options
+             '(when (local-variable-p 'magit-diff-options)
+                magit-diff-options))))))))
 
 ;; create the interactive functions for the key mode popups (which are
 ;; applied in the top-level key maps)
 
 ;; create the interactive functions for the key mode popups (which are
 ;; applied in the top-level key maps)
@@ -518,4 +726,10 @@ Returns the point before the actions part, if any."
         (magit-key-mode-generate (car g)))
       magit-key-mode-groups)
 
         (magit-key-mode-generate (car g)))
       magit-key-mode-groups)
 
+;;;###autoload (mapc (lambda (g) (eval `(autoload ',(intern (concat "magit-key-mode-popup-" (symbol-name (car g)))) "magit-key-mode" ,(concat "Key menu for " (symbol-name (car g))) t))) magit-key-mode-groups)
+
 (provide 'magit-key-mode)
 (provide 'magit-key-mode)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; magit-key-mode.el ends here
index 982f2c9..2bdcdff 100644 (file)
@@ -1 +1 @@
-(define-package "magit" "1.2.0" "Control Git from Emacs." 'nil)
+(define-package "magit" "20140508.1256" "control Git from Emacs" '((emacs "23.2") (cl-lib "0.3") (git-commit-mode "0.14.0") (git-rebase-mode "0.14.0")) :keywords ("vc" "tools"))
diff --git a/.emacs.d/elisp/magit/magit-stgit.el b/.emacs.d/elisp/magit/magit-stgit.el
deleted file mode 100644 (file)
index b105b71..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-;;; magit-stgit.el --- StGit plug-in for Magit
-
-;; Copyright (C) 2011  Lluis Vilanova
-;;
-;; 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 StGit functionality as a separate component of Magit.
-
-;; Available actions:
-;; - visit: Shows the patch at point in the series (stg show)
-;; - apply: Goes to the patch at point in the series (stg goto)
-;; - discard: Deletes the marked/at point patch in the series (stg delete)
-
-;; Available commands:
-;; - `magit-stgit-refresh': Refresh the marked/at point patch in the series
-;;   (stg refresh)
-;; - `magit-stgit-repair': Repair the StGit metadata (stg repair)
-;; - `magit-stgit-rebase': Rebase the whole series (stg rebase)
-
-;; TODO:
-;; - Let the user select which files must be included in a refresh.
-;; - Missing actions for `magit-show-item-or-scroll-up' and
-;;   `magit-show-item-or-scroll-down'.
-;; - Marking a patch is slow and refreshes all buffers, which resets their
-;;   position (i.e., the buffer is shown from its first line).
-
-;;; Code:
-
-(require 'magit)
-(eval-when-compile
-  (require 'cl))
-
-;;; Customizables:
-
-(defcustom magit-stgit-executable "stg"
-  "The name of the StGit executable."
-  :group 'magit
-  :type 'string)
-
-(defface magit-stgit-applied
-  '((t :inherit magit-diff-add))
-  "Face for an applied stgit patch."
-  :group 'magit-faces)
-
-(defface magit-stgit-current
-  '((t :inherit magit-item-highlight))
-  "Face for the current stgit patch."
-  :group 'magit-faces)
-
-(defface magit-stgit-other
-  '((t :inherit magit-diff-del))
-  "Face for a non-applied stgit patch."
-  :group 'magit-faces)
-
-(defface magit-stgit-marked
-  '((t :inherit magit-item-mark))
-  "Face for a marked stgit patch."
-  :group 'magit-faces)
-
-(defface magit-stgit-empty
-  '((t :inherit magit-item-mark))
-  "Face for an empty stgit patch."
-  :group 'magit-faces)
-
-;;; Common code:
-
-(defvar magit-stgit--enabled nil
-  "Whether this buffer has StGit support.")
-(make-variable-buffer-local 'magit-stgit--enabled)
-
-(defvar magit-stgit-mode)
-
-(defun magit-stgit--enabled ()
-  "Whether this buffer has StGit support enabled."
-  (if (assoc 'magit-stgit--enabled (buffer-local-variables))
-      magit-stgit--enabled
-    (setq magit-stgit--enabled
-          (and magit-stgit-mode
-               (not (null
-                     (member (concat (magit-get-current-branch) ".stgit")
-                             (mapcar #'(lambda (line)
-                                         (string-match "^\\*?\s*\\([^\s]*\\)"
-                                                       line)
-                                         (match-string 1 line))
-                                     (magit-git-lines "branch")))))))))
-
-(defun magit-stgit--enabled-reset ()
-  "Reset the StGit enabled state."
-  (kill-local-variable 'magit-stgit--enabled))
-
-(defvar magit-stgit--marked-patch nil
-  "The (per-buffer) currently marked patch in an StGit series.")
-(make-variable-buffer-local 'magit-stgit--marked-patch)
-
-;;; Menu:
-
-(easy-menu-define magit-stgit-extension-menu
-  nil
-  "StGit extension menu"
-  '("StGit"
-    :active (magit-stgit--enabled)
-
-    ["Refresh patch" magit-stgit-refresh
-     :help "Refresh the contents of a patch in an StGit series"]
-    ["Repair" magit-stgit-repair
-     :help "Repair StGit metadata if branch was modified with git commands"]
-    ["Rebase series" magit-stgit-rebase
-     :help "Rebase an StGit patch series"]
-    ))
-
-(easy-menu-add-item 'magit-mode-menu
-                    '("Extensions")
-                    magit-stgit-extension-menu)
-
-;;; Series section:
-
-(defun magit-stgit--wash-patch ()
-  (if (search-forward-regexp "^\\(.\\)\\(.\\) \\([^\s]*\\)\\(\s*# ?\\)\\(.*\\)"
-                             (line-end-position) t)
-      (let* ((empty-str "[empty] ")
-             (indent-str (make-string (string-bytes empty-str) ?\ ))
-             (empty (match-string 1))
-             (state (match-string 2))
-             (patch (match-string 3))
-             (descr (match-string 5)))
-        (delete-region (line-beginning-position) (line-end-position))
-        (insert
-         (cond ((string= empty "0")
-                (propertize (concat empty-str " " state " " descr) 'face 'magit-stgit-empty))
-               ((string= magit-stgit--marked-patch patch)
-                (propertize (concat indent-str " " state " " descr) 'face 'magit-stgit-marked))
-               ((string= state "+")
-                (concat indent-str " " (propertize state 'face 'magit-stgit-applied) " " descr))
-               ((string= state ">")
-                (propertize (concat indent-str " " state " " descr) 'face 'magit-stgit-current))
-               ((string= state "-")
-                (concat indent-str " " (propertize state 'face 'magit-stgit-other) " " descr))))
-        (goto-char (line-beginning-position))
-        (magit-with-section patch 'series
-          (magit-set-section-info patch)
-          (goto-char (line-end-position)))
-        (forward-line))
-    (delete-region (line-beginning-position) (1+ (line-end-position))))
-  t)
-
-(defun magit-stgit--wash-series ()
-    (let ((magit-old-top-section nil))
-      (magit-wash-sequence #'magit-stgit--wash-patch)))
-
-(magit-define-inserter series ()
-  (when (executable-find magit-stgit-executable)
-    (magit-insert-section 'series
-                          "Series:" 'magit-stgit--wash-series
-                          magit-stgit-executable "series" "-a" "-d" "-e")))
-
-;;; Actions:
-
-;; Copy of `magit-refresh-commit-buffer' (version 1.0.0)
-(defun magit-stgit--refresh-patch-buffer (patch)
-  (magit-create-buffer-sections
-    (magit-insert-section nil nil
-                       'magit-wash-commit
-                       magit-stgit-executable
-                       "show"
-                       patch)))
-
-;; Copy of `magit-show-commit' (version 1.0.0)
-(defun magit-stgit--show-patch (patch &optional scroll)
-  (when (magit-section-p patch)
-    (setq patch (magit-section-info patch)))
-  (let ((dir default-directory)
-        (buf (get-buffer-create magit-commit-buffer-name)))
-    (cond ((and (equal magit-currently-shown-commit patch)
-                ;; if it's empty then the buffer was killed
-                (with-current-buffer buf
-                  (> (length (buffer-string)) 1)))
-           (let ((win (get-buffer-window buf)))
-             (cond ((not win)
-                    (display-buffer buf))
-                   (scroll
-                    (with-selected-window win
-                      (funcall scroll))))))
-          (t
-           (setq magit-currently-shown-commit patch)
-           (display-buffer buf)
-           (with-current-buffer buf
-             (set-buffer buf)
-             (goto-char (point-min))
-             (magit-mode-init dir 'magit-commit-mode
-                              #'magit-stgit--refresh-patch-buffer patch))))))
-
-(magit-add-action (item info "visit")
-  ((series)
-   (magit-stgit--show-patch info)
-   (pop-to-buffer magit-commit-buffer-name)))
-
-(magit-add-action (item info "apply")
-  ((series)
-   (magit-run magit-stgit-executable "goto" info)))
-
-(magit-add-action (item info "discard")
-  ((series)
-   (let ((patch (or magit-stgit--marked-patch info)))
-     (if (yes-or-no-p (format "Delete patch '%s' in series? " patch))
-         (progn
-           (if (string= magit-stgit--marked-patch patch)
-               (setq magit-stgit--marked-patch nil))
-           (magit-run magit-stgit-executable "delete" patch))))))
-
-(defun magit-stgit--set-marked-patch (patch)
-  (setq magit-stgit--marked-patch
-        (if (string= magit-stgit--marked-patch patch)
-            nil
-          patch)))
-
-(magit-add-action (item info "mark")
-  ((series)
-   (magit-stgit--set-marked-patch info)
-   (magit-refresh-all)))
-
-;;; Commands:
-
-(defun magit-stgit-refresh ()
-  "Refresh the contents of a patch in an StGit series.
-If there is no marked patch in the series, refreshes the current
-patch.
-Otherwise, refreshes the marked patch."
-  (interactive)
-  (if magit-stgit--marked-patch
-      (magit-run magit-stgit-executable "refresh" "-p" magit-stgit--marked-patch)
-    (magit-run magit-stgit-executable "refresh")))
-
-(defun magit-stgit-repair ()
-  "Repair StGit metadata if branch was modified with git commands.
-In the case of Git commits these will be imported as new patches
-into the series."
-  (interactive)
-  (message "Repairing series...")
-  (magit-run magit-stgit-executable "repair")
-  (message ""))
-
-(defun magit-stgit-rebase ()
-  "Rebase an StGit patch series."
-  (interactive)
-  (if (magit-get-current-remote)
-      (progn
-        (if (yes-or-no-p "Update remotes? ")
-            (progn
-              (message "Updating remotes...")
-              (magit-run-git-async "remote" "update")))
-        (magit-run magit-stgit-executable "rebase"
-                   (format "remotes/%s/%s"
-                           (magit-get-current-remote)
-                           (magit-get-current-branch))))))
-
-;;;###autoload
-(define-minor-mode magit-stgit-mode "StGit support for Magit"
-  :lighter " Stg" :require 'magit-stgit
-  (or (derived-mode-p 'magit-mode)
-      (error "This mode only makes sense with magit"))
-  (if magit-stgit-mode
-      (progn
-        (add-hook 'magit-after-insert-stashes-hook 'magit-insert-series nil t))
-    (progn
-      (remove-hook 'magit-after-insert-stashes-hook 'magit-insert-series t)))
-  (when (called-interactively-p 'any)
-    (magit-refresh)))
-
-;;;###autoload
-(defun turn-on-magit-stgit ()
-  "Unconditionally turn on `magit-stgit-mode'."
-  (magit-stgit-mode 1))
-
-(provide 'magit-stgit)
-;;; magit-stgit.el ends here
diff --git a/.emacs.d/elisp/magit/magit-svn.el b/.emacs.d/elisp/magit/magit-svn.el
deleted file mode 100644 (file)
index d08c048..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-;;; magit-svn.el --- git-svn plug-in for Magit
-
-;; Copyright (C) 2008  Alex Ott
-;; Copyright (C) 2009  Alexey Voinov
-;; Copyright (C) 2009  John Wiegley
-;; Copyright (C) 2008  Linh Dang
-;; Copyright (C) 2008  Marcin Bachry
-;; Copyright (C) 2008, 2009  Marius Vollmer
-;; Copyright (C) 2010  Yann Hodique
-;;
-;; 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 git-svn functionality as a separate component of Magit
-
-;;; Code:
-
-(require 'magit)
-(eval-when-compile
-  (require 'cl))
-
-;; git svn commands
-
-(defun magit-svn-find-rev (rev &optional branch)
-  (interactive
-   (list (read-string "SVN revision: ")
-         (if current-prefix-arg
-             (read-string "In branch: "))))
-  (let* ((sha (apply 'magit-git-string
-                     `("svn"
-                       "find-rev"
-                       ,(concat "r" rev)
-                       ,@(when branch (list branch))))))
-    (if sha
-        (magit-show-commit
-         (magit-with-section sha 'commit
-           (magit-set-section-info sha)
-           sha))
-      (error "Revision %s could not be mapped to a commit" rev))))
-
-(defun magit-svn-create-branch (name)
-  (interactive "sBranch name: ")
-  (magit-run-git "svn" "branch" name))
-
-(defun magit-svn-rebase ()
-  (interactive)
-  (magit-run-git-async "svn" "rebase"))
-
-(defun magit-svn-dcommit ()
-  (interactive)
-  (magit-run-git-async "svn" "dcommit"))
-
-(defun magit-svn-enabled ()
-  (not (null (magit-svn-get-ref-info t))))
-
-(defun magit-svn-expand-braces-in-branches (branch)
-  (if (not (string-match "\\(.+\\){\\(.+,.+\\)}\\(.*\\):\\(.*\\)\\\*" branch))
-      (list branch)
-    (let ((prefix (match-string 1 branch))
-          (suffix (match-string 3 branch))
-          (rhs (match-string 4 branch))
-          (pieces (split-string (match-string 2 branch) ",")))
-      (mapcar (lambda (p) (concat prefix p suffix ":" rhs p)) pieces))))
-
-(defun magit-svn-get-local-ref (url)
-  (let* ((branches (cons (magit-get "svn-remote" "svn" "fetch")
-                        (magit-get-all "svn-remote" "svn" "branches")))
-         (branches (apply 'nconc
-                          (mapcar 'magit-svn-expand-braces-in-branches
-                                  branches)))
-        (base-url (magit-get "svn-remote" "svn" "url"))
-        (result nil))
-    (while branches
-      (let* ((pats (split-string (pop branches) ":"))
-             (src (replace-regexp-in-string "\\*" "\\\\(.*\\\\)" (car pats)))
-             (dst (replace-regexp-in-string "\\*" "\\\\1" (cadr pats)))
-             (base-url (replace-regexp-in-string "\\+" "\\\\+" base-url))
-             (base-url (replace-regexp-in-string "//.+@" "//" base-url))
-             (pat1 (concat "^" src "$"))
-             (pat2 (cond ((equal src "") (concat "^" base-url "$"))
-                         (t (concat "^" base-url "/" src "$")))))
-        (cond ((string-match pat1 url)
-               (setq result (replace-match dst nil nil url))
-               (setq branches nil))
-              ((string-match pat2 url)
-               (setq result (replace-match dst nil nil url))
-               (setq branches nil)))))
-    result))
-
-(defvar magit-svn-get-ref-info-cache nil
-  "A cache for svn-ref-info.
-As `magit-get-svn-ref-info' might be considered a quite
-expensive operation a cache is taken so that `magit-status'
-doesn't repeatedly call it.")
-
-(defun magit-svn-get-ref-info (&optional use-cache)
-  "Gather details about the current git-svn repository.
-Return nil if there isn't one.  Keys of the alist are ref-path,
-trunk-ref-name and local-ref-name.
-If USE-CACHE is non-nil then return the value of `magit-get-svn-ref-info-cache'."
-  (if (and use-cache magit-svn-get-ref-info-cache)
-      magit-svn-get-ref-info-cache
-    (let* ((fetch (magit-get "svn-remote" "svn" "fetch"))
-           (url)
-           (revision))
-      (when fetch
-        (let* ((ref (cadr (split-string fetch ":")))
-               (ref-path (file-name-directory ref))
-               (trunk-ref-name (file-name-nondirectory ref)))
-          (set (make-local-variable
-                'magit-svn-get-ref-info-cache)
-                (list
-                 (cons 'ref-path ref-path)
-                 (cons 'trunk-ref-name trunk-ref-name)
-                 ;; get the local ref from the log. This is actually
-                 ;; the way that git-svn does it.
-                 (cons 'local-ref
-                       (with-temp-buffer
-                         (insert (or (magit-git-string "log" "--first-parent"
-                                                       "--grep" "git-svn" "-1")
-                                     ""))
-                         (goto-char (point-min))
-                         (cond ((re-search-forward "git-svn-id: \\(.+/.+?\\)@\\([0-9]+\\)" nil t)
-                                (setq url (match-string 1)
-                                      revision (match-string 2))
-                                (magit-svn-get-local-ref url))
-                               (t
-                                (setq url (magit-get "svn-remote" "svn" "url"))
-                                nil))))
-                 (cons 'revision revision)
-                 (cons 'url url))))))))
-
-(defun magit-svn-get-ref (&optional use-cache)
-  "Get the best guess remote ref for the current git-svn based branch.
-If USE-CACHE is non nil, use the cached information."
-  (let ((info (magit-svn-get-ref-info use-cache)))
-    (cdr (assoc 'local-ref info))))
-
-(magit-define-inserter svn-unpulled (&optional use-cache)
-  (when (magit-svn-enabled)
-    (apply #'magit-git-section
-           'svn-unpulled "Unpulled commits (SVN):" 'magit-wash-log "log"
-           (append magit-git-log-options
-                   (list
-                    (format "HEAD..%s" (magit-svn-get-ref use-cache)))))))
-
-(magit-define-inserter svn-unpushed (&optional use-cache)
-  (when (magit-svn-enabled)
-    (apply #'magit-git-section
-           'svn-unpushed "Unpushed commits (SVN):" 'magit-wash-log "log"
-           (append magit-git-log-options
-                   (list
-                    (format "%s..HEAD" (magit-svn-get-ref use-cache)))))))
-
-(magit-define-section-jumper svn-unpushed  "Unpushed commits (SVN)")
-
-(defun magit-svn-remote-string ()
-  (let ((svn-info (magit-svn-get-ref-info)))
-    (when svn-info
-      (concat (cdr (assoc 'url svn-info))
-              " @ "
-              (cdr (assoc 'revision svn-info))))))
-
-(defun magit-svn-remote-update ()
-  (interactive)
-  (when (magit-svn-enabled)
-    (magit-run-git-async "svn" "fetch")))
-
-(easy-menu-define magit-svn-extension-menu
-  nil
-  "Git SVN extension menu"
-  '("Git SVN"
-    :visible magit-svn-mode
-    ["Create branch" magit-svn-create-branch (magit-svn-enabled)]
-    ["Rebase" magit-svn-rebase (magit-svn-enabled)]
-    ["Fetch" magit-svn-remote-update (magit-svn-enabled)]
-    ["Commit" magit-svn-dcommit (magit-svn-enabled)]))
-
-(easy-menu-add-item 'magit-mode-menu
-                    '("Extensions")
-                    magit-svn-extension-menu)
-
-;; add the group and its keys
-(progn
-  ;; (re-)create the group
-  (magit-key-mode-add-group 'svn)
-
-  (magit-key-mode-insert-action 'svn "r" "Rebase" 'magit-svn-rebase)
-  (magit-key-mode-insert-action 'svn "c" "DCommit" 'magit-svn-dcommit)
-  (magit-key-mode-insert-action 'svn "f" "Fetch" 'magit-svn-remote-update)
-  (magit-key-mode-insert-action 'svn "s" "Find rev" 'magit-svn-find-rev)
-  (magit-key-mode-insert-action 'svn "B" "Create branch" 'magit-svn-create-branch)
-
-  ;; generate and bind the menu popup function
-  (magit-key-mode-generate 'svn))
-
-(defvar magit-svn-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "N") 'magit-key-mode-popup-svn)
-    map))
-
-;;;###autoload
-(define-minor-mode magit-svn-mode "SVN support for Magit"
-  :lighter " SVN" :require 'magit-svn :keymap 'magit-svn-mode-map
-  (or (derived-mode-p 'magit-mode)
-      (error "This mode only makes sense with magit"))
-  (let ((unpulled-hook (lambda () (magit-insert-svn-unpulled t)))
-        (unpushed-hook (lambda () (magit-insert-svn-unpushed t)))
-        (remote-hook 'magit-svn-remote-string))
-    (if magit-svn-mode
-        (progn
-          (add-hook 'magit-after-insert-unpulled-commits-hook unpulled-hook nil t)
-          (add-hook 'magit-after-insert-unpushed-commits-hook unpushed-hook nil t)
-          (add-hook 'magit-remote-string-hook remote-hook nil t))
-      (progn
-        (remove-hook 'magit-after-insert-unpulled-commits-hook unpulled-hook t)
-        (remove-hook 'magit-after-insert-unpushed-commits-hook unpushed-hook t)
-        (remove-hook 'magit-remote-string-hook remote-hook t)))
-    (when (called-interactively-p 'any)
-      (magit-refresh))))
-
-;;;###autoload
-(defun turn-on-magit-svn ()
-  "Unconditionally turn on `magit-svn-mode'."
-  (magit-svn-mode 1))
-
-(provide 'magit-svn)
-;;; magit-svn.el ends here
diff --git a/.emacs.d/elisp/magit/magit-topgit.el b/.emacs.d/elisp/magit/magit-topgit.el
deleted file mode 100644 (file)
index 6f0080c..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-;;; magit-topgit.el --- topgit plug-in for Magit
-
-;; Copyright (C) 2010  Nathan Weizenbaum
-;; Copyright (C) 2010  Yann Hodique
-;;
-;; 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 topgit functionality as a separate component of Magit
-
-;;; Code:
-
-(require 'magit)
-(eval-when-compile
-  (require 'cl))
-
-(defcustom magit-topgit-executable "tg"
-  "The name of the TopGit executable."
-  :group 'magit
-  :type 'string)
-
-(defcustom magit-topgit-branch-prefix "t/"
-  "Convention prefix for topic branch creation."
-  :group 'magit
-  :type 'string)
-
-(defface magit-topgit-current
-  '((t :weight bold :inherit magit-branch))
-  "Face for section titles."
-  :group 'magit-faces)
-
-;;; Topic branches (using topgit)
-
-(defun magit-topgit-in-topic-p ()
-  (and (file-exists-p ".topdeps")
-       (executable-find magit-topgit-executable)))
-
-(defun magit-topgit-create-branch (branch parent)
-  (when (zerop (or (string-match magit-topgit-branch-prefix branch) -1))
-    (magit-run* (list magit-topgit-executable "create"
-                      branch (magit-rev-to-git parent))
-                nil nil nil t)
-    t))
-
-(defun magit-topgit-pull ()
-  (when (magit-topgit-in-topic-p)
-    (magit-run* (list magit-topgit-executable "update")
-                nil nil nil t)
-    t))
-
-(defun magit-topgit-push ()
-  (when (magit-topgit-in-topic-p)
-    (let* ((branch (or (magit-get-current-branch)
-                       (error "Don't push a detached head.  That's gross")))
-           (remote (magit-get "topgit" "remote"))
-           (push-remote (if (or current-prefix-arg (not remote))
-                            (magit-read-remote (format "Push %s to" branch))
-                          remote)))
-      (when (and (not remote)
-                 (not current-prefix-arg))
-        (magit-set push-remote "topgit" "remote"))
-      (magit-run magit-topgit-executable "push" "-r" push-remote))
-    t))
-
-(defun magit-topgit-remote-update (&optional remote)
-  (when (magit-topgit-in-topic-p)
-    (let* ((remote (magit-get "topgit" "remote"))
-           (remote-update (if (or current-prefix-arg (not remote))
-                              (magit-read-remote)
-                            remote)))
-      (if (and (not remote)
-               (not current-prefix-arg))
-          (progn
-            (magit-set remote-update "topgit" "remote")
-            (magit-run magit-topgit-executable "remote"
-                       "--populate" remote-update)))
-      (magit-run magit-topgit-executable "remote" remote-update))
-    ;; We return nil anyway, as we also want regular "git remote update" to
-    ;; happen
-    nil))
-
-(defun magit-topgit-parse-flags (flags-string)
-  (let ((flags (string-to-list flags-string))
-        (void-flag ?\ ))
-    (list :current (not (eq (nth 0 flags) void-flag))
-          :empty (not (eq (nth 1 flags) void-flag)))))
-
-(defun magit-topgit-wash-topic ()
-  (let ((fmt "^\\(.\\{7\\}\\)\\s-\\(\\S-+\\)\\s-+\\(.*\\)"))
-    (if (search-forward-regexp fmt (line-end-position) t)
-        (let ((flags (magit-topgit-parse-flags (match-string 1)))
-              (topic (match-string 2)))
-          (goto-char (line-beginning-position))
-          (delete-char 8)
-          (insert "\t")
-          (goto-char (line-beginning-position))
-          (magit-with-section topic 'topic
-            (magit-set-section-info topic)
-            (let ((beg (1+ (line-beginning-position)))
-                  (end (line-end-position)))
-              (when (plist-get flags :current)
-                (put-text-property beg end 'face 'magit-topgit-current))
-              (when (plist-get flags :empty)
-                (put-text-property beg end 'face `(:strike-through t :inherit ,(get-text-property beg 'face)))))
-            (forward-line)))
-      (delete-region (line-beginning-position) (1+ (line-end-position))))
-    t))
-
-(defun magit-topgit-wash-topics ()
-  (let ((magit-old-top-section nil))
-    (magit-wash-sequence #'magit-topgit-wash-topic)))
-
-(defun magit-topgit-section (section title washer &rest args)
-  (when (executable-find magit-topgit-executable)
-    (let ((magit-git-executable magit-topgit-executable)
-          (magit-git-standard-options nil))
-      (apply 'magit-git-section section title washer args))))
-
-(magit-define-inserter topics ()
-  (magit-topgit-section 'topics
-                        "Topics:" 'magit-topgit-wash-topics
-                        "summary"))
-
-(magit-add-action (item info "discard")
-  ((topic)
-   (when (yes-or-no-p "Discard topic? ")
-     (magit-run* (list magit-topgit-executable "delete" "-f" info)
-                 nil nil nil t))))
-
-(magit-add-action (item info "visit")
-  ((topic)
-   (magit-checkout info)))
-
-(defun magit-topgit-get-top-bases-color (suffix)
-  (list nil nil))
-
-(defun magit-topgit-get-remote-top-bases-color (suffix)
-  (when (string-match "^\\(?:[^/]+\\)/top-bases" suffix)
-    (list nil nil)))
-
-(defconst magit-topgit-ignored-namespace
-  '("top-bases" magit-topgit-get-top-bases-color))
-
-;;;###autoload
-(define-minor-mode magit-topgit-mode "Topgit support for Magit"
-  :lighter " Topgit" :require 'magit-topgit
-  (or (derived-mode-p 'magit-mode)
-      (error "This mode only makes sense with magit"))
-  (if magit-topgit-mode
-      (progn
-        (add-hook 'magit-after-insert-stashes-hook 'magit-insert-topics nil t)
-        (add-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch nil t)
-        (add-hook 'magit-pull-command-hook 'magit-topgit-pull nil t)
-        (add-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update nil t)
-        (add-hook 'magit-push-command-hook 'magit-topgit-push nil t)
-        ;; hide refs for top-bases namespace in any remote
-        (add-hook 'magit-log-remotes-color-hook
-                  'magit-topgit-get-remote-top-bases-color)
-        ;; hide refs in the top-bases namespace, as they're not meant for the user
-        (add-to-list 'magit-refs-namespaces magit-topgit-ignored-namespace))
-    (progn
-        (remove-hook 'magit-after-insert-stashes-hook 'magit-insert-topics t)
-        (remove-hook 'magit-create-branch-command-hook 'magit-topgit-create-branch t)
-        (remove-hook 'magit-pull-command-hook 'magit-topgit-pull t)
-        (remove-hook 'magit-remote-update-command-hook 'magit-topgit-remote-update t)
-        (remove-hook 'magit-push-command-hook 'magit-topgit-push t)
-        (remove-hook 'magit-log-remotes-color-hook
-                     'magit-topgit-get-remote-top-bases-color)
-        (delete magit-topgit-ignored-namespace magit-refs-namespaces)))
-  (when (called-interactively-p 'any)
-    (magit-refresh)))
-
-;;;###autoload
-(defun turn-on-magit-topgit ()
-  "Unconditionally turn on `magit-topgit-mode'."
-  (magit-topgit-mode 1))
-
-(provide 'magit-topgit)
-;;; magit-topgit.el ends here
index 5c19840..e2e3550 100644 (file)
@@ -1,9 +1,14 @@
 ;;; magit-wip.el --- git-wip plug-in for Magit
 
 ;;; magit-wip.el --- git-wip plug-in for Magit
 
-;; Copyright (C) 2012  Jonas Bernoulli
-;; Copyright (C) 2012  Ryan C. Thompson
+;; Copyright (C) 2012-2014  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
 
 
-;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Keywords: vc tools
+;; Package: magit
 
 ;; Magit is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published by
 
 ;; Magit is free software; you can redistribute it and/or modify it
 ;; under the terms of the GNU General Public License as published by
 ;; This requires the third-party git command "git wip" which is available
 ;; from https://github.com/bartman/git-wip.
 
 ;; 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
 ;; 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'.
+;; which you want to use a work-in-progress ref.
 ;;
 ;;
-;;   (magit-wip-mode 1)
 ;;   (global-magit-wip-save-mode 1)
 ;;
 ;;   $ git config --add magit.extension wip-save           # or
 ;;   (global-magit-wip-save-mode 1)
 ;;
 ;;   $ git config --add magit.extension wip-save           # or
 (require 'magit)
 (require 'format-spec)
 
 (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))
+(defun magit-wip-mode (&rest ignore)
+  (message "magit-wip-mode is obsolete and doesn't do anything"))
+(make-obsolete 'magit-wip-mode "This mode is a noop now" "2.0.0")
 
 
-;;;###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))))
+;;; Options
 
 
-;;; Magit Wip Save Mode.
+(defgroup magit-wip nil
+  "Git-Wip support for Magit."
+  :group 'magit-extensions)
 
 (defcustom magit-wip-commit-message "WIP %r"
   "Commit message for git-wip commits.
 
 The following `format'-like specs are supported:
 
 (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
+%f the full name of the file being saved
+%g the root of the git repository
+%r the name of the file being saved,
+   relative to the repository root."
+  :group 'magit-wip
   :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:
   :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
+%f the full name of the file being saved
+%g the root of the git repository
+%r the name of the file being saved,
+   relative to the repository root."
+  :group 'magit-wip
   :type '(choice (const :tag "No message" nil) string))
 
 (defvar magit-wip-save-mode-lighter " Wip")
 
   :type '(choice (const :tag "No message" nil) string))
 
 (defvar magit-wip-save-mode-lighter " Wip")
 
+;;; Mode
+
 ;;;###autoload
 (define-minor-mode magit-wip-save-mode
   "Magit support for committing to a work-in-progress ref.
 
 ;;;###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."
+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
   :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)))
+      (add-hook  'after-save-hook 'magit-wip-save t t)
+    (remove-hook 'after-save-hook 'magit-wip-save t)))
 
 ;;;###autoload
 (define-globalized-minor-mode global-magit-wip-save-mode
   magit-wip-save-mode turn-on-magit-wip-save
 
 ;;;###autoload
 (define-globalized-minor-mode global-magit-wip-save-mode
   magit-wip-save-mode turn-on-magit-wip-save
-  :group 'magit)
+  :group 'magit-wip)
 
 (defun turn-on-magit-wip-save ()
 
 (defun turn-on-magit-wip-save ()
+  "Conditionally turn on magit-wip-save-mode.
+
+Turn on magit-wip-save-mode if the buffer is a file in a git
+repository where wip-save is enabled in git config.
+
+You can activate it with git config magit.extension wip-save."
   (when (and (buffer-file-name)
   (when (and (buffer-file-name)
-             (magit-get-top-dir default-directory)
+             (magit-get-top-dir)
              (member "wip-save" (magit-get-all "magit.extension")))
              (member "wip-save" (magit-get-all "magit.extension")))
-    (if (= (magit-git-exit-code "wip" "-h") 0)
+    (if (magit-git-success "wip" "-h")
         (magit-wip-save-mode 1)
       (message "Git command 'git wip' cannot be found"))))
 
         (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 ()
 (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))
+  (let* ((filename (expand-file-name (file-truename (buffer-file-name))))
+         (filedir  (file-name-directory filename))
+         (toplevel (magit-get-top-dir filedir))
+         (blobname (file-relative-name filename toplevel))
+         (spec `((?f . ,filename)
+                 (?r . ,blobname)
+                 (?g . ,toplevel))))
+    (when (and toplevel (file-writable-p toplevel)
+               (not (member blobname
+                            (let ((default-directory filedir))
+                              (magit-git-lines
+                               "ls-files" "--other" "--ignored"
+                               "--exclude-standard" "--full-name")))))
+      (magit-run-git "wip" "save"
+                     (format-spec magit-wip-commit-message spec)
+                     "--editor" "--" filename)
       (when magit-wip-echo-area-message
         (message (format-spec magit-wip-echo-area-message spec))))))
 
 (provide 'magit-wip)
       (when magit-wip-echo-area-message
         (message (format-spec magit-wip-echo-area-message spec))))))
 
 (provide 'magit-wip)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
 ;;; magit-wip.el ends here
 ;;; magit-wip.el ends here
index 121ec9c..71e7b8f 100644 (file)
@@ -1,55 +1,30 @@
 ;;; magit.el --- control Git from Emacs
 
 ;;; magit.el --- control Git from Emacs
 
-;; Copyright (C) 2010 Aaron Culich.
-;; Copyright (C) 2010 Alan Falloon.
-;; Copyright (C) 2008, 2010 Alex Ott.
-;; Copyright (C) 2008, 2009, 2010 Alexey Voinov.
-;; Copyright (C) 2010 Ben Walton.
-;; Copyright (C) 2010 Chris Bernard.
-;; Copyright (C) 2010 Christian Kluge.
-;; Copyright (C) 2008 Daniel Farina.
-;; Copyright (C) 2010 David Abrahams.
-;; Copyright (C) 2009 David Wallin.
-;; Copyright (C) 2009, 2010 Hannu Koivisto.
-;; Copyright (C) 2009 Ian Eure.
-;; Copyright (C) 2009 Jesse Alama.
-;; Copyright (C) 2009 John Wiegley.
-;; Copyright (C) 2010 Leo.
-;; Copyright (C) 2008, 2009 Marcin Bachry.
-;; Copyright (C) 2008, 2009 Marius Vollmer.
-;; Copyright (C) 2010 Mark Hepburn.
-;; Copyright (C) 2010 Moritz Bunkus.
-;; Copyright (C) 2010 Nathan Weizenbaum.
-;; Copyright (C) 2010 Oscar Fuentes.
-;; Copyright (C) 2009 Pavel Holejsovsky.
-;; Copyright (C) 2011-2012 Peter J Weisberg
-;; Copyright (C) 2009, 2010 Phil Jackson.
-;; Copyright (C) 2010 Philip Weaver.
-;; Copyright (C) 2010 Ramkumar Ramachandra.
-;; Copyright (C) 2010 Remco van 't Veer.
-;; Copyright (C) 2009 René Stadler.
-;; Copyright (C) 2010 Robin Green.
-;; Copyright (C) 2010 Roger Crew.
-;; Copyright (C) 2009, 2010, 2011 Rémi Vanicat.
-;; Copyright (C) 2010 Sean Bryant.
-;; Copyright (C) 2009, 2011 Steve Purcell.
-;; Copyright (C) 2010 Timo Juhani Lindfors.
-;; Copyright (C) 2010, 2011 Yann Hodique.
-;; Copyright (C) 2010 Ævar Arnfjörð Bjarmason.
-;; Copyright (C) 2010 Óscar Fuentes.
-
-;; Original Author: Marius Vollmer <marius.vollmer@nokia.com>
-;; Former Maintainer: Phil Jackson <phil@shellarchive.co.uk>
-;; Maintenance Group: https://github.com/organizations/magit/teams/53130
-;;   Currently composed of:
-;;   - Phil Jackson
-;;   - Peter J Weisberg
-;;   - Yann Hodique
-;;   - Rémi Vanicat
-;; Version: 1.2.0
-;; Keywords: tools
-
+;; Copyright (C) 2008-2014  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: Marius Vollmer <marius.vollmer@gmail.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;; Former-Maintainers:
+;;     Nicolas Dudebout  <nicolas.dudebout@gatech.edu>
+;;     Peter J. Weisberg <pj@irregularexpressions.net>
+;;     Phil Jackson      <phil@shellarchive.co.uk>
+;;     Rémi Vanicat      <vanicat@debian.org>
+;;     Yann Hodique      <yann.hodique@gmail.com>
+
+;; Keywords: vc tools
+;; Package: magit
+;; Package-Requires: ((emacs "23.2") (cl-lib "0.3") (git-commit-mode "0.14.0") (git-rebase-mode "0.14.0"))
+
+;; Magit requires at least GNU Emacs 23.2 and Git 1.7.2.5.
+;; These are the versions shipped by Debian oldstable (6.0, Squeeze).
+
+;; Contains code from GNU Emacs <https://www.gnu.org/software/emacs/>,
+;; released under the GNU General Public License version 3 or later.
+
 ;; 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)
 ;; 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)
 
 ;;; Code:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
-(require 'log-edit)
-(require 'easymenu)
-(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))
-(eval-when-compile (require 'ido))
-(eval-when-compile (require 'ediff))
+(defvar magit-version 'undefined
+  "The version of Magit that you're using.
+Use the function by the same name instead of this variable.")
+;; The value is set at the end of this file, using the
+;; function `magit-version' which is also defined there.
 
 
-;; Dummy to be used by the defcustoms when first loading the file.
-(eval-when (load eval)
-  (defalias 'magit-set-variable-and-refresh 'set-default))
+;;;; Dependencies
 
 
-;;; Code:
-(defgroup magit nil
-  "Controlling Git from Emacs."
-  :prefix "magit-"
-  :group 'tools)
+(when (version< emacs-version "23.2")
+  (error "Magit requires at least GNU Emacs 23.2"))
 
 
-(defcustom magit-git-executable "git"
-  "The name of the Git executable."
-  :group 'magit
-  :type 'string)
+;; Users may choose to use `magit-log-edit' instead of the preferred
+;; `git-commit-mode', by simply putting it on the `load-path'.  If
+;; it can be found there then it is loaded at the end of this file.
+(unless (locate-library "magit-log-edit")
+  (require 'git-commit-mode))
 
 
-(defcustom magit-gitk-executable (concat (file-name-directory magit-git-executable)
-                                         "gitk")
-  "The name of the Gitk executable."
-  :group 'magit
-  :type 'string)
+(require 'git-rebase-mode)
 
 
-(defcustom magit-git-standard-options '("--no-pager")
-  "Standard options when running Git."
-  :group 'magit
-  :type '(repeat string))
+(require 'ansi-color)
+(require 'autorevert)
+(require 'cl-lib)
+(require 'diff-mode)
+(require 'easymenu)
+(require 'epa)
+(require 'format-spec)
+(require 'grep)
+(require 'help-mode)
+(require 'ring)
+(require 'server)
+(require 'tramp)
+(require 'view)
+
+(eval-when-compile
+  (require 'dired)
+  (require 'dired-x)
+  (require 'ediff)
+  (require 'eshell)
+  (require 'ido)
+  (require 'iswitchb)
+  (require 'package nil t)
+  (require 'view))
+
+;;;; Declarations
+
+(if (featurep 'vc-git)
+    (defalias 'magit-grep 'vc-git-grep)
+  (defalias 'magit-grep 'lgrep))
+
+(declare-function dired-jump 'dired-x)
+(declare-function dired-uncache 'dired)
+(declare-function ediff-cleanup-mess 'ediff)
+(declare-function eshell-parse-arguments 'eshell)
+(declare-function ido-completing-read 'ido)
+(declare-function iswitchb-read-buffer 'iswitchb)
+(declare-function package-desc-vers 'package)
+(declare-function package-desc-version 'package)
+(declare-function package-version-join 'package)
+(declare-function view-mode 'view)
 
 
-(defcustom magit-repo-dirs nil
-  "Directories containing Git repositories.
-Magit will look into these directories for Git repositories and
-offer them as choices for `magit-status'."
-  :group 'magit
-  :type '(repeat string))
+(defvar git-commit-previous-winconf)
+(defvar magit-commit-buffer-name)
+(defvar magit-custom-options)
+(defvar magit-log-buffer-name)
+(defvar magit-marked-commit)
+(defvar magit-process-buffer-name)
+(defvar magit-reflog-buffer-name)
+(defvar magit-refresh-args)
+(defvar magit-stash-buffer-name)
+(defvar magit-status-buffer-name)
+(defvar magit-this-process)
+(defvar package-alist)
+
+;;;; Compatibility
 
 
-(defcustom magit-repo-dirs-depth 3
-  "The maximum depth to look for Git repos.
-When looking for a Git repository below the directories in `magit-repo-dirs',
-Magit will only descend this many levels deep."
-  :group 'magit
-  :type 'integer)
+(eval-and-compile
 
 
-(defcustom magit-set-upstream-on-push nil
-  "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.
+  ;; Added in Emacs 24.3
+  (unless (fboundp 'user-error)
+    (defalias 'user-error 'error))
+
+  ;; Added in Emacs 24.3 (mirrors/emacs@b335efc3).
+  (unless (fboundp 'setq-local)
+    (defmacro setq-local (var val)
+      "Set variable VAR to value VAL in current buffer."
+      (list 'set (list 'make-local-variable (list 'quote var)) val)))
+
+  ;; Added in Emacs 24.3 (mirrors/emacs@b335efc3).
+  (unless (fboundp 'defvar-local)
+    (defmacro defvar-local (var val &optional docstring)
+      "Define VAR as a buffer-local variable with default value VAL.
+Like `defvar' but additionally marks the variable as being automatically
+buffer-local wherever it is set."
+      (declare (debug defvar) (doc-string 3))
+      (list 'progn (list 'defvar var val docstring)
+            (list 'make-variable-buffer-local (list 'quote var)))))
+
+  ;; Added in Emacs 24.1
+  (unless (fboundp 'run-hook-wrapped)
+    (defun run-hook-wrapped-1 (hook fns wrap-function &rest args)
+      (cl-loop for fn in fns
+               if (and (eq fn t)
+                       (local-variable-p hook)
+                       (default-boundp hook)
+                       (apply 'run-hook-wrapped-1 nil
+                              (default-value hook) wrap-function args))
+               return it
+               else if (and (functionp fn) (apply wrap-function fn args))
+               return it))
+
+    (defun run-hook-wrapped  (hook wrap-function &rest args)
+      "Run HOOK, passing each function through WRAP-FUNCTION.
+I.e. instead of calling each function FUN directly with arguments ARGS,
+it calls WRAP-FUNCTION with arguments FUN and ARGS.
+As soon as a call to WRAP-FUNCTION returns non-nil, `run-hook-wrapped'
+aborts and returns that value."
+      (when (boundp hook)
+        (let ((fns (symbol-value hook)))
+          (apply 'run-hook-wrapped-1 hook
+                 (if (functionp fns) (list fns) fns)
+                 wrap-function args)))))
+  )
+
+\f
+;;; Settings
+;;;; Custom Groups
 
 
---set-upstream is supported with git > 1.7.0"
-  :group 'magit
-  :type '(choice (const :tag "Never" nil)
-                 (const :tag "Ask" t)
-                 (const :tag "Refuse" refuse)
-                 (const :tag "Always" dontask)))
+(defgroup magit nil
+  "Controlling Git from Emacs."
+  :group 'tools)
 
 
-(defcustom magit-save-some-buffers t
-  "Non-nil means that \\[magit-status] will save modified buffers before running.
-Setting this to t will ask which buffers to save, setting it to 'dontask will
-save all modified buffers without asking."
-  :group 'magit
-  :type '(choice (const :tag "Never" nil)
-                 (const :tag "Ask" t)
-                 (const :tag "Save without asking" dontask)))
+(defgroup magit-process nil
+  "Git and other external processes used by Magit."
+  :group 'magit)
 
 
-(defcustom magit-save-some-buffers-predicate
-  'magit-save-buffers-predicate-tree-only
-  "A predicate function to decide whether to save a buffer.
+(defgroup magit-modes nil
+  "Modes provided by Magit."
+  :group 'magit)
 
 
-Used by function `magit-save-some-buffers' when the variable of
-the same name is non-nil."
+(defgroup magit-status nil
+  "Inspect and manipulate Git repositories."
+  :group 'magit-modes)
 
 
-  :group 'magit
-  :type '(radio (function-item magit-save-buffers-predicate-tree-only)
-                (function-item magit-save-buffers-predicate-all)
-                (function :tag "Other")))
+(defgroup magit-diff nil
+  "Inspect and manipulate Git diffs."
+  :group 'magit-modes)
 
 
-(defcustom magit-default-tracking-name-function
-  'magit-default-tracking-name-remote-plus-branch
-  "Specifies the function to use to generate default tracking branch names
-when doing a \\[magit-checkout].
+(defgroup magit-commit nil
+  "Inspect and manipulate Git commits."
+  :group 'magit-modes)
 
 
-The default is magit-default-tracking-name-remote-plus-branch,
-which generates a tracking name of the form 'REMOTE-BRANCHNAME'."
-  :group 'magit
-  :type '(radio (function-item magit-default-tracking-name-remote-plus-branch)
-                (function-item magit-default-tracking-name-branch-only)
-                (function :tag "Other")))
+(defgroup magit-log nil
+  "Inspect and manipulate Git history."
+  :group 'magit-modes)
 
 
-(defcustom magit-commit-all-when-nothing-staged 'ask
-  "Determines what \\[magit-log-edit] does when nothing is staged.
-Setting this to nil will make it do nothing, setting it to t will
-arrange things so that the actual commit command will use the \"--all\" option,
-setting it to 'ask will first ask for confirmation whether to do this,
-and setting it to 'ask-stage will cause all changes to be staged,
-after a confirmation."
-  :group 'magit
-  :type '(choice (const :tag "No" nil)
-                 (const :tag "Always" t)
-                 (const :tag "Ask" ask)
-                 (const :tag "Ask to stage everything" ask-stage)))
+(defgroup magit-extensions nil
+  "Extensions to Magit."
+  :group 'magit)
 
 
-(defcustom magit-commit-signoff nil
-  "Add the \"Signed-off-by:\" line when committing."
+(defgroup magit-faces nil
+  "Faces used by Magit."
   :group 'magit
   :group 'magit
-  :type 'boolean)
+  :group 'faces)
+
+(when (featurep 'gitattributes-mode)
+  (custom-add-to-group 'magit-modes 'gitattributes-mode 'custom-group))
+
+(when (featurep 'git-commit-mode)
+  (custom-add-to-group 'magit-modes 'git-commit       'custom-group)
+  (custom-add-to-group 'magit-faces 'git-commit-faces 'custom-group))
+
+(when (featurep 'git-rebase-mode)
+  (custom-add-to-group 'magit-modes 'git-rebase       'custom-group)
+  (custom-add-to-group 'magit-faces 'git-rebase-faces 'custom-group))
+
+(custom-add-to-group 'magit 'vc-follow-symlinks 'custom-variable)
+
+;;;; Custom Options
+;;;;; Processes
+
+(defcustom magit-git-executable
+  (or (and (eq system-type 'windows-nt)
+           ;; On Windows asking for "git" from $PATH might also return
+           ;; a "git.exe" or "git.cmd".  Using "bin/git.exe" directly
+           ;; is faster than using one of the wrappers "cmd/git.exe"
+           ;; or "cmd/git.cmd".  The wrappers are likely to come
+           ;; earlier on $PATH, and so we have to exlicitly use
+           ;; the former.
+           (let ((exe (executable-find "git.exe")))
+             (when exe
+               (let ((alt (directory-file-name (file-name-directory exe))))
+                 (if (and (equal (file-name-nondirectory alt) "cmd")
+                          (setq alt (expand-file-name
+                                     (convert-standard-filename "bin/git.exe")
+                                     (file-name-directory alt)))
+                          (file-executable-p alt))
+                     alt
+                   exe)))))
+      (executable-find "git") "git")
+  "The Git executable used by Magit."
+  :group 'magit-process
+  :type 'string)
 
 
-(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-git-standard-options
+  '("--no-pager" "-c" "core.preloadindex=true")
+  "Standard options when running Git.
+Be careful what you add here, especially if you are using
+tramp to connect to servers with ancient Git versions."
+  :group 'magit-process
+  :type '(repeat string))
 
 
-(defcustom magit-log-cutoff-length 100
-  "The maximum number of commits to show in the log and whazzup buffers."
-  :group 'magit
-  :type 'integer)
+(defcustom magit-gitk-executable
+  (or (and (eq system-type 'windows-nt)
+           (let ((exe (expand-file-name
+                       "gitk" (file-name-nondirectory magit-git-executable))))
+             (and (file-executable-p exe) exe)))
+      (executable-find "gitk") "gitk")
+  "The Gitk executable."
+  :group 'magit-process
+  :set-after '(magit-git-executable)
+  :type 'string)
 
 
-(defcustom magit-log-infinite-length 99999
-  "Number of log used to show as maximum for `magit-log-cutoff-length'."
-  :group 'magit
-  :type 'integer)
+(defcustom magit-emacsclient-executable
+  (ignore-errors
+    (shell-quote-argument
+     (let ((version
+            (format "%s.%s" emacs-major-version emacs-minor-version)))
+       (or (and (eq system-type 'darwin)
+                (let ((exec-path
+                       (list (expand-file-name "bin" invocation-directory))))
+                  (executable-find "emacsclient")))
+           (executable-find (format "emacsclient%s"   version))
+           (executable-find (format "emacsclient-%s"   version))
+           (executable-find (format "emacsclient%s.exe" version))
+           (executable-find (format "emacsclient-%s.exe" version))
+           (executable-find (format "emacsclient%s"   emacs-major-version))
+           (executable-find (format "emacsclient-%s"   emacs-major-version))
+           (executable-find (format "emacsclient%s.exe" emacs-major-version))
+           (executable-find (format "emacsclient-%s.exe" emacs-major-version))
+           (executable-find "emacsclient")
+           (executable-find "emacsclient.exe")))))
+  "The Emacsclient executable.
+
+The default value is the full path to the emacsclient executable
+located in the same directory as the executable of the current
+Emacs instance.  If the emacsclient cannot be located in that
+directory then the first executable found anywhere on the
+`exec-path' is used instead.
+
+If no executable can be located then nil becomes the default
+value, and some important Magit commands will fallback to an
+alternative code path.  However `magit-interactive-rebase'
+will stop working at all."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :type '(choice (string :tag "Executable")
+                 (const :tag "Don't use Emacsclient" nil)))
 
 
-(defcustom magit-log-auto-more nil
-  "Insert more log entries automatically when moving past the last entry.
+(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
+  "Connection type used for the git process.
 
 
-Only considered when moving past the last entry with
-`magit-goto-*-section' commands."
-  :group 'magit
-  :type 'boolean)
+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-process
+  :type '(choice (const :tag "pipe" nil)
+                 (const :tag "pty" t)))
 
 (defcustom magit-process-popup-time -1
   "Popup the process buffer if a command takes longer than this many seconds."
 
 (defcustom magit-process-popup-time -1
   "Popup the process buffer if a command takes longer than this many seconds."
-  :group 'magit
+  :group 'magit-process
   :type '(choice (const :tag "Never" -1)
                  (const :tag "Immediately" 0)
                  (integer :tag "After this many seconds")))
 
   :type '(choice (const :tag "Never" -1)
                  (const :tag "Immediately" 0)
                  (integer :tag "After this many seconds")))
 
-(defcustom magit-revert-item-confirm t
-  "Require acknowledgment before reverting an item."
-  :group 'magit
+(defcustom magit-process-log-max 32
+  "Maximum number of sections to keep in a process log buffer.
+When adding a new section would go beyond the limit set here,
+then the older half of the sections are remove.  Sections that
+belong to processes that are still running are never removed."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :type 'integer)
+
+(defcustom magit-process-quote-curly-braces
+  (and (eq system-type 'windows-nt)
+       (let ((case-fold-search t))
+         (string-match-p "cygwin" magit-git-executable))
+       t)
+  "Whether curly braces should be quoted when calling git.
+This may be necessary when using Windows.  On all other system
+types this must always be nil.
+
+We are not certain when quoting is needed, but it appears it is
+needed when using Cygwin Git but not when using stand-alone Git.
+The default value is set based on that assumptions.  If this
+turns out to be wrong you can customize this option but please
+also comment on issue #816."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :set-after '(magit-git-executable)
   :type 'boolean)
 
   :type 'boolean)
 
-(defcustom magit-log-edit-confirm-cancellation nil
-  "Require acknowledgment before canceling the log edit buffer."
+(defcustom magit-process-yes-or-no-prompt-regexp
+   " [\[(]\\([Yy]\\(?:es\\)?\\)[/|]\\([Nn]o?\\)[\])] ?[?:] ?$"
+  "Regexp matching Yes-or-No prompts of git and its subprocesses."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :type 'regexp)
+
+(defcustom magit-process-password-prompt-regexps
+  '("^\\(Enter \\)?[Pp]assphrase\\( for \\(RSA \\)?key '.*'\\)?: ?$"
+    "^\\(Enter \\)?[Pp]assword\\( for '.*'\\)?: ?$"
+    "^.*'s password: ?$"
+    "^Yubikey for .*: ?$")
+  "List of regexps matching password prompts of git and its subprocesses."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :type '(repeat (regexp)))
+
+(defcustom magit-process-username-prompt-regexps
+  '("^Username for '.*': ?$")
+  "List of regexps matching username prompts of git and its subprocesses."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :type '(repeat (regexp)))
+
+(defconst magit-server-window-type
+  '(choice
+    (const :tag "Use selected window"
+           :match (lambda (widget value)
+                    (not (functionp value)))
+           nil)
+    (function-item :tag "Display in new frame" switch-to-buffer-other-frame)
+    (function-item :tag "Use pop-to-buffer" pop-to-buffer)
+    (function :tag "Other function")))
+
+(defcustom magit-server-window-for-commit 'pop-to-buffer
+  "Function used to select a window for displaying commit message buffers.
+It should take one argument (a buffer) and display and select it.
+A common value is `pop-to-buffer'.  It can also be nil in which
+case the selected window is used."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :type magit-server-window-type)
+
+(defcustom magit-server-window-for-rebase server-window
+  "Function used to select a window for displaying interactive rebase buffers.
+It should take one argument (a buffer) and display and select it.
+A common value is `pop-to-buffer'.  It can also be nil in which
+case the selected window is used."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-process
+  :set-after '(server-window)
+  :type magit-server-window-type)
+
+;;;;; Staging
+
+(defcustom magit-stage-all-confirm t
+  "Whether to require confirmation before staging all changes.
+This reduces the risk of accidentally losing the index.  If
+nothing at all is staged yet, then always stage without requiring
+confirmation, because it can be undone without the risk of losing
+a carefully crafted index."
+  :package-version '(magit . "2.0.0")
   :group 'magit
   :type 'boolean)
 
   :group 'magit
   :type 'boolean)
 
-(defcustom magit-remote-ref-format 'branch-then-remote
-  "What format to use for autocompleting refs, in pariticular for remotes.
-
-Autocompletion is used by functions like `magit-checkout',
-`magit-interactive-rebase' and others which offer branch name
-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
-listed as \"remotes/upstream/next\" by \"git branch -l -a\"
-will be \"upstream/next\"."
+(defcustom magit-unstage-all-confirm t
+  "Whether to require confirmation before unstaging all changes.
+This reduces the risk of accidentally losing of the index.  If
+there are no staged changes at all, then always unstage without
+confirmation, because it can be undone without the risk of losing
+a carefully crafted index."
+  :package-version '(magit . "2.0.0")
   :group 'magit
   :group 'magit
-  :type '(choice (const :tag "name (remote)" branch-then-remote)
-                 (const :tag "remote/name" remote-slash-branch)))
-
-(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
-  "Connection type used for the git process.
+  :type 'boolean)
 
 
-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."
+(defcustom magit-revert-item-confirm t
+  "Whether to require confirmation before reverting hunks.
+If you disable this, consider enabling `magit-revert-backup'
+instead."
   :group 'magit
   :group 'magit
-  :type '(choice (const :tag "pipe" nil)
-                 (const :tag "pty" t)))
+  :type 'boolean)
 
 
-(defcustom magit-completing-read-function 'magit-builtin-completing-read
-  "Function to be called when requesting input from the user."
+(defcustom magit-revert-backup nil
+  "Whether to backup a hunk before reverting it.
+The hunk is stored in \".git/magit/reverted.diff\" and can be
+applied using `magit-revert-undo'.  Older hunks are available
+in the same directory as numbered backup files and have to be
+applied manually.  Only individual hunks are backed up; when
+a complete file is reverted (which requires confirmation) no
+backup is created."
+  :package-version '(magit . "2.1.0")
   :group 'magit
   :group 'magit
-  :type '(radio (function-item magit-iswitchb-completing-read)
-                (function-item magit-ido-completing-read)
-                (function-item magit-builtin-completing-read)
-                (function :tag "Other")))
+  :type 'boolean)
 
 
-(defcustom magit-create-branch-behaviour 'at-head
-  "Where magit will create a new branch if not supplied a branchname or ref.
+(defcustom magit-save-some-buffers t
+  "Whether certain commands save modified buffers before running.
 
 
-The value 'at-head means a new branch will be created at the tip
-of your current branch, while the value 'at-point means magit
-will try to find a valid reference at point..."
+nil        don't save buffers.
+t          ask which buffers to save.
+`dontask'  save all buffers without asking."
   :group 'magit
   :group 'magit
-  :type '(choice (const :tag "at HEAD" at-head)
-                 (const :tag "at point" at-point)))
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Save without asking" dontask)))
 
 
-(defcustom magit-status-buffer-switch-function 'pop-to-buffer
-  "Function for `magit-status' to use for switching to the status buffer.
+(defcustom magit-save-some-buffers-predicate
+  'magit-save-buffers-predicate-tree-only
+  "A predicate function to decide whether to save a buffer.
 
 
-The function is given one argument, the status buffer."
+Used by function `magit-save-some-buffers' when the variable of
+the same name is non-nil."
   :group 'magit
   :group 'magit
-  :type '(radio (function-item switch-to-buffer)
-                (function-item pop-to-buffer)
+  :type '(radio (function-item magit-save-buffers-predicate-tree-only)
+                (function-item magit-save-buffers-predicate-all)
                 (function :tag "Other")))
 
 (defcustom magit-rewrite-inclusive t
                 (function :tag "Other")))
 
 (defcustom magit-rewrite-inclusive t
@@ -313,23 +494,35 @@ cumbersome to use from the status buffer.
                  (const :tag "Never" nil)
                  (const :tag "Ask"   ask)))
 
                  (const :tag "Never" nil)
                  (const :tag "Ask"   ask)))
 
+;;;;; Highlighting
+
+(defun magit-set-variable-and-refresh (symbol value)
+  "Set SYMBOL to VALUE and call `magit-refresh-all'."
+  (set-default symbol value)
+  ;; If magit isn't fully loaded yet no buffer that might
+  ;; need refreshing can exist and we can take a shortcut.
+  ;; We also don't want everything to repeatedly refresh
+  ;; when evaluating this file.
+  (when (and (featurep 'magit) (not buffer-file-name))
+    (magit-refresh-all)))
+
 (defcustom magit-highlight-whitespace t
 (defcustom magit-highlight-whitespace t
-  "Specifies where to highlight whitespace errors.
+  "Specify where to highlight whitespace errors.
 See `magit-highlight-trailing-whitespace',
 `magit-highlight-indentation'.  The symbol t means in all diffs,
 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."
+`status' means only in the status buffer, and nil means nowhere."
   :group 'magit
   :group 'magit
+  :set 'magit-set-variable-and-refresh
   :type '(choice (const :tag "Always" t)
                  (const :tag "Never" nil)
   :type '(choice (const :tag "Always" t)
                  (const :tag "Never" nil)
-                 (const :tag "In status buffer" status))
-  :set 'magit-set-variable-and-refresh)
+                 (const :tag "In status buffer" status)))
 
 (defcustom magit-highlight-trailing-whitespace t
 
 (defcustom magit-highlight-trailing-whitespace t
-  "Highlight whitespace at the end of a line in diffs.
+  "Whether to highlight whitespace at the end of a line in diffs.
 Used only when `magit-highlight-whitespace' is non-nil."
   :group 'magit
 Used only when `magit-highlight-whitespace' is non-nil."
   :group 'magit
-  :type 'boolean
-  :set 'magit-set-variable-and-refresh)
+  :set 'magit-set-variable-and-refresh
+  :type 'boolean)
 
 (defcustom magit-highlight-indentation nil
   "Highlight the \"wrong\" indentation style.
 
 (defcustom magit-highlight-indentation nil
   "Highlight the \"wrong\" indentation style.
@@ -345,82 +538,665 @@ If the value is `tabs', highlight indentation with tabs.  If the
 value is an integer, highlight indentation with at least that
 many spaces.  Otherwise, highlight neither."
   :group 'magit
 value is an integer, highlight indentation with at least that
 many spaces.  Otherwise, highlight neither."
   :group 'magit
+  :set 'magit-set-variable-and-refresh
   :type `(repeat (cons (string :tag "Directory regexp")
                        (choice (const :tag "Tabs" tabs)
                                (integer :tag "Spaces" :value ,tab-width)
   :type `(repeat (cons (string :tag "Directory regexp")
                        (choice (const :tag "Tabs" tabs)
                                (integer :tag "Spaces" :value ,tab-width)
-                               (const :tag "Neither" nil))))
-  :set 'magit-set-variable-and-refresh)
+                               (const :tag "Neither" nil))))) ;^FIXME
+
+(defcustom magit-item-highlight-face 'magit-item-highlight
+  "The face used to highlight the current section.
+
+By default the highlighting of the current section is done using
+the background color specified by face `magit-item-highlight'.
+
+If you don't want to use the background to do the highlighting,
+this *might* by as easy as customizing that face.  However if you
+are using a theme, which in turn sets the background color of
+that face then, due to limitations in face inheritance when using
+themes, you might be forced to use another face.
+
+Unfortunately it is only possible to override a face attribute,
+set by a theme, but not to drop it entirely.  This means that one
+has to explicitly use the `default' background color, to make it
+appear *as if* the background wasn't used.
+
+One reason you might want to *not* use the background, is that
+doing so forces the use of overlays for parts of diffs and for
+refnames.  Using overlays potentially degrades performance when
+generating large diffs.  Also see option `magit-use-overlays'."
+  :package-version '(magit . "2.0.0")
+  :group 'magit
+  :group 'magit-faces
+  :type '(choice (const magit-item-highlight)
+                 (const bold)
+                 (face  :tag "Other face")
+                 (const :tag "Don't highlight" nil)))
+
+(defcustom magit-use-overlays
+  (not (eq magit-item-highlight-face 'bold))
+  "Whether to use overlays to highlight various diff components.
+
+This has to be non-nil if the current section is highlighted by
+changing the background color.  Otherwise background colors that
+hold semantic meaning, like that of the added and removed lines
+in diffs, as well as section headings, would be shadowed by the
+highlighting.
+
+To select the face used for highlighting customize the option
+`magit-item-highlight-face'.  If you set that to `bold' or some
+other face that does not use the background then you can set this
+option to nil.  Doing so could potentially improve performance
+when generating large diffs."
+  :package-version '(magit . "2.1.0")
+  :group 'magit
+  :group 'magit-faces
+  :set-after '(magit-item-highlight-face)
+  :type 'boolean)
 
 
-(defcustom magit-diff-refine-hunk nil
-  "Show fine (word-granularity) differences within diff hunks.
+(define-obsolete-variable-alias 'magit-diff-use-overlays
+  'magit-use-overlays "2.1.0")
 
 
-There are three possible settings:
+;;;;; Completion
+
+(defcustom magit-completing-read-function 'magit-builtin-completing-read
+  "Function to be called when requesting input from the user."
+  :group 'magit
+  :type '(radio (function-item magit-iswitchb-completing-read)
+                (function-item magit-ido-completing-read)
+                (function-item magit-builtin-completing-read)
+                (function :tag "Other")))
+
+(defcustom magit-remote-ref-format 'remote-slash-branch
+  "How to format refs when autocompleting, in particular for remotes.
+
+Autocompletion is used by functions like `magit-checkout',
+`magit-interactive-rebase' and others which offer branch name
+completion.
+
+`remote-slash-branch'  Format refs as \"remote/branch\".
+`branch-then-remote'   Format refs as \"branch (remote)\"."
+  :package-version '(magit . "2.0.0")
+  :group 'magit
+  :type '(choice (const :tag "branch (remote)" branch-then-remote)
+                 (const :tag "remote/branch" remote-slash-branch)))
+
+(defcustom magit-repo-dirs nil
+  "Directories containing Git repositories.
+Magit will look into these directories for Git repositories and
+offer them as choices for `magit-status'."
+  :group 'magit
+  :type '(repeat string))
 
 
-  nil means to never show fine differences
+(defcustom magit-repo-dirs-depth 3
+  "The maximum depth to look for Git repos.
+When looking for a Git repository below the directories in
+`magit-repo-dirs', Magit will only descend this many levels
+deep."
+  :group 'magit
+  :type 'integer)
 
 
-  t means to only show fine differences for the currently
-  selected diff hunk
+(defcustom magit-default-tracking-name-function
+  'magit-default-tracking-name-remote-plus-branch
+  "Function used to generate default tracking branch names
+when doing a \\[magit-checkout].
 
 
-  `all' means to always show fine differences for all displayed diff hunks"
+The default is `magit-default-tracking-name-remote-plus-branch',
+which generates a tracking name of the form \"REMOTE-BRANCHNAME\"."
   :group 'magit
   :group 'magit
+  :type '(radio (function-item magit-default-tracking-name-remote-plus-branch)
+                (function-item magit-default-tracking-name-branch-only)
+                (function :tag "Other")))
+
+;;;;; Modes
+;;;;;; Common
+
+(defcustom magit-mode-hook nil
+  "Hook run when entering a Magit mode derived mode."
+  :group 'magit-modes
+  :type 'hook)
+
+(defcustom magit-show-xref-buttons '(magit-diff-mode magit-commit-mode)
+  "List of modes whose buffers should contain history buttons.
+Currently only `magit-diff-mode' and `magit-commit-mode' are
+supported."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type '(repeat (choice (const magit-diff-mode)
+                         (const magit-commit-mode))))
+
+(defcustom magit-show-child-count nil
+  "Whether to append the number of childen to section headings."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type 'boolean)
+
+(defvar magit-status-line-align-to 9)
+
+(defcustom magit-restore-window-configuration nil
+  "Whether quitting a Magit buffer restores previous window configuration.
+
+Function `magit-mode-display-buffer' is used to display and
+select Magit buffers.  Unless the buffer was already displayed in
+a window of the selected frame it also stores the previous window
+configuration.  If this option is non-nil that configuration will
+later be restored by `magit-mode-quit-window', provided the
+buffer has not since been displayed in another frame.
+
+This works best when only two windows are usually displayed in a
+frame.  If this isn't the case setting this to t might often lead
+to undesirable behaviour.  Also quitting a Magit buffer while
+another Magit buffer that was created earlier is still displayed
+will cause that buffer to be hidden, which might or might not be
+what you want."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type 'boolean)
+
+(defcustom magit-refs-namespaces
+  '(("^\\(HEAD\\)$"              magit-log-head-label-head nil)
+    ("^refs/tags/\\(.+\\)"       magit-log-head-label-tags nil)
+    ("^refs/heads/\\(.+\\)"      magit-log-head-label-local nil)
+    ("^refs/remotes/\\(.+\\)"    magit-log-head-label-remote nil)
+    ("^refs/bisect/\\(bad\\)"    magit-log-head-label-bisect-bad nil)
+    ("^refs/bisect/\\(skip.*\\)" magit-log-head-label-bisect-skip nil)
+    ("^refs/bisect/\\(good.*\\)" magit-log-head-label-bisect-good nil)
+    ("^refs/wip/\\(.+\\)"        magit-log-head-label-wip nil)
+    ("^refs/patches/\\(.+\\)"    magit-log-head-label-patches nil)
+    ("^\\(bad\\):"               magit-log-head-label-bisect-bad nil)
+    ("^\\(skip\\):"              magit-log-head-label-bisect-skip nil)
+    ("^\\(good\\):"              magit-log-head-label-bisect-good nil)
+    ("\\(.+\\)"                  magit-log-head-label-default nil))
+  "How different refs should be formatted for display.
+
+Each entry controls how a certain type of ref is displayed, and
+has the form (REGEXP FACE FORMATTER).  REGEXP is a regular
+expression used to match full refs.  The first entry whose REGEXP
+matches the reference is used.  The first regexp submatch becomes
+the \"label\" that represents the ref and is propertized with
+font FONT.  If FORMATTER is non-nil it should be a function that
+takes two arguments, the full ref and the face.  It is supposed
+to return a propertized label that represents the ref.
+
+Currently this variable is only used in logs and the branch
+manager but it will be used in more places in the future."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type '(repeat
+          (list regexp
+                face
+                (choice (const :tag "first submatch is label" nil)
+                        (function :tag "format using function")))))
+
+;;;;;; Status
+
+(defcustom magit-status-sections-hook
+  '(magit-insert-status-local-line
+    magit-insert-status-remote-line
+    magit-insert-status-head-line
+    magit-insert-status-tags-line
+    magit-insert-status-merge-line
+    magit-insert-status-rebase-lines
+    magit-insert-empty-line
+    magit-insert-rebase-sequence
+    magit-insert-bisect-output
+    magit-insert-bisect-rest
+    magit-insert-bisect-log
+    magit-insert-stashes
+    magit-insert-untracked-files
+    magit-insert-pending-commits
+    magit-insert-unstaged-changes
+    magit-insert-staged-changes
+    magit-insert-unpulled-commits
+    magit-insert-unpushed-commits)
+  "Hook run to insert sections into the status buffer.
+
+This option allows reordering the sections and adding sections
+that are by default displayed in other Magit buffers.  Doing the
+latter is currently not recommended because not all functions
+that insert sections have been adapted yet.  Only inserters that
+take no argument can be used and some functions exist that begin
+with the `magit-insert-' prefix but do not insert a section.
+
+Note that there are already plans to improve this and to add
+similar hooks for other Magit modes."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-status
+  :type 'hook)
+
+(defcustom magit-status-buffer-switch-function 'pop-to-buffer
+  "Function for `magit-status' to use for switching to the status buffer.
+
+The function is given one argument, the status buffer."
+  :group 'magit-status
+  :type '(radio (function-item switch-to-buffer)
+                (function-item pop-to-buffer)
+                (function :tag "Other")))
+
+(defcustom magit-status-show-sequence-help t
+  "Whether to show instructions on how to proceed a stopped action.
+When this is non-nil and a commit failed to apply during a merge
+or rebase, then show instructions on how to continue."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-status
+  :type 'boolean)
+
+(defcustom magit-status-tags-line-subject 'head
+  "Whether tag or head is the subject on tags line in status buffer.
+
+This controls how the words \"ahead\" and \"behind\" are used on
+the tags line in the status buffer.  The tags line does not
+actually display complete sentences, but when thinking about when
+to use which term, it helps imagining it did.  This option
+controls whether the tag names should be considered the subjects
+or objects in these sentences.
+
+`tag'   The previous tag is *behind* HEAD by N commits.
+        The next tag is *ahead* of HEAD by N commits.
+`head'  HEAD is *ahead* of the previous tag by N commits.
+        HEAD is *behind* the next tag by N commits.
+
+If the value is `tag' the commit counts are fontified; otherwise
+they are not (due to semantic considerations)."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-status
+  :type '(choice (const :tag "tags are the subjects" tag)
+                 (const :tag "head is the subject" head)))
+
+;;;;;; Diff
+
+(defun magit-set-default-diff-options (symbol value)
+  "Set the default for `magit-diff-options' based on popup value.
+Also set the local value in all Magit buffers and refresh them.
+\n(fn)" ; The arguments are an internal implementation detail.
+  (interactive (list 'magit-diff-options magit-custom-options))
+  (set-default symbol value)
+  (when (and (featurep 'magit) (not buffer-file-name))
+    (dolist (buffer (buffer-list))
+      (when (derived-mode-p 'magit-mode)
+        (with-current-buffer buffer
+          (with-no-warnings
+            (setq-local magit-diff-options value))
+          (magit-mode-refresh-buffer))))))
+
+(defcustom magit-diff-options nil
+  "Git options used to display diffs.
+
+For more information about the options see man:git-diff.
+This variable can be conveniently set in Magit buffers
+using `magit-key-mode-popup-diff-options' (bound to \
+\\<magit-mode-map>\\[magit-key-mode-popup-diff-options]).
+
+Please note that not all of these options are supported by older
+versions of Git, which could become a problem if you use tramp to
+access repositories on a system with such a version.  If you see
+whitespace where you would have expected a diff, this likely is
+the cause, and the only (currently) workaround is to not make the
+problematic option a member of the default value."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-diff
+  :set 'magit-set-default-diff-options
+  :type '(set :greedy t
+              (const :tag
+                     "--minimal              Show smallest possible diff"
+                     "--minimal")
+              (const :tag
+                     "--patience             Use patience diff algorithm"
+                     "--patience")
+              (const :tag
+                     "--histogram            Use histogram diff algorithm"
+                     "--histogram")
+              (const :tag
+                     "--ignore-space-change  Ignore whitespace changes"
+                     "--ignore-space-change")
+              (const :tag
+                     "--ignore-all-space     Ignore all whitespace"
+                     "--ignore-all-space")
+              (const :tag
+                     "--function-context     Show surrounding functions"
+                     "--function-context")))
+
+(put 'magit-diff-options 'permanent-local t)
+
+(defcustom magit-show-diffstat t
+  "Whether to show diffstat in diff and commit buffers."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-diff
+  :group 'magit-commit
+  :type 'boolean)
+
+(defcustom magit-diff-refine-hunk nil
+  "Show fine (word-granularity) differences within diff hunks.
+
+There are three possible settings:
+
+nil    never show fine differences
+t      show fine differences for the selected diff hunk only
+`all'  show fine differences for all displayed diff hunks"
+  :group 'magit-diff
   :type '(choice (const :tag "Never" nil)
                  (const :tag "Selected only" t)
                  (const :tag "All" all))
   :set 'magit-set-variable-and-refresh)
 
   :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.
-This is calculated from `magit-highlight-indentation'.")
-(make-variable-buffer-local 'magit-current-indentation)
+;;;;;; Commit
 
 
-(defgroup magit-faces nil
-  "Customize the appearance of Magit."
-  :prefix "magit-"
-  :group 'faces
-  :group 'magit)
+(defcustom magit-commit-ask-to-stage t
+  "Whether to ask to stage everything when committing and nothing is staged."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-commit
+  :type 'boolean)
 
 
-(defface magit-header
-  '((t :inherit header-line))
-  "Face for generic header lines.
+(defcustom magit-commit-extend-override-date nil
+  "Whether using `magit-commit-extend' changes the committer date."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-commit
+  :type 'boolean)
 
 
-Many Magit faces inherit from this one by default."
-  :group 'magit-faces)
+(defcustom magit-commit-reword-override-date nil
+  "Whether using `magit-commit-reword' changes the committer date."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-commit
+  :type 'boolean)
 
 
-(defface magit-section-title
-  '((t :inherit magit-header))
-  "Face for section titles."
-  :group 'magit-faces)
+(defcustom magit-commit-squash-commit nil
+  "Whether to target the marked or current commit when squashing.
+
+When this is nil then the command `magit-commit-fixup' and
+`magit-commit-squash' always require that the user explicitly
+selects a commit.  This is also the case when these commands are
+used with a prefix argument, in which case this option is ignored.
+
+Otherwise this controls which commit to target, either the
+current or marked commit.  Or if both can be used, which should
+be preferred."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-commit
+  :type
+  '(choice
+    (const :tag "Always prompt" nil)
+    (const :tag "Prefer current commit, else use marked" current-or-marked)
+    (const :tag "Prefer marked commit, else use current" marked-or-current)
+    (const :tag "Use current commit, if any" current)
+    (const :tag "Use marked commit, if any" marked)))
+
+(defcustom magit-expand-staged-on-commit nil
+  "Whether to expand staged changes when creating a commit.
+When this is non-nil and the current buffer is the status buffer
+expand the section containing staged changes.  If this is `full'
+always expand all subsections; if it is t subsections that were
+previously hidden remain hidden.
+
+In the event that expanding very large patches takes a long time
+\\<global-map>\\[keyboard-quit] can be used to abort that step.
+This is especially useful when you would normally not look at the
+changes, e.g. because you are committing some binary files."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-commit
+  :type '(choice (const :tag "Expand all subsections" full)
+                 (const :tag "Expand top section" t)
+                 (const :tag "Don't expand" nil)))
+
+;;;;;; Log
 
 
-(defface magit-branch
-  '((t :inherit magit-header))
-  "Face for the current branch."
-  :group 'magit-faces)
+(defcustom magit-log-auto-more nil
+  "Insert more log entries automatically when moving past the last entry.
 
 
-(defface magit-diff-file-header
-  '((t :inherit diff-file-header))
-  "Face for diff file header lines."
-  :group 'magit-faces)
+Only considered when moving past the last entry with
+`magit-goto-*-section' commands."
+  :group 'magit-log
+  :type 'boolean)
 
 
-(defface magit-diff-hunk-header
-  '((t :inherit diff-hunk-header))
-  "Face for diff hunk header lines."
-  :group 'magit-faces)
+(defcustom magit-log-cutoff-length 100
+  "The maximum number of commits to show in the log and whazzup buffers."
+  :group 'magit-log
+  :type 'integer)
 
 
-(defface magit-diff-add
-  '((t :inherit diff-added))
-  "Face for lines in a diff that have been added."
-  :group 'magit-faces)
+(defcustom magit-log-infinite-length 99999
+  "Number of log used to show as maximum for `magit-log-cutoff-length'."
+  :group 'magit-log
+  :type 'integer)
 
 
-(defface magit-diff-none
-  '((t :inherit diff-context))
-  "Face for lines in a diff that are unchanged."
-  :group 'magit-faces)
+(defcustom magit-log-format-graph-function nil
+  "Function used to format graphs in log buffers.
+The function is called with one argument, the propertized graph
+of a single line in as a string.  It has to return the formatted
+string.  This option can also be nil, in which case the graph is
+inserted as is."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-log
+  :type '(choice (const :tag "insert as is" nil)
+                 (function-item magit-log-format-unicode-graph)
+                 function))
+
+(defcustom magit-log-format-unicode-graph-alist
+  '((?/ . ?╱) (?| . ?│) (?\\ . ?╲) (?* . ?◆) (?o . ?◇))
+  "Alist used by `magit-log-format-unicode-graph' to translate chars."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-log
+  :type '(repeat (cons :format "%v\n"
+                       (character :format "replace %v ")
+                       (character :format "with %v"))))
+
+(defcustom magit-log-show-gpg-status nil
+  "Display signature verification information as part of the log."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-log
+  :type 'boolean)
+
+(defcustom magit-log-show-margin t
+  "Whether to use a margin when showing `oneline' logs.
+When non-nil the author name and date are displayed in the margin
+of the log buffer if that contains a `oneline' log.  This can be
+toggled temporarily using the command `magit-log-toggle-margin'."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-log
+  :type 'boolean)
+
+(put 'magit-log-show-margin 'permanent-local t)
+
+(defcustom magit-log-margin-spec '(25 nil magit-duration-spec)
+  "How to format the margin for `oneline' logs.
+
+When the log buffer contains a `oneline' log, then it optionally
+uses the right margin to display the author name and author date.
+This is also supported in the reflog buffer.
+
+Logs that are shown together with other non-log information (e.g.
+in the status buffer) are never accompanied by a margin.  The
+same applies to `long' logs, in this case because that would be
+redundant.
+
+This option controls how that margin is formatted, the other
+option affecting this is `magit-log-show-margin'; if that is nil
+then no margin is displayed at all.  To toggle this temporarily
+use the command `magit-log-show-margin'.
+
+The value has the form (WIDTH CHARACTERP DURATION-SPEC).  The
+width of the margin is controlled using WIDTH, an integer.  When
+CHARACTERP is non-nil time units are shown as single characters,
+otherwise the full name of the unit is displayed.  DURATION-SPEC
+has to be a variable, its value controls which time units are
+used, how many seconds they contain, and what their names are."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-log
+  :type '(list (integer  :tag "Margin width")
+               (choice   :tag "Time unit style"
+                         (const :tag "Character" t)
+                         (const :tag "Word" nil))
+               (variable :tag "Duration spec variable")))
+
+(defcustom magit-duration-spec
+  `((?Y "year"   "years"   ,(round (* 60 60 24 365.2425)))
+    (?M "month"  "months"  ,(round (* 60 60 24 30.436875)))
+    (?w "week"   "weeks"   ,(* 60 60 24 7))
+    (?d "day"    "days"    ,(* 60 60 24))
+    (?h "hour"   "hours"   ,(* 60 60))
+    (?m "minute" "minutes" 60)
+    (?s "second" "seconds" 1))
+  "Units used to display durations in a human format.
+The value is a list of time units, beginning with the longest.
+Each element has the form ((CHAR UNIT UNITS SECONDS)..).  UNIT
+is the time unit, UNITS is the plural of that unit.  CHAR is a
+character that can be used as abbreviation and must be unique
+amoung all elements.  SECONDS is the number of seconds in one
+UNIT.  Also see option `magit-log-margin-spec'."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-log
+  :type '(repeat (list (character :tag "Unit character")
+                       (string    :tag "Unit singular string")
+                       (string    :tag "Unit plural string")
+                       (integer   :tag "Seconds in unit"))))
+
+(defcustom magit-ellipsis #x2026 ; "horizontal ellipsis"
+  "Character appended to abreviated text.
+Currently this is used only in the log margin, but might later
+be used elsewhere too.  Filenames that were abbreviated by Git
+are left as-is."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-log
+  :type 'character)
+
+;;;;;; Others
+
+(defcustom magit-auto-revert-mode-lighter " MRev"
+  "String to display when Magit-Auto-Revert mode is active."
+  :group 'magit-modes)
+
+(define-minor-mode magit-auto-revert-mode
+  "Toggle global Magit-Auto-Revert mode.
+With prefix ARG, enable Magit-Auto-Revert mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Magit-Auto-Revert mode is a global minor mode that, after Magit
+has run a Git command, reverts buffers associated with files that
+have changed on disk and are tracked in the current Git repository."
+  :group 'magit-modes
+  :lighter magit-auto-revert-mode-lighter
+  :global t
+  :init-value t)
+
+(defcustom magit-merge-warn-dirty-worktree t
+  "Whether to issue a warning when attempting to start a merge in a dirty worktree."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type 'boolean)
+
+(defcustom magit-push-hook '(magit-push-dwim)
+  "Hook run by `magit-push' to actually do the work.
+See `magit-push' and `magit-push-dwim' for more information."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type 'hook)
+
+(defcustom magit-set-upstream-on-push nil
+  "Whether `magit-push' may set upstream when pushing a branch.
+This only applies if the branch does not have an upstream set yet.
+
+nil        don't use --set-upstream.
+t          ask if --set-upstream should be used.
+`dontask'  always use --set-upstream.
+`refuse'   refuse to push unless a remote branch has already been set."
+  :group 'magit-modes
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Ask if not set" askifnotset)
+                 (const :tag "Refuse" refuse)
+                 (const :tag "Always" dontask)))
+
+(defcustom magit-wazzup-sections-hook
+  '(magit-insert-wazzup-head-line
+    magit-insert-empty-line
+    magit-insert-wazzup-branches)
+  "Hook run to insert sections into the wazzup buffer."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type 'hook)
+
+(defcustom magit-cherry-sections-hook
+  '(magit-insert-cherry-head-line
+    magit-insert-cherry-upstream-line
+    magit-insert-cherry-help-lines
+    magit-insert-empty-line
+    magit-insert-cherry-commits)
+  "Hook run to insert sections into the cherry buffer."
+  :package-version '(magit . "2.0.0")
+  :group 'magit-modes
+  :type 'hook)
+
+;;;; Custom Faces
+
+(defface magit-section-title
+  '((t :inherit header-line))
+  "Face for section titles."
+  :group 'magit-faces)
+
+(defface magit-branch
+  '((((class color) (background light))
+     :background "Grey85"
+     :foreground "LightSkyBlue4")
+    (((class color) (background dark))
+     :background "Grey13"
+     :foreground "LightSkyBlue1"))
+  "Face for branches."
+  :group 'magit-faces)
+
+(defface magit-tag
+  '((((class color) (background light))
+     :background "LemonChiffon1"
+     :foreground "goldenrod4")
+    (((class color) (background dark))
+     :background "LemonChiffon1"
+     :foreground "goldenrod4"))
+  "Face for tags."
+  :group 'magit-faces)
+
+(defface magit-diff-file-header
+  '((t :inherit diff-file-header))
+  "Face for diff file header lines."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-header
+  '((t :inherit diff-hunk-header))
+  "Face for diff hunk header lines."
+  :group 'magit-faces)
+
+(defface magit-diff-add
+  '((t :inherit diff-added))
+  "Face for lines in a diff that have been added."
+  :group 'magit-faces)
 
 (defface magit-diff-del
   '((t :inherit diff-removed))
   "Face for lines in a diff that have been deleted."
   :group 'magit-faces)
 
 
 (defface magit-diff-del
   '((t :inherit diff-removed))
   "Face for lines in a diff that have been deleted."
   :group 'magit-faces)
 
+(defface magit-diff-none
+  '((t :inherit diff-context))
+  "Face for lines in a diff that are unchanged."
+  :group 'magit-faces)
+
+(defface magit-diff-merge-current
+  '((t :inherit font-lock-preprocessor-face))
+  "Face for merge conflict marker 'current' line."
+  :group 'magit-faces)
+
+(defface magit-diff-merge-separator
+  '((t :inherit font-lock-preprocessor-face))
+  "Face for merge conflict marker seperator."
+  :group 'magit-faces)
+
+(defface magit-diff-merge-diff3-separator
+  '((t :inherit font-lock-preprocessor-face))
+  "Face for merge conflict marker seperator."
+  :group 'magit-faces)
+
+(defface magit-diff-merge-proposed
+  '((t :inherit font-lock-preprocessor-face))
+  "Face for merge conflict marker 'proposed' line."
+  :group 'magit-faces)
+
 (defface magit-log-graph
   '((((class color) (background light))
      :foreground "grey11")
 (defface magit-log-graph
   '((((class color) (background light))
      :foreground "grey11")
@@ -437,18 +1213,39 @@ Many Magit faces inherit from this one by default."
   "Face for the sha1 element of the log output."
   :group 'magit-faces)
 
   "Face for the sha1 element of the log output."
   :group 'magit-faces)
 
+(defface magit-log-author
+  '((((class color) (background light))
+     :foreground "firebrick")
+    (((class color) (background dark))
+     :foreground "tomato"))
+  "Face for the author element of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-date
+  '((t))
+  "Face for the date element of the log output."
+  :group 'magit-faces)
+
 (defface magit-log-message
   '((t))
   "Face for the message element of the log output."
   :group 'magit-faces)
 
 (defface magit-log-message
   '((t))
   "Face for the message element of the log output."
   :group 'magit-faces)
 
+(defface magit-cherry-unmatched
+  '((t :foreground "cyan"))
+  "Face for unmatched cherry commits.")
+
+(defface magit-cherry-equivalent
+  '((t :foreground "magenta"))
+  "Face for equivalent cherry commits.")
+
 (defface magit-item-highlight
 (defface magit-item-highlight
-  '((t :inherit highlight))
+  '((t :inherit secondary-selection))
   "Face for highlighting the current item."
   :group 'magit-faces)
 
 (defface magit-item-mark
   "Face for highlighting the current item."
   :group 'magit-faces)
 
 (defface magit-item-mark
-  '((t :inherit secondary-selection))
+  '((t :inherit highlight))
   "Face for highlighting marked item."
   :group 'magit-faces)
 
   "Face for highlighting marked item."
   :group 'magit-faces)
 
@@ -464,6 +1261,18 @@ Many Magit faces inherit from this one by default."
   "Face for good bisect refs."
   :group 'magit-faces)
 
   "Face for good bisect refs."
   :group 'magit-faces)
 
+(defface magit-log-head-label-bisect-skip
+  '((((class color) (background light))
+     :box t
+     :background "light goldenrod"
+     :foreground "dark goldenrod")
+    (((class color) (background dark))
+     :box t
+     :background "light goldenrod"
+     :foreground "dark goldenrod"))
+  "Face for skipped bisect refs."
+  :group 'magit-faces)
+
 (defface magit-log-head-label-bisect-bad
   '((((class color) (background light))
      :box t
 (defface magit-log-head-label-bisect-bad
   '((((class color) (background light))
      :box t
@@ -517,35 +1326,96 @@ Many Magit faces inherit from this one by default."
   "Face for highlighting whitespace errors in Magit diffs."
   :group 'magit-faces)
 
   "Face for highlighting whitespace errors in Magit diffs."
   :group 'magit-faces)
 
-(defvar magit-custom-options '()
-  "List of custom options to pass to Git.
-Do not customize this (used in the `magit-key-mode' implementation).")
+(defface magit-log-head-label-local
+  '((((class color) (background light))
+     :box t
+     :background "Grey85"
+     :foreground "LightSkyBlue4")
+    (((class color) (background dark))
+     :box t
+     :background "Grey13"
+     :foreground "LightSkyBlue1"))
+  "Face for local branch head labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-log-head-label-head
+  '((((class color) (background light))
+     :box t
+     :background "Grey70"
+     :foreground "Black")
+    (((class color) (background dark))
+     :box t
+     :background "Grey20"
+     :foreground "White"))
+  "Face for working branch head labels shown in log buffer."
+  :group 'magit-faces)
 
 
-(defvar magit-read-rev-history nil
-  "The history of inputs to `magit-read-rev'.")
+(defface magit-log-head-label-default
+  '((((class color) (background light))
+     :box t
+     :background "Grey50")
+    (((class color) (background dark))
+     :box t
+     :background "Grey50"))
+  "Face for unknown ref labels shown in log buffer."
+  :group 'magit-faces)
 
 
-(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).")
+(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)
+
+(defface magit-signature-good
+  '((t :foreground "green"))
+  "Face for good signatures."
+  :group 'magit-faces)
 
 
-(defvar magit-back-navigation-history nil
-  "History items that will be visited by successively going \"back\".")
-(make-variable-buffer-local 'magit-back-navigation-history)
-(put 'magit-back-navigation-history 'permanent-local t)
+(defface magit-signature-bad
+  '((t :foreground "red"))
+  "Face for bad signatures."
+  :group 'magit-faces)
 
 
-(defvar magit-forward-navigation-history nil
-  "History items that will be visited by successively going \"forward\".")
-(make-variable-buffer-local 'magit-forward-navigation-history)
-(put 'magit-forward-navigation-history 'permanent-local t)
+(defface magit-signature-untrusted
+  '((t :foreground "cyan"))
+  "Face for good untrusted signatures."
+  :group 'magit-faces)
 
 
-(defvar magit-omit-untracked-dir-contents nil
-  "When non-nil magit will only list an untracked directory, not its contents.")
+(defface magit-signature-none
+  '((t :inherit magit-log-message))
+  "Face for unsigned commits."
+  :group 'magit-faces)
 
 
-(defvar magit-tmp-buffer-name " *magit-tmp*")
 
 
-(defface magit-log-head-label-local
+(defface magit-log-reflog-label-commit
+  '((((class color) (background light))
+     :box t
+     :background "LemonChiffon1"
+     :foreground "goldenrod4")
+    (((class color) (background dark))
+     :box t
+     :background "LemonChiffon1"
+     :foreground "goldenrod4"))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-amend
+  '((t :inherit magit-log-reflog-label-commit))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-merge
+  '((t :inherit magit-log-reflog-label-commit))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-checkout
   '((((class color) (background light))
      :box t
      :background "Grey85"
   '((((class color) (background light))
      :box t
      :background "Grey85"
@@ -554,19 +1424,89 @@ operation after commit).")
      :box t
      :background "Grey13"
      :foreground "LightSkyBlue1"))
      :box t
      :background "Grey13"
      :foreground "LightSkyBlue1"))
-  "Face for local branch head labels shown in log buffer."
+  "Face for reflog subject labels shown in reflog buffer."
   :group 'magit-faces)
 
   :group 'magit-faces)
 
-(defface magit-log-head-label-default
+(defface magit-log-reflog-label-reset
+  '((((class color) (background light))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4")
+    (((class color) (background dark))
+     :box t
+     :background "IndianRed1"
+     :foreground "IndianRed4"))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-rebase
+  '((((class color) (background light))
+     :box t
+     :background "Grey85"
+     :foreground "OliveDrab4")
+    (((class color) (background dark))
+     :box t
+     :background "Grey11"
+     :foreground "DarkSeaGreen2"))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-cherry-pick
+'((((class color) (background light))
+     :box t
+     :background "light green"
+     :foreground "dark olive green")
+    (((class color) (background dark))
+     :box t
+     :background "light green"
+     :foreground "dark olive green"))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-remote
   '((((class color) (background light))
      :box t
      :background "Grey50")
     (((class color) (background dark))
      :box t
      :background "Grey50"))
   '((((class color) (background light))
      :box t
      :background "Grey50")
     (((class color) (background dark))
      :box t
      :background "Grey50"))
-  "Face for unknown ref labels shown in log buffer."
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-log-reflog-label-other
+  '((((class color) (background light))
+     :box t
+     :background "Grey50")
+    (((class color) (background dark))
+     :box t
+     :background "Grey50"))
+  "Face for reflog subject labels shown in reflog buffer."
+  :group 'magit-faces)
+
+(defface magit-process-ok
+  '((t :inherit magit-section-title
+       :foreground "green"))
+  "Face for zero exit-status."
+  :group 'magit-faces)
+
+(defface magit-process-ng
+  '((t :inherit magit-section-title
+       :foreground "red"))
+  "Face for non-zero exit-status."
   :group 'magit-faces)
 
   :group 'magit-faces)
 
+;;;; Keymaps
+
+;; Not an option to avoid advertising it.
+(defvar magit-rigid-key-bindings nil
+  "Use rigid key bindings instead of thematic key popups.
+If you enable this a lot of functionality is lost.  You most
+likely don't want that.  This variable only has an effect if
+set before loading libary `magit'.")
+
+(when (boundp 'git-commit-mode-map)
+  (define-key git-commit-mode-map (kbd "C-c C-d") 'magit-diff-staged))
+
 (defvar magit-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map t)
 (defvar magit-mode-map
   (let ((map (make-keymap)))
     (suppress-keymap map t)
@@ -591,32 +1531,54 @@ operation after commit).")
     (define-key map (kbd "M-S") 'magit-show-level-4-all)
     (define-key map (kbd "g") 'magit-refresh)
     (define-key map (kbd "G") 'magit-refresh-all)
     (define-key map (kbd "M-S") 'magit-show-level-4-all)
     (define-key map (kbd "g") 'magit-refresh)
     (define-key map (kbd "G") 'magit-refresh-all)
-    (define-key map (kbd "?") 'magit-describe-item)
-    (define-key map (kbd "!") 'magit-key-mode-popup-running)
+    (define-key map (kbd "?") 'magit-key-mode-popup-dispatch)
     (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 ":") '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 "L") 'magit-add-change-log-entry)
     (define-key map (kbd "RET") 'magit-visit-item)
     (define-key map (kbd "RET") 'magit-visit-item)
+    (define-key map (kbd "C-<return>") 'magit-dired-jump)
     (define-key map (kbd "SPC") 'magit-show-item-or-scroll-up)
     (define-key map (kbd "DEL") 'magit-show-item-or-scroll-down)
     (define-key map (kbd "C-w") 'magit-copy-item-as-kill)
     (define-key map (kbd "SPC") 'magit-show-item-or-scroll-up)
     (define-key map (kbd "DEL") 'magit-show-item-or-scroll-down)
     (define-key map (kbd "C-w") 'magit-copy-item-as-kill)
-    (define-key map (kbd "R") 'magit-rebase-step)
-    (define-key map (kbd "t") 'magit-key-mode-popup-tagging)
-    (define-key map (kbd "r") 'magit-key-mode-popup-rewriting)
-    (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)
-    (define-key map (kbd "$") 'magit-display-process)
-    (define-key map (kbd "c") 'magit-log-edit)
+    (cond (magit-rigid-key-bindings
+           (define-key map (kbd "c") 'magit-commit)
+           (define-key map (kbd "m") 'magit-merge)
+           (define-key map (kbd "b") 'magit-checkout)
+           (define-key map (kbd "M") 'magit-branch-manager)
+           (define-key map (kbd "r") 'undefined)
+           (define-key map (kbd "f") 'magit-fetch-current)
+           (define-key map (kbd "F") 'magit-pull)
+           (define-key map (kbd "J") 'magit-apply-mailbox)
+           (define-key map (kbd "!") 'magit-git-command-topdir)
+           (define-key map (kbd "P") 'magit-push)
+           (define-key map (kbd "t") 'magit-tag)
+           (define-key map (kbd "l") 'magit-log)
+           (define-key map (kbd "o") 'magit-submodule-update)
+           (define-key map (kbd "B") 'undefined)
+           (define-key map (kbd "z") 'magit-stash))
+          (t
+           (define-key map (kbd "c") 'magit-key-mode-popup-committing)
+           (define-key map (kbd "m") 'magit-key-mode-popup-merging)
+           (define-key map (kbd "b") 'magit-key-mode-popup-branching)
+           (define-key map (kbd "M") 'magit-key-mode-popup-remoting)
+           (define-key map (kbd "r") 'magit-key-mode-popup-rewriting)
+           (define-key map (kbd "f") 'magit-key-mode-popup-fetching)
+           (define-key map (kbd "F") 'magit-key-mode-popup-pulling)
+           (define-key map (kbd "J") 'magit-key-mode-popup-apply-mailbox)
+           (define-key map (kbd "!") 'magit-key-mode-popup-running)
+           (define-key map (kbd "P") 'magit-key-mode-popup-pushing)
+           (define-key map (kbd "t") 'magit-key-mode-popup-tagging)
+           (define-key map (kbd "l") 'magit-key-mode-popup-logging)
+           (define-key map (kbd "o") 'magit-key-mode-popup-submodule)
+           (define-key map (kbd "B") 'magit-key-mode-popup-bisecting)
+           (define-key map (kbd "z") 'magit-key-mode-popup-stashing)))
+    (define-key map (kbd "$") 'magit-process)
     (define-key map (kbd "E") 'magit-interactive-rebase)
     (define-key map (kbd "E") 'magit-interactive-rebase)
+    (define-key map (kbd "R") 'magit-rebase-step)
     (define-key map (kbd "e") 'magit-ediff)
     (define-key map (kbd "w") 'magit-wazzup)
     (define-key map (kbd "e") 'magit-ediff)
     (define-key map (kbd "w") 'magit-wazzup)
-    (define-key map (kbd "q") 'magit-quit-window)
-    (define-key map (kbd "m") 'magit-key-mode-popup-merging)
+    (define-key map (kbd "y") 'magit-cherry)
+    (define-key map (kbd "q") 'magit-mode-quit-window)
     (define-key map (kbd "x") 'magit-reset-head)
     (define-key map (kbd "v") 'magit-revert-item)
     (define-key map (kbd "a") 'magit-apply-item)
     (define-key map (kbd "x") 'magit-reset-head)
     (define-key map (kbd "v") 'magit-revert-item)
     (define-key map (kbd "a") 'magit-apply-item)
@@ -626,383 +1588,643 @@ operation after commit).")
     (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 "-") '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))
+    (define-key map (kbd "h") 'magit-key-mode-popup-diff-options)
+    (define-key map (kbd "H") 'magit-diff-toggle-refine-hunk)
+    (define-key map (kbd "M-g") 'magit-jump-to-diffstats)
+    (define-key map (kbd "S") 'magit-stage-all)
+    (define-key map (kbd "U") 'magit-unstage-all)
+    (define-key map (kbd "X") 'magit-reset-working-tree)
+    (define-key map (kbd "C-c C-c") 'magit-key-mode-popup-dispatch)
+    (define-key map (kbd "C-c C-e") 'magit-key-mode-popup-dispatch)
+    map)
+  "Parent keymap for all keymaps of modes derived from `magit-mode'.")
 
 (defvar magit-commit-mode-map
   (let ((map (make-sparse-keymap)))
 
 (defvar magit-commit-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c C-b") 'magit-show-commit-backward)
-    (define-key map (kbd "C-c C-f") 'magit-show-commit-forward)
-    map))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map (kbd "C-c C-b") 'magit-go-backward)
+    (define-key map (kbd "C-c C-f") 'magit-go-forward)
+    (define-key map (kbd "SPC") 'scroll-up)
+    (define-key map (kbd "DEL") 'scroll-down)
+    map)
+  "Keymap for `magit-commit-mode'.")
 
 (defvar magit-status-mode-map
   (let ((map (make-sparse-keymap)))
 
 (defvar magit-status-mode-map
   (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
     (define-key map (kbd "s") 'magit-stage-item)
     (define-key map (kbd "s") 'magit-stage-item)
-    (define-key map (kbd "S") 'magit-stage-all)
     (define-key map (kbd "u") 'magit-unstage-item)
     (define-key map (kbd "u") 'magit-unstage-item)
-    (define-key map (kbd "U") 'magit-unstage-all)
     (define-key map (kbd "i") 'magit-ignore-item)
     (define-key map (kbd "I") 'magit-ignore-item-locally)
     (define-key map (kbd "i") 'magit-ignore-item)
     (define-key map (kbd "I") 'magit-ignore-item-locally)
+    (define-key map (kbd "j") 'magit-section-jump-map)
     (define-key map (kbd ".") 'magit-mark-item)
     (define-key map (kbd "=") 'magit-diff-with-mark)
     (define-key map (kbd "k") 'magit-discard-item)
     (define-key map (kbd ".") 'magit-mark-item)
     (define-key map (kbd "=") 'magit-diff-with-mark)
     (define-key map (kbd "k") 'magit-discard-item)
-    (define-key map (kbd "C") 'magit-add-log)
-    (define-key map (kbd "X") 'magit-reset-working-tree)
-    (define-key map (kbd "z") 'magit-key-mode-popup-stashing)
-    map))
+    (define-key map (kbd "C") 'magit-commit-add-log)
+    map)
+  "Keymap for `magit-status-mode'.")
 
 (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)))
 
 (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)))
+    (set-keymap-parent map magit-mode-map)
     (define-key map (kbd ".") 'magit-mark-item)
     (define-key map (kbd "=") 'magit-diff-with-mark)
     (define-key map (kbd "e") 'magit-log-show-more-entries)
     (define-key map (kbd ".") 'magit-mark-item)
     (define-key map (kbd "=") 'magit-diff-with-mark)
     (define-key map (kbd "e") 'magit-log-show-more-entries)
-    map))
+    (define-key map (kbd "h") 'magit-log-toggle-margin)
+    map)
+  "Keymap for `magit-log-mode'.")
+
+(defvar magit-cherry-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    map)
+  "Keymap for `magit-cherry-mode'.")
+
+(defvar magit-reflog-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-log-mode-map)
+    map)
+  "Keymap for `magit-reflog-mode'.")
+
+(defvar magit-diff-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map (kbd "C-c C-b") 'magit-go-backward)
+    (define-key map (kbd "C-c C-f") 'magit-go-forward)
+    (define-key map (kbd "SPC") 'scroll-up)
+    (define-key map (kbd "DEL") 'scroll-down)
+    map)
+  "Keymap for `magit-diff-mode'.")
 
 (defvar magit-wazzup-mode-map
   (let ((map (make-sparse-keymap)))
 
 (defvar magit-wazzup-mode-map
   (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
     (define-key map (kbd ".") 'magit-mark-item)
     (define-key map (kbd "=") 'magit-diff-with-mark)
     (define-key map (kbd "i") 'magit-ignore-item)
     (define-key map (kbd ".") 'magit-mark-item)
     (define-key map (kbd "=") 'magit-diff-with-mark)
     (define-key map (kbd "i") 'magit-ignore-item)
-    map))
+    map)
+  "Keymap for `magit-wazzup-mode'.")
 
 (defvar magit-branch-manager-mode-map
   (let ((map (make-sparse-keymap)))
 
 (defvar magit-branch-manager-mode-map
   (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
     (define-key map (kbd "c") 'magit-create-branch)
     (define-key map (kbd "a") 'magit-add-remote)
     (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 "r") 'magit-rename-item)
     (define-key map (kbd "k") 'magit-discard-item)
     (define-key map (kbd "T") 'magit-change-what-branch-tracks)
     (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.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"
-            "%s\n"
-            "You are using Magit version %s.")
-           str magit-bug-report-url magit-version))
-
-(defun magit-buffer-switch (buf)
-  (if (string-match "magit" (buffer-name))
-      (switch-to-buffer buf)
-    (pop-to-buffer buf)))
-
-;;; Macros
-
-(defmacro magit-with-refresh (&rest body)
-  (declare (indent 0))
-  `(magit-refresh-wrapper (lambda () ,@body)))
-
-;;; Git features
-
-(defvar magit-have-graph 'unset)
-(defvar magit-have-decorate 'unset)
-(defvar magit-have-abbrev 'unset)
-(make-variable-buffer-local 'magit-have-graph)
-(put 'magit-have-graph 'permanent-local t)
-(make-variable-buffer-local 'magit-have-decorate)
-(put 'magit-have-decorate 'permanent-local t)
-(make-variable-buffer-local 'magit-have-abbrev)
-(put 'magit-have-abbrev 'permanent-local t)
-
-(defun magit-configure-have-graph ()
-  (if (eq magit-have-graph 'unset)
-      (let ((res (magit-git-exit-code "log" "--graph" "--max-count=0")))
-        (setq magit-have-graph (eq res 0)))))
-
-(defun magit-configure-have-decorate ()
-  (if (eq magit-have-decorate 'unset)
-      (let ((res (magit-git-exit-code "log" "--decorate=full" "--max-count=0")))
-        (setq magit-have-decorate (eq res 0)))))
-
-(defun magit-configure-have-abbrev ()
-  (if (eq magit-have-abbrev 'unset)
-      (let ((res (magit-git-exit-code "log" "--no-abbrev-commit" "--max-count=0")))
-        (setq magit-have-abbrev (eq res 0)))))
-
-;;; Compatibilities
-
-(eval-and-compile
-  (defun magit-max-args-internal (function)
-    "Returns the maximum number of arguments accepted by FUNCTION."
-    (if (symbolp function)
-        (setq function (symbol-function function)))
-    (if (subrp function)
-        (let ((max (cdr (subr-arity function))))
-          (if (eq 'many max)
-              most-positive-fixnum
-            max))
-      (if (eq 'macro (car-safe function))
-          (setq function (cdr function)))
-      (let ((arglist (if (byte-code-function-p function)
-                         (aref function 0)
-                       (second function))))
-        (if (memq '&rest arglist)
-            most-positive-fixnum
-          (length (remq '&optional arglist))))))
-
-  (if (functionp 'start-file-process)
-      (defalias 'magit-start-process 'start-file-process)
-    (defalias 'magit-start-process 'start-process))
-
-  (unless (fboundp 'string-match-p)
-    (defun string-match-p (regexp string &optional start)
-      "Same as `string-match' except this function does not
-change the match data."
-      (let ((inhibit-changing-match-data t))
-        (string-match regexp string start))))
-
-  (if (fboundp 'with-silent-modifications)
-      (defalias 'magit-with-silent-modifications 'with-silent-modifications)
-    (defmacro magit-with-silent-modifications (&rest body)
-      "Execute body without changing `buffer-modified-p'. Also, do not
-record undo information."
-      `(set-buffer-modified-p
-        (prog1 (buffer-modified-p)
-          (let ((buffer-undo-list t)
-                before-change-functions
-                after-change-functions)
-            ,@body)))))
-
-  (if (>= (magit-max-args-internal 'delete-directory) 2)
-      (defalias 'magit-delete-directory 'delete-directory)
-    (defun magit-delete-directory (directory &optional recursive)
-      "Deletes a directory named DIRECTORY.  If RECURSIVE is non-nil,
-recursively delete all of DIRECTORY's contents as well.
-
-Does not follow symlinks."
-      (if (or (file-symlink-p directory)
-              (not (file-directory-p directory)))
-          (delete-file directory)
-        (if recursive
-            ;; `directory-files-no-dot-files-regex' borrowed from Emacs 23
-            (dolist (file (directory-files directory 'full "\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))
-              (magit-delete-directory file recursive)))
-        (delete-directory directory)))))
-
-;;; Utilities
-
-(defun magit-set-variable-and-refresh (symbol value)
-  "Set SYMBOL to VALUE and call `magit-refresh-all'"
-  (set-default symbol value)
-  (magit-refresh-all))
-
-(defun magit-iswitchb-completing-read (prompt choices &optional predicate require-match
-                                              initial-input hist def)
-  "iswitchb-based completing-read almost-replacement."
-  (require 'iswitchb)
-  (let ((iswitchb-make-buflist-hook
-         (lambda ()
-           (setq iswitchb-temp-buflist (if (consp (first choices))
-                                           (mapcar #'car choices)
-                                         choices)))))
-    (iswitchb-read-buffer prompt (or initial-input def) require-match)))
-
-(defun magit-ido-completing-read (prompt choices &optional predicate require-match initial-input hist def)
-  "ido-based completing-read almost-replacement."
-  (require 'ido)
-  (let ((selected (ido-completing-read prompt (if (consp (first choices))
-                                                  (mapcar #'car choices)
-                                                choices)
-                                       predicate require-match initial-input hist def)))
-    (if (consp (first choices))
-        (or (cdr (assoc selected choices))
-            selected)
-      selected)))
-
-(defun magit-builtin-completing-read (prompt choices &optional predicate require-match
-                                             initial-input hist def)
-  "Magit wrapper for standard `completing-read' function."
-  (completing-read (if (and def (> (length prompt) 2)
-                            (string-equal ": " (substring prompt -2)))
-                       (format "%s (default %s): " (substring prompt 0 -2) def)
-                     prompt)
-                   choices predicate require-match initial-input hist def))
-
-(defun magit-completing-read (prompt choices &optional predicate require-match
-                                     initial-input hist def)
-  (funcall magit-completing-read-function prompt choices predicate require-match
-           initial-input hist def))
-
-(defun magit-use-region-p ()
-  (if (fboundp 'use-region-p)
-      (use-region-p)
-    (and transient-mark-mode mark-active)))
-
-(defun magit-goto-line (line)
-  "Like `goto-line' but doesn't set the mark."
-  (save-restriction
-    (widen)
-    (goto-char 1)
-    (forward-line (1- line))))
-
-(defun magit-trim-line (str)
-  (if (string= str "")
-      nil
-    (if (equal (elt str (- (length str) 1)) ?\n)
-        (substring str 0 (- (length str) 1))
-      str)))
-
-(defun magit-split-lines (str)
-  (if (string= str "")
-      nil
-    (let ((lines (nreverse (split-string str "\n"))))
-      (if (string= (car lines) "")
-          (setq lines (cdr lines)))
-      (nreverse lines))))
-
-(defun magit-git-insert (args)
-  (insert (magit-git-output args)))
-
-(defun magit-git-output (args)
-  (magit-cmd-output magit-git-executable (append magit-git-standard-options args)))
-
-(defun magit-cmd-insert (cmd args)
-  (insert (magit-cmd-output cmd args)))
-
-(defun magit-cmd-output (cmd args)
-  (let ((cmd-output (with-output-to-string
-                      (with-current-buffer standard-output
-                        (apply #'process-file
-                               cmd
-                               nil (list t nil) nil
-                               args)))))
-    (replace-regexp-in-string "\e\\[.*?m" "" cmd-output)))
-
-(defun magit-git-string (&rest args)
-  (magit-trim-line (magit-git-output args)))
-
-(defun magit-git-lines (&rest args)
-  (magit-split-lines (magit-git-output args)))
-
-(defun magit-git-exit-code (&rest args)
-  (apply #'process-file magit-git-executable nil nil nil
-         (append magit-git-standard-options args)))
-
-(defun magit-file-lines (file)
-  (when (file-exists-p file)
-    (with-temp-buffer
-      (insert-file-contents file)
-      (let ((rev (nreverse (split-string (buffer-string) "\n"))))
-        (nreverse (if (equal (car rev) "")
-                      (cdr rev)
-                    rev))))))
-
-(defun magit-write-file-lines (file lines)
-  (with-temp-buffer
-    (dolist (l lines)
-      (insert l "\n"))
-    (write-file file)))
-
-(defun magit-get (&rest keys)
-  "Return the value of Git config entry specified by KEYS."
-  (magit-git-string "config" (mapconcat 'identity keys ".")))
-
-(defun magit-get-all (&rest keys)
-  "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"))
+    map)
+  "Keymap for `magit-branch-manager-mode'.")
 
 
-(defun magit-set (val &rest keys)
-  "Set Git config settings specified by KEYS to VAL."
-  (if val
-      (magit-git-string "config" (mapconcat 'identity keys ".") val)
-    (magit-git-string "config" "--unset" (mapconcat 'identity keys "."))))
+(defvar magit-process-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    map)
+  "Keymap for `magit-process-mode'.")
 
 
-(defun magit-remove-conflicts (alist)
-  (let ((dict (make-hash-table :test 'equal))
-        (result nil))
-    (dolist (a alist)
-      (puthash (car a) (cons (cdr a) (gethash (car a) dict))
-               dict))
-    (maphash (lambda (key value)
-               (if (= (length value) 1)
-                   (push (cons key (car value)) result)
-                 (let ((sub (magit-remove-conflicts
-                             (mapcar (lambda (entry)
-                                       (let ((dir (directory-file-name
-                                                   (substring entry 0 (- (length key))))))
-                                         (cons (concat (file-name-nondirectory dir) "/" key)
-                                               entry)))
-                                     value))))
-                   (setq result (append result sub)))))
-             dict)
-    result))
+(defvar magit-section-jump-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "z") 'magit-jump-to-stashes)
+    (define-key map (kbd "n") 'magit-jump-to-untracked)
+    (define-key map (kbd "u") 'magit-jump-to-unstaged)
+    (define-key map (kbd "s") 'magit-jump-to-staged)
+    (define-key map (kbd "f") 'magit-jump-to-unpulled)
+    (define-key map (kbd "p") 'magit-jump-to-unpushed)
+    (define-key map (kbd "r") 'magit-jump-to-pending)
+    map)
+  "Submap for jumping to sections in `magit-status-mode'.")
+(fset 'magit-section-jump-map magit-section-jump-map)
 
 
-(defun magit-git-repo-p (dir)
-  (file-exists-p (expand-file-name ".git" dir)))
+(easy-menu-define magit-mode-menu magit-mode-map
+  "Magit menu"
+  '("Magit"
+    ["Refresh" magit-refresh t]
+    ["Refresh all" magit-refresh-all t]
+    "---"
+    ["Stage" magit-stage-item t]
+    ["Stage all" magit-stage-all t]
+    ["Unstage" magit-unstage-item t]
+    ["Unstage all" magit-unstage-all t]
+    ["Commit" magit-key-mode-popup-committing t]
+    ["Add log entry" magit-commit-add-log t]
+    ["Tag" magit-tag t]
+    "---"
+    ["Diff working tree" magit-diff-working-tree t]
+    ["Diff" magit-diff t]
+    ("Log"
+     ["Short Log" magit-log t]
+     ["Long Log" magit-log-long t]
+     ["Reflog" magit-reflog t]
+     ["Extended..." magit-key-mode-popup-logging t])
+    "---"
+    ["Cherry pick" magit-cherry-pick-item t]
+    ["Apply" magit-apply-item t]
+    ["Revert" magit-revert-item t]
+    "---"
+    ["Ignore" magit-ignore-item t]
+    ["Ignore locally" magit-ignore-item-locally t]
+    ["Discard" magit-discard-item t]
+    ["Reset head" magit-reset-head t]
+    ["Reset working tree" magit-reset-working-tree t]
+    ["Stash" magit-stash t]
+    ["Snapshot" magit-stash-snapshot t]
+    "---"
+    ["Branch..." magit-checkout t]
+    ["Merge" magit-merge t]
+    ["Interactive resolve" magit-interactive-resolve t]
+    ["Rebase" magit-rebase-step t]
+    ("Rewrite"
+     ["Start" magit-rewrite-start t]
+     ["Stop" magit-rewrite-stop t]
+     ["Finish" magit-rewrite-finish t]
+     ["Abort" magit-rewrite-abort t]
+     ["Set used" magit-rewrite-set-used t]
+     ["Set unused" magit-rewrite-set-unused t])
+    "---"
+    ["Push" magit-push t]
+    ["Pull" magit-pull t]
+    ["Remote update" magit-remote-update t]
+    ("Submodule"
+     ["Submodule update" magit-submodule-update t]
+     ["Submodule update and init" magit-submodule-update-init t]
+     ["Submodule init" magit-submodule-init t]
+     ["Submodule sync" magit-submodule-sync t])
+    "---"
+    ("Extensions")
+    "---"
+    ["Display Git output" magit-process t]
+    ["Quit Magit" magit-mode-quit-window t]))
 
 
-(defun magit-git-dir ()
-  "Returns the .git directory for the current repository."
-  (concat (expand-file-name (magit-git-string "rev-parse" "--git-dir")) "/"))
+\f
+;;; Utilities (1)
+;;;; Minibuffer Input
 
 
-(defun magit-no-commit-p ()
-  "Return non-nil if there is no commit in the current git repository."
-  (not (magit-git-string
-        "rev-list" "HEAD" "--max-count=1")))
+(defun magit-iswitchb-completing-read
+  (prompt choices &optional predicate require-match initial-input hist def)
+  "iswitchb-based completing-read almost-replacement."
+  (require 'iswitchb)
+  (let ((iswitchb-make-buflist-hook
+         (lambda ()
+           (setq iswitchb-temp-buflist (if (consp (car choices))
+                                           (mapcar #'car choices)
+                                         choices)))))
+    (iswitchb-read-buffer prompt (or initial-input def) require-match)))
 
 
-(defun magit-list-repos* (dir level)
-  (if (magit-git-repo-p dir)
-      (list dir)
-    (apply #'append
-           (mapcar (lambda (entry)
-                     (unless (or (string= (substring entry -3) "/..")
-                                 (string= (substring entry -2) "/."))
-                       (magit-list-repos* entry (+ level 1))))
-                   (and (file-directory-p dir)
-                        (< level magit-repo-dirs-depth)
-                        (directory-files dir t nil t))))))
+(defun magit-ido-completing-read
+  (prompt choices &optional predicate require-match initial-input hist def)
+  "ido-based completing-read almost-replacement."
+  (require 'ido)
+  (let ((reply (ido-completing-read
+                prompt
+                (if (consp (car choices))
+                    (mapcar #'car choices)
+                  choices)
+                predicate require-match initial-input hist def)))
+    (or (and (consp (car choices))
+             (cdr (assoc reply choices)))
+        reply)))
+
+(defun magit-builtin-completing-read
+  (prompt choices &optional predicate require-match initial-input hist def)
+  "Magit wrapper for standard `completing-read' function."
+  (let ((reply (completing-read
+                (if (and def (> (length prompt) 2)
+                         (string-equal ": " (substring prompt -2)))
+                    (format "%s (default %s): " (substring prompt 0 -2) def)
+                  prompt)
+                choices predicate require-match initial-input hist def)))
+    (if (string= reply "")
+        (if require-match
+            (user-error "Nothing selected")
+          nil)
+      reply)))
+
+(defun magit-completing-read
+  (prompt collection &optional predicate require-match initial-input hist def)
+  "Call function in `magit-completing-read-function' to read user input.
+
+Read `completing-read' documentation for the meaning of the argument."
+  (funcall magit-completing-read-function
+           (concat prompt ": ") collection predicate
+           require-match initial-input hist def))
+
+(defvar magit-gpg-secret-key-hist nil)
+
+(defun magit-read-gpg-secret-key (prompt)
+  (let ((keys (mapcar
+               (lambda (key)
+                 (list (epg-sub-key-id (car (epg-key-sub-key-list key)))
+                       (let ((id-obj (car (epg-key-user-id-list key)))
+                             (id-str nil))
+                         (when id-obj
+                           (setq id-str (epg-user-id-string id-obj))
+                           (if (stringp id-str)
+                               id-str
+                             (epg-decode-dn id-obj))))))
+               (epg-list-keys (epg-make-context epa-protocol) nil t))))
+    (magit-completing-read prompt keys nil t nil 'magit-gpg-secret-key-hist
+                           (car (or magit-gpg-secret-key-hist keys)))))
+
+;;;; Various Utilities
+
+(defmacro magit-bind-match-strings (varlist &rest body)
+  (declare (indent 1))
+  (let ((i 0))
+    `(let ,(mapcar (lambda (var)
+                     (list var (list 'match-string (cl-incf i))))
+                   varlist)
+       ,@body)))
+
+(defun magit-file-line (file)
+  "Return the first line of FILE as a string."
+  (when (file-regular-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-substring-no-properties (point-min)
+                                      (line-end-position)))))
 
 
-(defun magit-list-repos (dirs)
-  (magit-remove-conflicts
-   (apply #'append
-          (mapcar (lambda (dir)
-                    (mapcar #'(lambda (repo)
-                                (cons (file-name-nondirectory repo)
-                                      repo))
-                            (magit-list-repos* dir 0)))
-                  dirs))))
-
-(defun magit-get-top-dir (cwd)
-  (let ((cwd (expand-file-name (file-truename cwd))))
-    (when (file-directory-p cwd)
-      (let* ((default-directory (file-name-as-directory cwd))
-             (cdup (magit-git-string "rev-parse" "--show-cdup")))
-        (when cdup
-          (file-name-as-directory (expand-file-name cdup cwd)))))))
+(defun magit-file-lines (file &optional keep-empty-lines)
+  "Return a list of strings containing one element per line in FILE.
+Unless optional argument KEEP-EMPTY-LINES is t, trim all empty lines."
+  (when (file-regular-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (split-string (buffer-string) "\n" (not keep-empty-lines)))))
+
+(defvar-local magit-file-name ()
+  "Name of file the buffer shows a different version of.")
+
+(defun magit-buffer-file-name (&optional relative)
+  (let* ((topdir (magit-get-top-dir))
+         (filename (or buffer-file-name
+                       (when (buffer-base-buffer)
+                         (with-current-buffer (buffer-base-buffer)
+                           buffer-file-name))
+                       (when magit-file-name
+                         (expand-file-name magit-file-name topdir)))))
+    (when filename
+      (setq filename (file-truename filename))
+      (if relative
+          (file-relative-name filename topdir)
+        filename))))
+
+(defun magit-format-duration (duration spec width)
+  (cl-destructuring-bind (char unit units weight)
+      (car spec)
+    (let ((cnt (round (/ duration weight 1.0))))
+      (if (or (not (cdr spec))
+              (>= (/ duration weight) 1))
+          (if (= width 1)
+              (format "%3i%c" cnt char)
+            (format (format "%%3i %%-%is" width) cnt
+                    (if (= cnt 1) unit units)))
+        (magit-format-duration duration (cdr spec) width)))))
+
+(defun magit-flatten-onelevel (list)
+  (cl-mapcan (lambda (elt)
+               (cond ((consp elt) (copy-sequence elt))
+                     (elt (list elt))))
+             list))
+
+(defun magit-insert (string face &rest args)
+  (if magit-use-overlays
+      (let ((start (point)))
+        (insert string)
+        (let ((ov (make-overlay start (point) nil t)))
+          (overlay-put ov 'face face)
+          ;; (overlay-put ov 'priority 10)
+          (overlay-put ov 'evaporate t)))
+    (insert (propertize string 'face face)))
+  (apply #'insert args))
+
+(defun magit-put-face-property (start end face)
+  (if magit-use-overlays
+      (let ((ov (make-overlay start end nil t)))
+        (overlay-put ov 'face face)
+        ;; (overlay-put ov 'priority 10)
+        (overlay-put ov 'evaporate t))
+    (put-text-property start end 'face face)))
+
+;;;; Buffer Margins
+
+(defun magit-set-buffer-margin (width enable)
+  (let ((window (get-buffer-window)))
+    (when window
+      (with-selected-window window
+        (set-window-margins nil (car (window-margins)) (if enable width 0))
+        (let ((fn (apply-partially
+                   (lambda (width)
+                     (let ((window (get-buffer-window)))
+                       (when window
+                         (with-selected-window window
+                           (set-window-margins nil (car (window-margins))
+                                               width)))))
+                   width)))
+          (if enable
+              (add-hook  'window-configuration-change-hook fn nil t)
+            (remove-hook 'window-configuration-change-hook fn t)))))))
+
+(defun magit-make-margin-overlay (&rest strings)
+  (let ((o (make-overlay (point) (line-end-position) nil t)))
+    (overlay-put o 'evaporate t)
+    (overlay-put o 'before-string
+                 (propertize "o" 'display
+                             (list '(margin right-margin)
+                                   (apply #'concat strings))))))
+
+(defvar-local magit-log-margin-timeunit-width nil)
+
+(defun magit-log-margin-set-timeunit-width ()
+  (cl-destructuring-bind (width characterp duration-spec)
+      magit-log-margin-spec
+    (setq magit-log-margin-timeunit-width
+          (if characterp
+              1
+            (apply 'max (mapcar (lambda (e)
+                                  (max (length (nth 1 e))
+                                       (length (nth 2 e))))
+                                (symbol-value duration-spec)))))))
+
+;;;; Emacsclient Support
+
+(defmacro magit-with-emacsclient (server-window &rest body)
+  "Arrange for Git to use Emacsclient as \"the git editor\".
+
+Git processes that use \"the editor\" have to be asynchronous.
+The use of this macro ensures that such processes inside BODY use
+Emacsclient as \"the editor\" by setting the environment variable
+$GIT_EDITOR accordingly around calls to Git and starting the
+server if necessary."
+  (declare (indent 1))
+  `(let* ((process-environment process-environment)
+          (magit-process-popup-time -1))
+     ;; Make sure the client is usable.
+     (magit-assert-emacsclient "use `magit-with-emacsclient'")
+     ;; Make sure server-use-tcp's value is valid.
+     (unless (featurep 'make-network-process '(:family local))
+       (setq server-use-tcp t))
+     ;; Make sure the server is running.
+     (unless server-process
+       (when (server-running-p server-name)
+         (setq server-name (format "server%s" (emacs-pid)))
+         (when (server-running-p server-name)
+           (server-force-delete server-name)))
+       (server-start))
+     ;; Tell Git to use the client.
+     (setenv "GIT_EDITOR"
+             (concat magit-emacsclient-executable
+     ;; Tell the client where the server file is.
+                     (and (not server-use-tcp)
+                          (concat " --socket-name="
+                                  (expand-file-name server-name
+                                                    server-socket-dir)))))
+     (when server-use-tcp
+       (setenv "EMACS_SERVER_FILE"
+               (expand-file-name server-name server-auth-dir)))
+     ;; As last resort fallback to a new Emacs instance.
+     (setenv "ALTERNATE_EDITOR"
+             (expand-file-name invocation-name invocation-directory))
+     ;; Git has to be called asynchronously in BODY or we create a
+     ;; dead lock.  By the time Emacsclient is called the dynamic
+     ;; binding is no longer in effect and our primitives don't
+     ;; support callbacks.  Temporarily set the default value and
+     ;; restore the old value using a timer.
+     (let ((window ,server-window))
+       (unless (equal window server-window)
+         (run-at-time "1 sec" nil
+                      (apply-partially (lambda (value)
+                                         (setq server-window value))
+                                       server-window))
+         (setq-default server-window window)))
+     ,@body))
+
+(defun magit-use-emacsclient-p ()
+  (and magit-emacsclient-executable
+       (not (tramp-tramp-file-p default-directory))))
+
+(defun magit-assert-emacsclient (action)
+  (unless magit-emacsclient-executable
+    (user-error "Cannot %s when `magit-emacsclient-executable' is nil" action))
+  (when (tramp-tramp-file-p default-directory)
+    (user-error "Cannot %s when accessing repository using tramp" action)))
+
+;;;; Git Config
+
+(defun magit-get (&rest keys)
+  "Return the value of Git config entry specified by KEYS."
+  (magit-git-string "config" (mapconcat 'identity keys ".")))
+
+(defun magit-get-all (&rest keys)
+  "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."
+  (magit-git-true "config" "--bool" (mapconcat 'identity keys ".")))
+
+(defun magit-set (val &rest keys)
+  "Set Git config settings specified by KEYS to VAL."
+  (if val
+      (magit-git-string "config" (mapconcat 'identity keys ".") val)
+    (magit-git-string "config" "--unset" (mapconcat 'identity keys "."))))
+
+;;;; Git Low-Level
+
+(defun magit-git-repo-p (dir)
+  (file-exists-p (expand-file-name ".git" dir)))
+
+(defun magit-git-dir (&optional path)
+  "Return absolute path to the GIT_DIR for the current repository.
+If optional PATH is non-nil it has to be a path relative to the
+GIT_DIR and its absolute path is returned"
+  (let ((gitdir (magit-git-string "rev-parse" "--git-dir")))
+    (when gitdir
+      (setq gitdir (file-name-as-directory
+                    (magit-expand-git-file-name gitdir)))
+      (if path
+          (expand-file-name (convert-standard-filename path) gitdir)
+        gitdir))))
+
+(defun magit-no-commit-p ()
+  "Return non-nil if there is no commit in the current git repository."
+  (not (magit-git-string "rev-list" "-1" "HEAD")))
+
+(defun magit-get-top-dir (&optional directory)
+  "Return the top directory for the current repository.
+
+Determine the repository which contains `default-directory' in
+either its work tree or git control directory and return its top
+directory.  If there is no top directory, because the repository
+is bare, return the control directory instead.
+
+If optional DIRECTORY is non-nil then return the top directory of
+the repository that contains that instead.  DIRECTORY has to be
+an existing directory."
+  (setq directory (if directory
+                      (file-name-as-directory
+                       (expand-file-name directory))
+                    default-directory))
+  (unless (file-directory-p directory)
+    (error "%s isn't an existing directory" directory))
+  (let* ((default-directory directory)
+         (top (magit-git-string "rev-parse" "--show-toplevel")))
+    (if top
+        (file-name-as-directory (magit-expand-git-file-name top))
+      (let ((gitdir (magit-git-dir)))
+        (when gitdir
+          (if (magit-bare-repo-p)
+              gitdir
+            (file-name-directory (directory-file-name gitdir))))))))
+
+(defun magit-expand-git-file-name (filename)
+  (when (tramp-tramp-file-p default-directory)
+    (setq filename (file-relative-name filename
+                                       (with-parsed-tramp-file-name
+                                           default-directory nil
+                                         localname))))
+  (expand-file-name filename))
+
+(defun magit-file-relative-name (file)
+  "Return the path of FILE relative to the repository root.
+If FILE isn't inside a Git repository then return nil."
+  (setq file (file-truename file))
+  (let ((topdir (magit-get-top-dir (file-name-directory file))))
+    (and topdir (substring file (length topdir)))))
+
+(defun magit-bare-repo-p ()
+  "Return t if the current repository is bare."
+  (magit-git-true "rev-parse" "--is-bare-repository"))
 
 (defun magit-get-ref (ref)
   (magit-git-string "symbolic-ref" "-q" ref))
 
 (defun magit-get-current-branch ()
 
 (defun magit-get-ref (ref)
   (magit-git-string "symbolic-ref" "-q" ref))
 
 (defun magit-get-current-branch ()
-  (let* ((head (magit-get-ref "HEAD"))
-         (pos (and head (string-match "^refs/heads/" head))))
-    (if pos
-        (substring head 11)
-      nil)))
+  (let ((head (magit-get-ref "HEAD")))
+    (when (and head (string-match "^refs/heads/" head))
+      (substring head 11))))
+
+(defun magit-get-remote/branch (&optional branch verify)
+  "Return the remote-tracking branch of BRANCH used for pulling.
+Return a string of the form \"REMOTE/BRANCH\".
+
+If optional BRANCH is nil return the remote-tracking branch of
+the current branch.  If optional VERIFY is non-nil verify that
+the remote branch exists; else return nil."
+  (save-match-data
+    (let (remote remote-branch remote/branch)
+      (and (or branch (setq branch (magit-get-current-branch)))
+           (setq remote (magit-get "branch" branch "remote"))
+           (setq remote-branch (magit-get "branch" branch "merge"))
+           (string-match "^refs/heads/\\(.+\\)" remote-branch)
+           (setq remote/branch
+                 (concat remote "/" (match-string 1 remote-branch)))
+           (or (not verify)
+               (magit-git-success "rev-parse" "--verify" remote/branch))
+           remote/branch))))
+
+(defun magit-get-tracked-branch (&optional branch qualified pretty)
+  "Return the name of the tracking branch the local branch name BRANCH.
+
+If optional QUALIFIED is non-nil return the full branch path,
+otherwise try to shorten it to a name (which may fail).  If
+optional PRETTY is non-nil additionally format the branch name
+according to option `magit-remote-ref-format'."
+  (unless branch
+    (setq branch (magit-get-current-branch)))
+  (when branch
+    (let ((remote (magit-get "branch" branch "remote"))
+          (merge  (magit-get "branch" branch "merge")))
+      (when (and (not merge)
+                 (not (equal remote ".")))
+        (setq merge branch))
+      (when (and remote merge)
+        (if (string= remote ".")
+            (cond (qualified merge)
+                  ((string-match "^refs/heads/" merge)
+                   (substring merge 11))
+                  ((string-match "^refs/" merge)
+                   merge))
+          (let* ((fetch (mapcar (lambda (f) (split-string f "[+:]" t))
+                                (magit-get-all "remote" remote "fetch")))
+                 (match (cadr (assoc merge fetch))))
+            (unless match
+              (let* ((prefix (nreverse (split-string merge "/")))
+                     (unique (list (car prefix))))
+                (setq prefix (cdr prefix))
+                (setq fetch
+                      (cl-mapcan
+                       (lambda (f)
+                         (cl-destructuring-bind (from to) f
+                           (setq from (nreverse (split-string from "/")))
+                           (when (equal (car from) "*")
+                             (list (list (cdr from) to)))))
+                       fetch))
+                (while (and prefix (not match))
+                  (if (setq match (cadr (assoc prefix fetch)))
+                      (setq match (concat (substring match 0 -1)
+                                          (mapconcat 'identity unique "/")))
+                    (push (car prefix) unique)
+                    (setq prefix (cdr prefix))))))
+            (cond ((not match) nil)
+                  (qualified match)
+                  ((string-match "^refs/remotes/" match)
+                   (if pretty
+                       (magit-format-ref match)
+                     (substring match 13)))
+                  (t match))))))))
+
+(defun magit-get-previous-branch ()
+  "Return the refname of the previously checked out branch.
+Return nil if the previously checked out branch no longer exists."
+  (magit-name-rev (magit-git-string "rev-parse" "--verify" "@{-1}")))
+
+(defun magit-get-current-tag (&optional with-distance-p)
+  "Return the closest tag reachable from \"HEAD\".
+
+If optional WITH-DISTANCE-P is non-nil then return (TAG COMMITS),
+if it is `dirty' return (TAG COMMIT DIRTY). COMMITS is the number
+of commits in \"HEAD\" but not in TAG and DIRTY is t if there are
+uncommitted changes, nil otherwise."
+  (let ((tag (magit-git-string "describe" "--long" "--tags"
+                               (and (eq with-distance-p 'dirty) "--dirty"))))
+    (save-match-data
+      (when tag
+        (string-match
+         "\\(.+\\)-\\(?:0[0-9]*\\|\\([0-9]+\\)\\)-g[0-9a-z]+\\(-dirty\\)?$" tag)
+        (if with-distance-p
+            (list (match-string 1 tag)
+                  (string-to-number (or (match-string 2 tag) "0"))
+                  (and (match-string 3 tag) t))
+          (match-string 1 tag))))))
+
+(defun magit-get-next-tag (&optional with-distance-p)
+  "Return the closest tag from which \"HEAD\" is reachable.
+
+If no such tag can be found or if the distance is 0 (in which
+case it is the current tag, not the next) return nil instead.
+
+If optional WITH-DISTANCE-P is non-nil then return (TAG COMMITS)
+where COMMITS is the number of commits in TAG but not in \"HEAD\"."
+  (let ((rev (magit-git-string "describe" "--contains" "HEAD")))
+    (save-match-data
+      (when (and rev (string-match "^[^^~]+" rev))
+        (let ((tag (match-string 0 rev)))
+          (unless (equal tag (magit-get-current-tag))
+            (if with-distance-p
+                (list tag (car (magit-rev-diff-count tag "HEAD")))
+              tag)))))))
 
 (defun magit-get-remote (branch)
   "Return the name of the remote for BRANCH.
 If branch is nil or it has no remote, but a remote named
 
 (defun magit-get-remote (branch)
   "Return the name of the remote for BRANCH.
 If branch is nil or it has no remote, but a remote named
-\"origin\" exists, return that. Otherwise, return nil."
+\"origin\" exists, return that.  Otherwise, return nil."
   (let ((remote (or (and branch (magit-get "branch" branch "remote"))
                     (and (magit-get "remote" "origin" "url") "origin"))))
   (let ((remote (or (and branch (magit-get "branch" branch "remote"))
                     (and (magit-get "remote" "origin" "url") "origin"))))
-    (if (string= remote "") nil remote)))
+    (unless (string= remote "")
+      remote)))
 
 (defun magit-get-current-remote ()
   "Return the name of the remote for the current branch.
 
 (defun magit-get-current-remote ()
   "Return the name of the remote for the current branch.
@@ -1012,25 +2234,7 @@ Otherwise, return nil."
   (magit-get-remote (magit-get-current-branch)))
 
 (defun magit-ref-exists-p (ref)
   (magit-get-remote (magit-get-current-branch)))
 
 (defun magit-ref-exists-p (ref)
-  (= (magit-git-exit-code "show-ref" "--verify" ref) 0))
-
-(defun magit-read-top-dir (dir)
-  "Ask the user for a Git repository.  The choices offered by
-auto-completion will be the repositories under `magit-repo-dirs'.
-If `magit-repo-dirs' is nil or DIR is non-nill, then
-autocompletion will offer directory names."
-  (if (and (not dir) magit-repo-dirs)
-      (let* ((repos (magit-list-repos magit-repo-dirs))
-             (reply (magit-completing-read "Git repository: " repos)))
-        (file-name-as-directory
-         (or (cdr (assoc reply repos))
-             (if (file-directory-p reply)
-                 (expand-file-name reply)
-               (error "Not a repository or a directory: %s" reply)))))
-    (file-name-as-directory
-     (read-directory-name "Git repository: "
-                          (or (magit-get-top-dir default-directory)
-                              default-directory)))))
+  (magit-git-success "show-ref" "--verify" ref))
 
 (defun magit-rev-parse (ref)
   "Return the SHA hash for REF."
 
 (defun magit-rev-parse (ref)
   "Return the SHA hash for REF."
@@ -1038,15 +2242,26 @@ autocompletion will offer directory names."
 
 (defun magit-ref-ambiguous-p (ref)
   "Return whether or not REF is ambiguous."
 
 (defun magit-ref-ambiguous-p (ref)
   "Return whether or not REF is ambiguous."
-  ;; If REF is ambiguous, rev-parse just prints errors,
-  ;; so magit-git-string returns nil.
+  ;; An ambiguous ref does not cause `git rev-parse --abbrev-ref'
+  ;; to exits with a non-zero status.  But there is nothing on
+  ;; stdout in that case.
   (not (magit-git-string "rev-parse" "--abbrev-ref" ref)))
 
   (not (magit-git-string "rev-parse" "--abbrev-ref" ref)))
 
+(defun magit-rev-diff-count (a b)
+  "Return the commits in A but not B and vice versa.
+Return a list of two integers: (A>B B>A)."
+  (mapcar 'string-to-number
+          (split-string (magit-git-string "rev-list"
+                                          "--count" "--left-right"
+                                          (concat a "..." b))
+                        "\t")))
+
 (defun magit-name-rev (rev &optional no-trim)
   "Return a human-readable name for 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 (unless optional arg NO-TRIM is
-non-nil).  In addition, it will filter out revs involving HEAD."
+Unlike `git name-rev', this will remove \"tags/\" and \"remotes/\"
+prefixes 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,
   (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,
@@ -1070,351 +2285,341 @@ non-nil).  In addition, it will filter out revs involving HEAD."
             (setq rev plain-name))))
       rev)))
 
             (setq rev plain-name))))
       rev)))
 
-(defun magit-highlight-line-whitespace ()
-  (when (and magit-highlight-whitespace
-             (or (derived-mode-p 'magit-status-mode)
-                 (not (eq magit-highlight-whitespace 'status))))
-    (if (and magit-highlight-trailing-whitespace
-             (looking-at "^[-+].*?\\([ \t]+\\)$"))
-        (overlay-put (make-overlay (match-beginning 1) (match-end 1))
-                     'face 'magit-whitespace-warning-face))
-    (if (or (and (eq magit-current-indentation 'tabs)
-                 (looking-at "^[-+]\\( *\t[ \t]*\\)"))
-            (and (integerp magit-current-indentation)
-                 (looking-at (format "^[-+]\\([ \t]* \\{%s,\\}[ \t]*\\)"
-                                     magit-current-indentation))))
-        (overlay-put (make-overlay (match-beginning 1) (match-end 1))
-                     'face 'magit-whitespace-warning-face))))
-
-(defun magit-put-line-property (prop val)
-  (put-text-property (line-beginning-position) (line-beginning-position 2)
-                     prop val))
-
-(defun magit-format-commit (commit format)
-  (magit-git-string "log" "--max-count=1"
-                    (concat "--pretty=format:" format)
-                    commit))
-
-(defun magit-current-line ()
-  (buffer-substring-no-properties (line-beginning-position)
-                                  (line-end-position)))
-
-(defun magit-insert-region (beg end buf)
-  (let ((text (buffer-substring-no-properties beg end)))
-    (with-current-buffer buf
-      (insert text))))
-
-(defun magit-insert-current-line (buf)
-  (let ((text (buffer-substring-no-properties
-               (line-beginning-position) (line-beginning-position 2))))
-    (with-current-buffer buf
-      (insert text))))
-
 (defun magit-file-uptodate-p (file)
 (defun magit-file-uptodate-p (file)
-  (eq (magit-git-exit-code "diff" "--quiet" "--" file) 0))
+  (magit-git-success "diff" "--quiet" "--" file))
 
 (defun magit-anything-staged-p ()
 
 (defun magit-anything-staged-p ()
-  (not (eq (magit-git-exit-code "diff" "--quiet" "--cached") 0)))
+  (magit-git-failure "diff" "--quiet" "--cached"))
 
 
-(defun magit-everything-clean-p ()
-  (and (not (magit-anything-staged-p))
-       (eq (magit-git-exit-code "diff" "--quiet") 0)))
+(defun magit-anything-unstaged-p ()
+  (magit-git-failure "diff" "--quiet"))
+
+(defun magit-anything-modified-p ()
+  (or (magit-anything-staged-p)
+      (magit-anything-unstaged-p)))
 
 (defun magit-commit-parents (commit)
   (cdr (split-string (magit-git-string "rev-list" "-1" "--parents" commit))))
 
 
 (defun magit-commit-parents (commit)
   (cdr (split-string (magit-git-string "rev-list" "-1" "--parents" commit))))
 
-;; XXX - let the user choose the parent
-
-(defun magit-choose-parent-id (commit op)
-  (let* ((parents (magit-commit-parents commit)))
-    (if (> (length parents) 1)
-        (error "Can't %s merge commits" op)
-      nil)))
-
-;;; Revisions and ranges
-
-(defvar magit-current-range nil
-  "The range described by the current buffer.
-This is only non-nil in diff and log buffers.
-
-This has three possible (non-nil) forms.  If it's a string REF or
-a singleton list (REF), then the range is from REF to the current
-working directory state (or HEAD in a log buffer).  If it's a
-pair (START . END), then the range is START..END.")
-(make-variable-buffer-local 'magit-current-range)
-
-(defun magit-list-interesting-refs (&optional uninteresting)
-  "Return interesting references as given by `git show-ref'.
-Removes references matching UNINTERESTING from the
-results. UNINTERESTING can be either a function taking a single
-argument or a list of strings used as regexps."
-  (let ((refs ()))
-    (dolist (line (magit-git-lines "show-ref"))
-      (if (string-match "[^ ]+ +\\(.*\\)" line)
-          (let ((ref (match-string 1 line)))
-            (cond ((and (functionp uninteresting)
-                        (funcall uninteresting ref)))
-                  ((and (not (functionp uninteresting))
-                        (loop for i in uninteresting thereis (string-match i ref))))
-                  (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-assert-one-parent (commit command)
+  (when (> (length (magit-commit-parents commit)) 1)
+    (user-error "Cannot %s a merge commit" command)))
+
+(defun magit-decode-git-path (path)
+  (if (eq (aref path 0) ?\")
+      (string-as-multibyte (read path))
+    path))
+
+(defun magit-abbrev-length ()
+  (string-to-number (or (magit-get "core.abbrev") "7")))
+
+(defun magit-abbrev-arg ()
+  (format "--abbrev=%d" (magit-abbrev-length)))
+
+;;;; Git Revisions
+
+(defvar magit-uninteresting-refs
+  '("^refs/stash$"
+    "^refs/remotes/[^/]+/HEAD$"
+    "^refs/remotes/[^/]+/top-bases$"
+    "^refs/top-bases$"))
+
+(cl-defun magit-list-interesting-refs (&optional uninteresting
+                                                 (refs nil srefs))
+  (cl-loop for ref in (if srefs
+                          refs
+                        (mapcar (lambda (l)
+                                  (cadr (split-string l " ")))
+                                (magit-git-lines "show-ref")))
+           with label
+           unless (or (cl-loop for i in
+                               (cl-typecase uninteresting
+                                 (null magit-uninteresting-refs)
+                                 (list uninteresting)
+                                 (string (cons (format "^refs/heads/%s$"
+                                                       uninteresting)
+                                               magit-uninteresting-refs)))
+                               thereis (string-match i ref))
+                      (not (setq label (magit-format-ref ref))))
+           collect (cons label ref)))
 
 (defun magit-format-ref (ref)
 
 (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."
-  (let ((return-value nil))
-    (with-temp-buffer
-      (magit-git-insert (list "ls-tree" "-r" treeish))
-      (if (eql 0 (buffer-size))
-          (error "%s is not a commit or tree." treeish))
-      (goto-char (point-min))
-      (while (search-forward-regexp "\t\\(.*\\)" nil 'noerror)
-        (push (match-string 1) return-value)))
-    return-value))
-
-(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)
-                         (magit-tree-contents revision)
-                         nil
-                         'require-match
-                         nil
-                         'magit-read-file-hist
-                         (if buffer-file-name
-                             (let ((topdir-length (length (magit-get-top-dir default-directory))))
-                               (substring (buffer-file-name) topdir-length)))))
-
-(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 default))
-         (rev (or (cdr (assoc reply interesting-refs)) reply)))
-    (if (string= rev "")
-        nil
-      rev)))
+  (cond ((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))
+           (substring ref 13)))
+        (t ref)))
+
+(defvar magit-read-file-hist nil)
+
+(defun magit-read-file-from-rev (revision &optional default)
+  (unless revision
+    (setq revision "HEAD"))
+  (let ((default-directory (magit-get-top-dir)))
+    (magit-completing-read
+     (format "Retrieve file from %s" revision)
+     (magit-git-lines "ls-tree" "-r" "-t" "--name-only" revision)
+     nil 'require-match
+     nil 'magit-read-file-hist
+     (or default (magit-buffer-file-name t)))))
+
+(defun magit-read-file-trace (ignored)
+  (let ((file  (magit-read-file-from-rev "HEAD"))
+        (trace (read-string "Trace: ")))
+    (if (string-match
+         "^\\(/.+/\\|:[^:]+\\|[0-9]+,[-+]?[0-9]+\\)\\(:\\)?$" trace)
+        (concat trace (or (match-string 2 trace) ":") file)
+      (user-error "Trace is invalid, see man git-log"))))
 
 
-(defun magit-read-rev-range (op &optional def-beg def-end)
-  (let ((beg (magit-read-rev (format "%s start" op)
-                             def-beg)))
-    (if (not beg)
-        nil
-      (save-match-data
-        (if (string-match "^\\(.+\\)\\.\\.\\(.+\\)$" beg)
-            (cons (match-string 1 beg) (match-string 2 beg))
-          (let ((end (magit-read-rev (format "%s end" op) def-end)))
-            (cons beg end)))))))
-
-(defun magit-rev-to-git (rev)
-  (or rev
-      (error "No revision specified"))
-  (if (string= rev ".")
-      (magit-marked-commit)
+(defvar magit-read-rev-history nil
+  "The history of inputs to `magit-read-rev' and `magit-read-tag'.")
+
+(defun magit-read-tag (prompt &optional require-match)
+  (magit-completing-read prompt (magit-git-lines "tag") nil
+                         require-match nil 'magit-read-rev-history))
+
+(defun magit-read-rev (prompt &optional default uninteresting noselection)
+  (let* ((interesting-refs
+          (mapcar (lambda (elt)
+                    (setcdr elt (replace-regexp-in-string
+                                 "^refs/heads/" "" (cdr elt)))
+                    elt)
+                  (magit-list-interesting-refs uninteresting)))
+         (reply (magit-completing-read prompt interesting-refs nil nil nil
+                                       'magit-read-rev-history default))
+         (rev (or (cdr (assoc reply interesting-refs)) reply)))
+    (when (equal rev ".")
+      (setq rev magit-marked-commit))
+    (unless (or rev noselection)
+      (user-error "No rev selected"))
     rev))
 
     rev))
 
-(defun magit-rev-range-to-git (range)
-  (or range
-      (error "No revision range specified"))
-  (if (stringp range)
-      range
-    (if (cdr range)
-        (format "%s..%s"
-                (magit-rev-to-git (car range))
-                (magit-rev-to-git (cdr range)))
-      (format "%s" (magit-rev-to-git (car range))))))
-
-(defun magit-rev-describe (rev)
-  (or rev
-      (error "No revision specified"))
-  (if (string= rev ".")
-      "mark"
-    (magit-name-rev rev)))
-
-(defun magit-rev-range-describe (range things)
-  (or range
-      (error "No revision range specified"))
-  (if (stringp range)
-      (format "%s in %s" things range)
-    (if (cdr range)
-        (format "%s from %s to %s" things
-                (magit-rev-describe (car range))
-                (magit-rev-describe (cdr range)))
-      (format "%s at %s" things (magit-rev-describe (car range))))))
-
-(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)
-                (match-string 1 branch)
-              branch)))))
-
-(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."
-  (let* ((prompt (or prompt "Remote"))
-         (def (or def (magit-guess-remote)))
-         (remotes (magit-git-lines "remote"))
-
-         (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)))
-         (branches (delete nil
-                           (mapcar
-                            (lambda (b)
-                              (and (not (string-match " -> " b))
-                                   (string-match (format "^ *%s/\\(.*\\)$"
-                                                         (regexp-quote remote)) b)
-                                   (match-string 1 b)))
-                            (magit-git-lines "branch" "-r"))))
-         (reply (magit-completing-read (concat prompt ": ") branches
-                                       nil nil nil nil default)))
-    (if (string= reply "") nil reply)))
-
-;;; Sections
-
-;; A buffer in magit-mode is organized into hierarchical sections.
-;; These sections are used for navigation and for hiding parts of the
-;; buffer.
-;;
-;; Most sections also represent the objects that Magit works with,
-;; such as files, diffs, hunks, commits, etc.  The 'type' of a section
-;; identifies what kind of object it represents (if any), and the
-;; parent and grand-parent, etc provide the context.
-
-(defstruct magit-section
-  parent title beginning end children hidden type info
-  needs-refresh-on-show)
-
-(defvar magit-top-section nil
-  "The top section of the current buffer.")
-(make-variable-buffer-local 'magit-top-section)
-(put 'magit-top-section 'permanent-local t)
-
-(defvar magit-old-top-section nil)
-
-(defvar magit-section-hidden-default nil)
-
-(defun magit-new-section (title type)
-  "Create a new section with title TITLE and type TYPE in current buffer.
-
-If not `magit-top-section' exist, the new section will be the new top-section
-otherwise, the new-section will be a child of the current top-section.
-
-If TYPE is nil, the section won't be highlighted."
-  (let* ((s (make-magit-section :parent magit-top-section
-                                :title title
-                                :type type
-                                :hidden magit-section-hidden-default))
-         (old (and magit-old-top-section
-                   (magit-find-section (magit-section-path s)
-                                       magit-old-top-section))))
-    (if magit-top-section
-        (push s (magit-section-children magit-top-section))
-      (setq magit-top-section s))
-    (if old
-        (setf (magit-section-hidden s) (magit-section-hidden old)))
-    s))
-
-(defun magit-cancel-section (section)
-  "Delete the section SECTION."
-  (delete-region (magit-section-beginning section)
-                 (magit-section-end section))
-  (let ((parent (magit-section-parent section)))
-    (if parent
-        (setf (magit-section-children parent)
-              (delq section (magit-section-children parent)))
-      (setq magit-top-section nil))))
+(defun magit-read-rev-with-default (prompt)
+  (magit-read-rev prompt
+                  (let ((branch (or (magit-guess-branch) "HEAD")))
+                    (when branch
+                      (if (string-match "^refs/\\(.*\\)" branch)
+                          (match-string 1 branch)
+                        branch)))))
 
 
-(defmacro magit-with-section (title type &rest body)
-  "Create a new section of title TITLE and type TYPE and evaluate BODY there.
+(defun magit-read-rev-range (op &optional def-beg def-end)
+  (let ((beg (magit-read-rev (format "%s range or start" op) def-beg)))
+    (save-match-data
+      (if (string-match "^\\(.+\\)\\.\\.\\(.+\\)$" beg)
+          (cons (match-string 1 beg) (match-string 2 beg))
+        (let ((end (magit-read-rev (format "%s end" op) def-end nil t)))
+          (if end (cons beg end) beg))))))
+
+(defun magit-read-stash (prompt)
+  (let ((n (read-number prompt 0))
+        (l (1- (length (magit-git-lines "stash" "list")))))
+    (if (> n l)
+        (user-error "No stash older than stash@{%i}" l)
+      (format "stash@{%i}" n))))
+
+(defun magit-read-remote (prompt &optional default require-match)
+  (magit-completing-read prompt (magit-git-lines "remote")
+                         nil require-match nil nil
+                         (or default (magit-guess-remote))))
+
+(defun magit-read-remote-branch (prompt remote &optional default)
+  (let ((branch (magit-completing-read
+                 prompt
+                 (cl-mapcan
+                  (lambda (b)
+                    (and (not (string-match " -> " b))
+                         (string-match (format "^ *%s/\\(.*\\)$"
+                                               (regexp-quote remote)) b)
+                         (list (match-string 1 b))))
+                  (magit-git-lines "branch" "-r"))
+                 nil nil nil nil default)))
+    (unless (string= branch "")
+      branch)))
 
 
-Sections created inside BODY will become children of the new
-section. BODY must leave point at the end of the created section.
+(defun magit-format-ref-label (ref)
+  (cl-destructuring-bind (re face fn)
+      (cl-find-if (lambda (ns)
+                    (string-match (car ns) ref))
+                  magit-refs-namespaces)
+    (if fn
+        (funcall fn ref face)
+      (propertize (or (match-string 1 ref) ref) 'face face))))
+
+(defun magit-format-ref-labels (string)
+  (save-match-data
+    (mapconcat 'magit-format-ref-label
+               (mapcar 'cdr
+                       (magit-list-interesting-refs
+                        nil (split-string string "\\(tag: \\|[(), ]\\)" t)))
+               " ")))
+
+(defun magit-insert-ref-labels (string)
+  (save-match-data
+    (dolist (ref (split-string string "\\(tag: \\|[(), ]\\)" t) " ")
+      (cl-destructuring-bind (re face fn)
+          (cl-find-if (lambda (elt) (string-match (car elt) ref))
+                      magit-refs-namespaces)
+        (if fn
+            (let ((text (funcall fn ref face)))
+              (magit-insert text (get-text-property 1 'face text) ?\s))
+        (magit-insert (or (match-string 1 ref) ref) face ?\s))))))
+
+(defun magit-format-rev-summary (rev)
+  (let ((s (magit-git-string "log" "-1"
+                             (concat "--pretty=format:%h %s") rev)))
+    (when s
+      (string-match " " s)
+      (put-text-property 0 (match-beginning 0) 'face 'magit-log-sha1 s)
+      s)))
+
+;;; Magit Api
+;;;; Section Api
+;;;;; Section Core
+
+(cl-defstruct magit-section
+  type info
+  beginning content-beginning end
+  hidden needs-refresh-on-show highlight
+  diff-status diff-file2 diff-range
+  process
+  parent children)
+
+(defvar-local magit-root-section nil
+  "The root section in the current buffer.
+All other sections are descendants of this section.  The value
+of this variable is set by `magit-with-section' and you should
+never modify it.")
+(put 'magit-root-section 'permanent-local t)
+
+;;;;; Section Creation
+
+(defvar magit-with-section--parent nil
+  "For use by `magit-with-section' only.")
+
+(defvar magit-with-section--oldroot nil
+  "For use by `magit-with-section' only.")
+
+(defmacro magit-with-section (arglist &rest body)
+  "\n\n(fn (NAME TYPE &optional INFO HEADING NOHIGHLIGHT COLLAPSE) &rest ARGS)"
+  (declare (indent 1) (debug ((form form &optional form form form) body)))
+  (let ((s (car arglist)))
+    `(let ((,s (make-magit-section
+                :type ',(nth 1 arglist)
+                :info  ,(nth 2 arglist)
+                :highlight (not ,(nth 4 arglist))
+                :beginning (point-marker)
+                :content-beginning (point-marker)
+                :parent magit-with-section--parent)))
+       (setf (magit-section-hidden ,s)
+             (let ((old (and magit-with-section--oldroot
+                             (magit-find-section (magit-section-path ,s)
+                                                 magit-with-section--oldroot))))
+               (if old
+                   (magit-section-hidden old)
+                 ,(nth 5 arglist))))
+       (let ((magit-with-section--parent ,s)
+             (magit-with-section--oldroot
+              (or magit-with-section--oldroot
+                  (unless magit-with-section--parent
+                    (prog1 magit-root-section
+                      (setq magit-root-section ,s))))))
+         ,@body)
+       (when ,s
+         (set-marker-insertion-type (magit-section-content-beginning ,s) t)
+         (let ((heading ,(nth 3 arglist)))
+           (when heading
+             (save-excursion
+               (goto-char (magit-section-beginning ,s))
+               (insert
+                (if (string-match-p "\n$" heading)
+                    (substring heading 0 -1)
+                 (propertize
+                  (let (c)
+                    (if (and magit-show-child-count
+                              (string-match-p ":$" heading)
+                             (> (setq c (length (magit-section-children ,s))) 0))
+                        (format "%s (%s):" (substring heading 0 -1) c)
+                      heading))
+                  'face 'magit-section-title)))
+               (insert "\n"))))
+         (set-marker-insertion-type (magit-section-beginning ,s) t)
+         (goto-char (max (point) ; smaller if there is no content
+                         (magit-section-content-beginning ,s)))
+         (setf (magit-section-end ,s) (point-marker))
+         (save-excursion
+           (goto-char (magit-section-beginning ,s))
+           (let ((end (magit-section-end ,s)))
+             (while (< (point) end)
+               (let ((next (or (next-single-property-change
+                                (point) 'magit-section)
+                               end)))
+                 (unless (get-text-property (point) 'magit-section)
+                   (put-text-property (point) next 'magit-section ,s))
+                 (goto-char next)))))
+         (if (eq ,s magit-root-section)
+             (magit-section-set-hidden magit-root-section nil)
+           (setf (magit-section-children (magit-section-parent ,s))
+                 (nconc (magit-section-children (magit-section-parent ,s))
+                        (list ,s)))))
+       ,s)))
 
 
-If TYPE is nil, the section won't be highlighted."
+(defmacro magit-cmd-insert-section (arglist washer program &rest args)
+  "\n\n(fn (TYPE &optional HEADING) WASHER PROGRAM &rest ARGS)"
   (declare (indent 2))
   (declare (indent 2))
-  (let ((s (make-symbol "*section*")))
-    `(let* ((,s (magit-new-section ,title ,type))
-            (magit-top-section ,s))
-       (setf (magit-section-beginning ,s) (point))
-       ,@body
-       (setf (magit-section-end ,s) (point))
-       (setf (magit-section-children ,s)
-             (nreverse (magit-section-children ,s)))
-       ,s)))
+  `(magit-with-section (section ,(car arglist)
+                                ',(car arglist)
+                                ,(cadr arglist) t)
+     (apply #'process-file ,program nil (list t nil) nil
+            (magit-flatten-onelevel (list ,@args)))
+     (unless (eq (char-before) ?\n)
+       (insert "\n"))
+     (save-restriction
+       (narrow-to-region (magit-section-content-beginning section) (point))
+       (goto-char (point-min))
+       (funcall ,washer)
+       (goto-char (point-max)))
+     (let ((parent   (magit-section-parent section))
+           (head-beg (magit-section-beginning section))
+           (body-beg (magit-section-content-beginning section)))
+  &nbs