"Returns non-nil if the index contains no changes from HEAD."
(zerop (stgit-run-git-silent "diff-index" "--cached" "--quiet" "HEAD")))
+(defvar stgit-index-node)
+(defvar stgit-worktree-node)
+
+(defun stgit-refresh-index ()
+ (when stgit-index-node
+ (ewoc-invalidate (car stgit-index-node) (cdr stgit-index-node))))
+
+(defun stgit-refresh-worktree ()
+ (when stgit-worktree-node
+ (ewoc-invalidate (car stgit-worktree-node) (cdr stgit-worktree-node))))
+
(defun stgit-run-series (ewoc)
(let ((first-line t))
(with-temp-buffer
:empty (string= (match-string 1) "0"))))
(setq first-line nil)
(forward-line 1)))))
- (when stgit-show-worktree
- (ewoc-enter-last ewoc
- (make-stgit-patch
- :status 'index
- :name :index
- :desc nil
- :empty nil))
- (ewoc-enter-last ewoc
- (make-stgit-patch
- :status 'work
- :name :work
- :desc nil
- :empty nil)))))
+ (if stgit-show-worktree
+ (setq stgit-index-node (cons ewoc (ewoc-enter-last ewoc
+ (make-stgit-patch
+ :status 'index
+ :name :index
+ :desc nil
+ :empty nil)))
+ stgit-worktree-node (cons ewoc (ewoc-enter-last ewoc
+ (make-stgit-patch
+ :status 'work
+ :name :work
+ :desc nil
+ :empty nil))))
+ (setq stgit-worktree-node nil))))
(defun stgit-reload ()
(with-temp-buffer
(stgit-run-silent "branch")
(buffer-substring (point-min) (1- (point-max))))
- 'face 'bold)
+ 'face 'stgit-branch-name-face)
"\n")
(if stgit-show-worktree
"--"
"The face used for StGit descriptions"
:group 'stgit)
+(defface stgit-branch-name-face
+ '((t :inherit bold))
+ "The face used for the StGit branch name"
+ :group 'stgit)
+
(defface stgit-top-patch-face
'((((background dark)) (:weight bold :foreground "yellow"))
(((background light)) (:weight bold :foreground "purple"))
'file-data file))))
(defun stgit-insert-patch-files (patch)
- "Expand (show modification of) the patch with name PATCHSYM (a
-symbol) after the line at point.
-`stgit-expand-find-copies-harder' controls how hard to try to
-find copied files."
- (insert "\n")
+ "Expand (show modification of) the patch PATCH after the line
+at point."
(let* ((patchsym (stgit-patch-name patch))
(end (progn (insert "#") (prog1 (point-marker) (forward-char -1))))
(args (list "-z" (if stgit-expand-find-copies-harder
("S" . stgit-squash)
("N" . stgit-new)
("R" . stgit-repair)
- ("C" . stgit-commit)
- ("U" . stgit-uncommit)
+ ("\C-c\C-c" . stgit-commit)
+ ("\C-c\C-u" . stgit-uncommit)
+ ("U" . stgit-revert-file)
("\r" . stgit-select)
("o" . stgit-find-file-other-window)
("i" . stgit-file-toggle-index)
(set (make-local-variable 'stgit-marked-patches) nil)
(set (make-local-variable 'stgit-expanded-patches) nil)
(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-variable 'truncate-lines 't)
(add-hook 'after-save-hook 'stgit-update-saved-file)
(run-hooks 'stgit-mode-hook))
(buffer (and gitdir (stgit-find-buffer gitdir))))
(when buffer
(with-current-buffer buffer
- ;; FIXME: just invalidate ewoc node
- (stgit-reload)))))
+ (stgit-refresh-worktree)))))
(defun stgit-add-mark (patchsym)
"Mark the patch PATCHSYM."
(stgit-capture-output nil (stgit-run "commit" "-n" count))
(stgit-reload))
+(defun stgit-revert-file ()
+ "Revert the file at point, which must be in the index or the
+working tree."
+ (interactive)
+ (let* ((patched-file (or (stgit-patched-file-at-point)
+ (error "No file on the current line")))
+ (patch-name (stgit-patch-name-at-point))
+ (file-status (stgit-file-status patched-file))
+ (rm-file (cond ((stgit-file-copy-or-rename patched-file)
+ (stgit-file-cr-to patched-file))
+ ((eq file-status 'add)
+ (stgit-file-file patched-file))))
+ (co-file (cond ((eq file-status 'rename)
+ (stgit-file-cr-from patched-file))
+ ((not (memq file-status '(copy add)))
+ (stgit-file-file patched-file)))))
+
+ (unless (memq patch-name '(:work :index))
+ (error "No index or working tree file on this line"))
+
+ (let ((nfiles (+ (if rm-file 1 0) (if co-file 1 0))))
+ (when (yes-or-no-p (format "Revert %d file%s? "
+ nfiles
+ (if (= nfiles 1) "" "s")))
+ (stgit-capture-output nil
+ (when rm-file
+ (stgit-run-git "rm" "-f" "-q" "--" rm-file))
+ (when co-file
+ (stgit-run-git "checkout" "HEAD" co-file)))
+ (stgit-reload)))))
+
(defun stgit-uncommit (count)
"Run stg uncommit on COUNT commits.
Interactively, the prefix argument is used as COUNT."
(goto-char (point-min))
(diff-mode))))
-(defun stgit-move-change-to-index (file status)
+(defun stgit-move-change-to-index (file)
"Copies the workspace state of FILE to index, using git add or git rm"
- (let ((op (if (file-exists-p file) "add" "rm")))
+ (let ((op (if (or (file-exists-p file) (file-symlink-p file))
+ '("add") '("rm" "-q"))))
(stgit-capture-output "*git output*"
- (stgit-run-git op "--" file))))
+ (apply 'stgit-run-git (append op '("--") (list file))))))
-(defun stgit-remove-change-from-index (file status)
+(defun stgit-remove-change-from-index (file)
"Unstages the change in FILE from the index"
(stgit-capture-output "*git output*"
(stgit-run-git "reset" "-q" "--" file)))
(error "No file on the current line"))
(let ((patch-name (stgit-patch-name-at-point)))
(cond ((eq patch-name :work)
- (stgit-move-change-to-index (stgit-file-file patched-file)
- (stgit-file-status patched-file)))
+ (stgit-move-change-to-index (stgit-file-file patched-file)))
((eq patch-name :index)
- (stgit-remove-change-from-index (stgit-file-file patched-file)
- (stgit-file-status patched-file)))
+ (stgit-remove-change-from-index (stgit-file-file patched-file)))
(t
(error "Can only move files in the working tree to index")))))
- ;; FIXME: invalidate ewoc
- (stgit-reload))
+ (stgit-refresh-worktree)
+ (stgit-refresh-index))
(defun stgit-edit ()
"Edit the patch on the current line."