;;
;; To start: `M-x stgit'
+(when (< emacs-major-version 22)
+ (error "Emacs older than 22 is not supported by stgit.el"))
+
(require 'git nil t)
(require 'cl)
(require 'ewoc)
(insert (propertize (if (eq status 'index) "Index" "Work tree")
'face face))
(insert (format "%-30s"
- (propertize (symbol-name name) 'face face))
+ (propertize (symbol-name name)
+ 'face face
+ 'syntax-table (string-to-syntax "w")))
" "
(if (stgit-patch-empty patch) "(empty) " "")
(propertize (or (stgit-patch-desc patch) "")
("G" . stgit-goto)
("=" . stgit-diff)
("D" . stgit-delete)
- ([(control ?/)] . stgit-undo)
+ ([?\C-/] . stgit-undo)
("\C-_" . stgit-undo)
+ ([?\C-c ?\C-/] . stgit-redo)
+ ("\C-c\C-_" . stgit-redo)
("B" . stgit-branch)
("t" . ,toggle-map)
("d" . ,diff-map)
(set (make-local-variable 'stgit-show-worktree) stgit-default-show-worktree)
(set (make-local-variable 'stgit-index-node) nil)
(set (make-local-variable 'stgit-worktree-node) nil)
+ (set (make-local-variable 'parse-sexp-lookup-properties) t)
(set-variable 'truncate-lines 't)
(add-hook 'after-save-hook 'stgit-update-saved-file)
(run-hooks 'stgit-mode-hook))
(error "Cannot find commit id for %s" patchsym))
(match-string 1 result))))
-(defun stgit-show-patch (unmerged-stage)
+(defun stgit-show-patch (unmerged-stage ignore-whitespace)
"Show the patch on the current line.
UNMERGED-STAGE is the argument to `git-diff' that that selects
which stage to diff against in the case of unmerged files."
- (stgit-capture-output "*StGit patch*"
- (case (get-text-property (point) 'entry-type)
- ('file
- (let* ((patched-file (stgit-patched-file-at-point))
- (patch-name (stgit-patch-name-at-point))
- (patch-id (let ((id (stgit-id patch-name)))
- (if (and (eq id :index)
- (eq (stgit-file-status patched-file)
- 'unmerged))
- :work
- id)))
- (args (append (and (stgit-file-cr-from patched-file)
- (list (stgit-find-copies-harder-diff-arg)))
- (cond ((eq patch-id :index)
- '("--cached"))
- ((eq patch-id :work)
- (list unmerged-stage))
- (t
- (list (concat patch-id "^") patch-id)))
- '("--")
+ (let ((space-arg (when (numberp ignore-whitespace)
+ (cond ((> ignore-whitespace 4)
+ "--ignore-all-space")
+ ((> ignore-whitespace 1)
+ "--ignore-space-change"))))
+ (patch-name (stgit-patch-name-at-point t)))
+ (stgit-capture-output "*StGit patch*"
+ (case (get-text-property (point) 'entry-type)
+ ('file
+ (let* ((patched-file (stgit-patched-file-at-point))
+ (patch-id (let ((id (stgit-id patch-name)))
+ (if (and (eq id :index)
+ (eq (stgit-file-status patched-file)
+ 'unmerged))
+ :work
+ id)))
+ (args (append (and space-arg (list space-arg))
+ (and (stgit-file-cr-from patched-file)
+ (list (stgit-find-copies-harder-diff-arg)))
+ (cond ((eq patch-id :index)
+ '("--cached"))
+ ((eq patch-id :work)
+ (list unmerged-stage))
+ (t
+ (list (concat patch-id "^") patch-id)))
+ '("--")
(if (stgit-file-copy-or-rename patched-file)
(list (stgit-file-cr-from patched-file)
(stgit-file-cr-to patched-file))
(list (stgit-file-file patched-file))))))
- (apply 'stgit-run-git "diff" args)))
- ('patch
- (let* ((patch-name (stgit-patch-name-at-point))
- (patch-id (stgit-id patch-name)))
- (if (or (eq patch-id :index) (eq patch-id :work))
- (apply 'stgit-run-git "diff"
- (stgit-find-copies-harder-diff-arg)
- (if (eq patch-id :index)
- '("--cached")
- (list unmerged-stage)))
- (stgit-run "show" "-O" "--patch-with-stat" "-O" "-M"
- (stgit-patch-name-at-point)))))
- (t
- (error "No patch or file at point")))
- (with-current-buffer standard-output
- (goto-char (point-min))
- (diff-mode))))
-
-(defun stgit-diff ()
- "Show the patch on the current line."
- (interactive)
- (stgit-show-patch "--ours"))
-
-(defun stgit-diff-ours ()
- "Show the patch on the current line.
-
-For unmerged files, diff against our branch."
- (interactive)
- (stgit-show-patch "--ours"))
-
-(defun stgit-diff-theirs ()
- "Show the patch on the current line.
-
-For unmerged files, diff against their branch."
- (interactive)
- (stgit-show-patch "--theirs"))
-
-(defun stgit-diff-base ()
- "Show the patch on the current line.
-
-For unmerged files, diff against the base version."
- (interactive)
- (stgit-show-patch "--base"))
-
-(defun stgit-diff-combined ()
- "Show the patch on the current line.
-
-For unmerged files, show a combined diff."
- (interactive)
- (stgit-show-patch "--cc"))
+ (apply 'stgit-run-git "diff" args)))
+ ('patch
+ (let* ((patch-id (stgit-id patch-name)))
+ (if (or (eq patch-id :index) (eq patch-id :work))
+ (apply 'stgit-run-git "diff"
+ (stgit-find-copies-harder-diff-arg)
+ (append (and space-arg (list space-arg))
+ (if (eq patch-id :index)
+ '("--cached")
+ (list unmerged-stage))))
+ (let ((args (append '("show" "-O" "--patch-with-stat" "-O" "-M")
+ (and space-arg (list "-O" space-arg))
+ (list (stgit-patch-name-at-point)))))
+ (apply 'stgit-run args)))))
+ (t
+ (error "No patch or file at point")))
+ (with-current-buffer standard-output
+ (goto-char (point-min))
+ (diff-mode)))))
+
+(defmacro stgit-define-diff (name diff-arg &optional unmerged-action)
+ `(defun ,name (&optional ignore-whitespace)
+ ,(format "Show the patch on the current line.
+
+%sWith a prefix argument, ignore whitespace. With a prefix argument
+greater than four (e.g., \\[universal-argument] \
+\\[universal-argument] \\[%s]), ignore all whitespace."
+ (if unmerged-action
+ (format "For unmerged files, %s.\n\n" unmerged-action)
+ "")
+ name)
+ (interactive "p")
+ (stgit-show-patch ,diff-arg ignore-whitespace)))
+
+(stgit-define-diff stgit-diff
+ "--ours" nil)
+(stgit-define-diff stgit-diff-ours
+ "--ours"
+ "diff against our branch")
+(stgit-define-diff stgit-diff-theirs
+ "--theirs"
+ "diff against their branch")
+(stgit-define-diff stgit-diff-base
+ "--base"
+ "diff against the merge base")
+(stgit-define-diff stgit-diff-combined
+ "--cc"
+ "show a combined diff")
(defun stgit-move-change-to-index (file)
"Copies the workspace state of FILE to index, using git add or git rm"
(defun stgit-undo (&optional arg)
"Run stg undo.
-With prefix argument, run it with the --hard flag."
+With prefix argument, run it with the --hard flag.
+
+See also `stgit-redo'."
(interactive "P")
(stgit-capture-output nil
(if arg
(stgit-run "undo")))
(stgit-reload))
+(defun stgit-redo (&optional arg)
+ "Run stg redo.
+With prefix argument, run it with the --hard flag.
+
+See also `stgit-undo'."
+ (interactive "P")
+ (stgit-capture-output nil
+ (if arg
+ (stgit-run "redo" "--hard")
+ (stgit-run "redo")))
+ (stgit-reload))
+
(defun stgit-refresh (&optional arg)
"Run stg refresh.
If the index contains any changes, only refresh from index.
:group 'stgit)
(defcustom stgit-default-show-worktree
- nil
+ t
"Set to non-nil to by default show the working tree in a new stgit buffer.
This value is used as the default value for `stgit-show-worktree'."