(erase-buffer)
(insert "Branch: ")
(stgit-run-silent "branch")
- (stgit-run-silent "series" "--description")
+ (stgit-run-silent "series" "--description" "--empty")
(stgit-rescan)
(if curpatch
(stgit-goto-patch curpatch)
(insert " <no files>\n"))
(put-text-property start (point) 'stgit-file-patchsym patchsym))))
+(defun stgit-collapse-patch (patchsym)
+ "Collapse the patch with name PATCHSYM after the line at point."
+ (save-excursion
+ (forward-line)
+ (let ((start (point)))
+ (while (eq (get-text-property (point) 'stgit-file-patchsym) patchsym)
+ (forward-line))
+ (delete-region start (point)))))
+
(defun stgit-rescan ()
"Rescan the status buffer."
(save-excursion
- (let ((marked ()))
+ (let ((marked ())
+ found-any)
(goto-char (point-min))
(while (not (eobp))
(cond ((looking-at "Branch: \\(.*\\)")
(put-text-property (match-beginning 1) (match-end 1)
'face 'bold))
- ((looking-at "\\([>+-]\\)\\( \\)\\([^ ]+\\) *[|#] \\(.*\\)")
- (let ((state (match-string 1))
- (patchsym (intern (match-string 3))))
+ ((looking-at "\\([0 ]\\)\\([>+-]\\)\\( \\)\\([^ ]+\\) *[|#] \\(.*\\)")
+ (setq found-any t)
+ (let ((empty (match-string 1))
+ (state (match-string 2))
+ (patchsym (intern (match-string 4))))
(put-text-property
- (match-beginning 3) (match-end 3) 'face
+ (match-beginning 4) (match-end 4) 'face
(cond ((string= state ">") 'stgit-top-patch-face)
((string= state "+") 'stgit-applied-patch-face)
((string= state "-") 'stgit-unapplied-patch-face)))
- (put-text-property (match-beginning 4) (match-end 4)
+ (put-text-property (match-beginning 5) (match-end 5)
'face 'stgit-description-face)
(when (memq patchsym stgit-marked-patches)
- (replace-match "*" nil nil nil 2)
+ (save-excursion
+ (replace-match "*" nil nil nil 3))
(setq marked (cons patchsym marked)))
(put-text-property (match-beginning 0) (match-end 0)
'stgit-patchsym patchsym)
(when (memq patchsym stgit-expanded-patches)
(stgit-expand-patch patchsym))
+ (when (equal "0" empty)
+ (save-excursion
+ (goto-char (match-beginning 5))
+ (insert "(empty) ")))
+ (delete-char 1)
))
((or (looking-at "stg series: Branch \".*\" not initialised")
(looking-at "stg series: .*: branch not initialized"))
+ (setq found-any t)
(forward-line 1)
(insert "Run M-x stgit-init to initialise")))
(forward-line 1))
- (setq stgit-marked-patches (nreverse marked)))))
+ (setq stgit-marked-patches (nreverse marked))
+ (unless found-any
+ (insert "\n "
+ (propertize "no patches in series"
+ 'face 'stgit-description-face))))))
+
+(defun stgit-select-file ()
+ (let ((patched-file (stgit-patched-file-at-point)))
+ (unless patched-file
+ (error "No patch or file on the current line"))
+ (let ((filename (expand-file-name (cdr patched-file))))
+ (unless (file-exists-p filename)
+ (error "File does not exist"))
+ (find-file filename))))
+
+(defun stgit-toggle-patch-file-list (curpath)
+ (let ((inhibit-read-only t))
+ (if (memq curpatch stgit-expanded-patches)
+ (save-excursion
+ (setq stgit-expanded-patches (delq curpatch stgit-expanded-patches))
+ (stgit-collapse-patch curpatch))
+ (progn
+ (setq stgit-expanded-patches (cons curpatch stgit-expanded-patches))
+ (stgit-expand-patch curpatch)))))
(defun stgit-select ()
"Expand or collapse the current entry"
(interactive)
(let ((curpatch (stgit-patch-at-point)))
- (if (not curpatch)
- (let ((patched-file (stgit-patched-file-at-point)))
- (unless patched-file
- (error "No patch or file on the current line"))
- (let ((filename (expand-file-name (cdr patched-file))))
- (unless (file-exists-p filename)
- (error "File does not exist"))
- (find-file filename)))
- (setq stgit-expanded-patches
- (if (memq curpatch stgit-expanded-patches)
- (delq curpatch stgit-expanded-patches)
- (cons curpatch stgit-expanded-patches)))
- (stgit-reload))))
+ (if curpatch
+ (stgit-toggle-patch-file-list curpatch)
+ (stgit-select-file))))
+
(defun stgit-find-file-other-window ()
"Open file at point in other window"
("r" . stgit-refresh)
("\C-c\C-r" . stgit-rename)
("e" . stgit-edit)
- ("c" . stgit-coalesce)
+ ("S" . stgit-squash)
("N" . stgit-new)
("R" . stgit-repair)
("C" . stgit-commit)
("D" . stgit-delete)
([(control ?/)] . stgit-undo)
("\C-_" . stgit-undo)
- ("q" . stgit-quit))))
+ ("B" . stgit-branch)
+ ("q" . stgit-quit))))
(defun stgit-mode ()
"Major mode for interacting with StGit.
(stgit-run "repair"))
(stgit-reload))
-(defun stgit-commit ()
- "Run stg commit."
- (interactive)
- (stgit-capture-output nil (stgit-run "commit"))
+(defun stgit-available-branches ()
+ "Returns a list of the available stg branches"
+ (let ((output (with-output-to-string
+ (stgit-run "branch" "--list")))
+ (start 0)
+ result)
+ (while (string-match "^>?\\s-+s\\s-+\\(\\S-+\\)" output start)
+ (setq result (cons (match-string 1 output) result))
+ (setq start (match-end 0)))
+ result))
+
+(defun stgit-branch (branch)
+ "Switch to branch BRANCH."
+ (interactive (list (completing-read "Switch to branch: "
+ (stgit-available-branches))))
+ (stgit-capture-output nil (stgit-run "branch" "--" branch))
+ (stgit-reload))
+
+(defun stgit-commit (count)
+ "Run stg commit on COUNT commits.
+Interactively, the prefix argument is used as COUNT."
+ (interactive "p")
+ (stgit-capture-output nil (stgit-run "commit" "-n" count))
(stgit-reload))
-(defun stgit-uncommit (arg)
- "Run stg uncommit. Numeric arg determines number of patches to uncommit."
+(defun stgit-uncommit (count)
+ "Run stg uncommit on COUNT commits.
+Interactively, the prefix argument is used as COUNT."
(interactive "p")
- (stgit-capture-output nil (stgit-run "uncommit" "-n" arg))
+ (stgit-capture-output nil (stgit-run "uncommit" "-n" count))
(stgit-reload))
(defun stgit-push-next (npatches)
;; just one file
(stgit-run-git "diff" (concat id "^") id "--"
(cdr patched-file)))))
- (stgit-run "show" patchsym))
+ (stgit-run "show" "-O" "--patch-with-stat" patchsym))
(with-current-buffer standard-output
(goto-char (point-min))
(diff-mode)))))
(substring patch 0 20))
(t patch))))
-(defun stgit-delete (patchsyms)
+(defun stgit-delete (patchsyms &optional spill-p)
"Delete the patches in PATCHSYMS.
-Interactively, delete the marked patches, or the patch at point."
- (interactive (list (stgit-patches-marked-or-at-point)))
+Interactively, delete the marked patches, or the patch at point.
+
+With a prefix argument, or SPILL-P, spill the patch contents to
+the work tree and index."
+ (interactive (list (stgit-patches-marked-or-at-point)
+ current-prefix-arg))
+ (unless patchsyms
+ (error "No patches to delete"))
(let ((npatches (length patchsyms)))
- (if (zerop npatches)
- (error "No patches to delete")
- (when (yes-or-no-p (format "Really delete %d patch%s? "
- npatches
- (if (= 1 npatches) "" "es")))
+ (when (yes-or-no-p (format "Really delete %d patch%s%s? "
+ npatches
+ (if (= 1 npatches) "" "es")
+ (if spill-p
+ " (spilling contents to index)"
+ "")))
+ (let ((args (if spill-p
+ (cons "--spill" patchsyms)
+ patchsyms)))
(stgit-capture-output nil
- (apply 'stgit-run "delete" patchsyms))
+ (apply 'stgit-run "delete" args))
(stgit-reload)))))
-(defun stgit-coalesce (patchsyms)
- "Coalesce the patches in PATCHSYMS.
-Interactively, coalesce the marked patches."
+(defun stgit-squash (patchsyms)
+ "Squash the patches in PATCHSYMS.
+Interactively, squash the marked patches."
(interactive (list stgit-marked-patches))
(when (< (length patchsyms) 2)
- (error "Need at least two patches to coalesce"))
+ (error "Need at least two patches to squash"))
(let ((edit-buf (get-buffer-create "*StGit edit*"))
(dir default-directory))
- (log-edit 'stgit-confirm-coalesce t nil edit-buf)
+ (log-edit 'stgit-confirm-squash t nil edit-buf)
(set (make-local-variable 'stgit-patchsyms) patchsyms)
(setq default-directory dir)
(let ((standard-output edit-buf))
- (apply 'stgit-run-silent "coalesce" "--save-template=-" patchsyms))))
+ (apply 'stgit-run-silent "squash" "--save-template=-" patchsyms))))
-(defun stgit-confirm-coalesce ()
+(defun stgit-confirm-squash ()
(interactive)
(let ((file (make-temp-file "stgit-edit-")))
(write-region (point-min) (point-max) file)
(stgit-capture-output nil
- (apply 'stgit-run "coalesce" "-f" file stgit-patchsyms))
+ (apply 'stgit-run "squash" "-f" file stgit-patchsyms))
(with-current-buffer log-edit-parent-buffer
(stgit-clear-marks)
;; Go to first marked patch and stay there