X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/980ccd21077134fa02716115cb457f6954b3cc42..68048d11396ac8ff09d96a5e1e4d1dee2c27f47a:/contrib/stgit.el diff --git a/contrib/stgit.el b/contrib/stgit.el index de466db..bd85598 100644 --- a/contrib/stgit.el +++ b/contrib/stgit.el @@ -65,7 +65,9 @@ Argument DIR is the repository path." buf)) (defmacro stgit-capture-output (name &rest body) - "Capture StGit output and show it in a window at the end." + "Capture StGit output and, if there was any output, show it in a window +at the end. +Returns nil if there was no output." `(let ((output-buf (get-buffer-create ,(or name "*StGit output*"))) (stgit-dir default-directory) (inhibit-read-only t)) @@ -526,6 +528,7 @@ find copied files." ("r" . stgit-refresh) ("\C-c\C-r" . stgit-rename) ("e" . stgit-edit) + ("M" . stgit-move-patches) ("S" . stgit-squash) ("N" . stgit-new) ("R" . stgit-repair) @@ -783,7 +786,7 @@ With numeric prefix argument, pop that many patches." ;; just one file (stgit-run-git "diff" (concat id "^") id "--" (cdr patched-file))))) - (stgit-run "show" "-O" "--patch-with-stat" patchsym)) + (stgit-run "show" "-O" "--patch-with-stat" "-O" "-M" patchsym)) (with-current-buffer standard-output (goto-char (point-min)) (diff-mode))))) @@ -875,6 +878,62 @@ the work tree and index." (apply 'stgit-run "delete" args)) (stgit-reload))))) +(defun stgit-move-patches-target () + "Return the patchsym indicating a target patch for +`stgit-move-patches'. + +This is either the patch at point, or one of :top and :bottom, if +the point is after or before the applied patches." + + (let ((patchsym (stgit-patch-at-point))) + (cond (patchsym patchsym) + ((save-excursion (re-search-backward "^>" nil t)) :top) + (t :bottom)))) + +(defun stgit-move-patches (patchsyms target-patch) + "Move the patches in PATCHSYMS to below TARGET-PATCH. +If TARGET-PATCH is :bottom or :top, move the patches to the +bottom or top of the stack, respectively. + +Interactively, move the marked patches to where the point is." + (interactive (list stgit-marked-patches + (stgit-move-patches-target))) + (unless patchsyms + (error "Need at least one patch to move")) + + (unless target-patch + (error "Point not at a patch")) + + (if (eq target-patch :top) + (stgit-capture-output nil + (apply 'stgit-run "float" patchsyms)) + + ;; need to have patchsyms sorted by position in the stack + (let (sorted-patchsyms + (series (with-output-to-string + (with-current-buffer standard-output + (stgit-run-silent "series" "--noprefix")))) + start) + (while (string-match "^\\(.+\\)" series start) + (let ((patchsym (intern (match-string 1 series)))) + (when (memq patchsym patchsyms) + (setq sorted-patchsyms (cons patchsym sorted-patchsyms)))) + (setq start (match-end 0))) + (setq sorted-patchsyms (nreverse sorted-patchsyms)) + + (unless (= (length patchsyms) (length sorted-patchsyms)) + (error "Internal error")) + + (while sorted-patchsyms + (setq sorted-patchsyms + (and (stgit-capture-output nil + (if (eq target-patch :bottom) + (stgit-run "sink" "--" (car sorted-patchsyms)) + (stgit-run "sink" "--to" target-patch "--" + (car sorted-patchsyms)))) + (cdr sorted-patchsyms)))))) + (stgit-reload)) + (defun stgit-squash (patchsyms) "Squash the patches in PATCHSYMS. Interactively, squash the marked patches."