stgit.el: Verify we're in stgit-mode before running commands
[stgit] / contrib / stgit.el
index 006c082..27b1744 100644 (file)
@@ -24,6 +24,10 @@ See `stgit-mode' for commands available."
   (switch-to-stgit-buffer (git-get-top-dir dir))
   (stgit-reload))
 
   (switch-to-stgit-buffer (git-get-top-dir dir))
   (stgit-reload))
 
+(defun stgit-assert-mode ()
+  "Signal an error if not in an StGit buffer."
+  (assert (derived-mode-p 'stgit-mode) nil "Not an StGit buffer"))
+
 (unless (fboundp 'git-get-top-dir)
   (defun git-get-top-dir (dir)
     "Retrieve the top-level directory of a git tree."
 (unless (fboundp 'git-get-top-dir)
   (defun git-get-top-dir (dir)
     "Retrieve the top-level directory of a git tree."
@@ -168,6 +172,10 @@ Returns nil if there was no output."
   "Returns non-nil if the index contains no changes from HEAD."
   (zerop (stgit-run-git-silent "diff-index" "--cached" "--quiet" "HEAD")))
 
   "Returns non-nil if the index contains no changes from HEAD."
   (zerop (stgit-run-git-silent "diff-index" "--cached" "--quiet" "HEAD")))
 
+(defun stgit-work-tree-empty-p ()
+  "Returns non-nil if the work tree contains no changes from index."
+  (zerop (stgit-run-git-silent "diff-files" "--quiet")))
+
 (defvar stgit-index-node)
 (defvar stgit-worktree-node)
 
 (defvar stgit-index-node)
 (defvar stgit-worktree-node)
 
@@ -249,6 +257,7 @@ Returns nil if there was no output."
 (defun stgit-reload ()
   "Update the contents of the StGit buffer."
   (interactive)
 (defun stgit-reload ()
   "Update the contents of the StGit buffer."
   (interactive)
+  (stgit-assert-mode)
   (let ((inhibit-read-only t)
         (curline (line-number-at-pos))
         (curpatch (stgit-patch-name-at-point))
   (let ((inhibit-read-only t)
         (curline (line-number-at-pos))
         (curpatch (stgit-patch-name-at-point))
@@ -674,6 +683,7 @@ See also `stgit-collapse'.
 Non-interactively, operate on PATCHES, and collapse instead of
 expand if COLLAPSE is not nil."
   (interactive (list (stgit-patches-marked-or-at-point)))
 Non-interactively, operate on PATCHES, and collapse instead of
 expand if COLLAPSE is not nil."
   (interactive (list (stgit-patches-marked-or-at-point)))
+  (stgit-assert-mode)
   (let ((patches-diff (funcall (if collapse #'intersection #'set-difference)
                                patches stgit-expanded-patches)))
     (setq stgit-expanded-patches
   (let ((patches-diff (funcall (if collapse #'intersection #'set-difference)
                                patches stgit-expanded-patches)))
     (setq stgit-expanded-patches
@@ -690,6 +700,7 @@ expand if COLLAPSE is not nil."
 
 See also `stgit-expand'."
   (interactive (list (stgit-patches-marked-or-at-point)))
 
 See also `stgit-expand'."
   (interactive (list (stgit-patches-marked-or-at-point)))
+  (stgit-assert-mode)
   (stgit-expand patches t))
 
 (defun stgit-select-patch ()
   (stgit-expand patches t))
 
 (defun stgit-select-patch ()
@@ -703,6 +714,7 @@ See also `stgit-expand'."
 With point on a file, open the associated file. Opens the target
 file for (applied) copies and renames."
   (interactive)
 With point on a file, open the associated file. Opens the target
 file for (applied) copies and renames."
   (interactive)
+  (stgit-assert-mode)
   (case (get-text-property (point) 'entry-type)
     ('patch
      (stgit-select-patch))
   (case (get-text-property (point) 'entry-type)
     ('patch
      (stgit-select-patch))
@@ -714,22 +726,26 @@ file for (applied) copies and renames."
 (defun stgit-find-file-other-window ()
   "Open file at point in other window"
   (interactive)
 (defun stgit-find-file-other-window ()
   "Open file at point in other window"
   (interactive)
+  (stgit-assert-mode)
   (stgit-find-file t))
 
 (defun stgit-find-file-merge ()
   "Open file at point and merge it using `smerge-ediff'."
   (interactive)
   (stgit-find-file t))
 
 (defun stgit-find-file-merge ()
   "Open file at point and merge it using `smerge-ediff'."
   (interactive)
+  (stgit-assert-mode)
   (stgit-find-file t)
   (smerge-ediff))
 
 (defun stgit-quit ()
   "Hide the stgit buffer."
   (interactive)
   (stgit-find-file t)
   (smerge-ediff))
 
 (defun stgit-quit ()
   "Hide the stgit buffer."
   (interactive)
+  (stgit-assert-mode)
   (bury-buffer))
 
 (defun stgit-git-status ()
   "Show status using `git-status'."
   (interactive)
   (bury-buffer))
 
 (defun stgit-git-status ()
   "Show status using `git-status'."
   (interactive)
+  (stgit-assert-mode)
   (unless (fboundp 'git-status)
     (error "The stgit-git-status command requires git-status"))
   (let ((dir default-directory))
   (unless (fboundp 'git-status)
     (error "The stgit-git-status command requires git-status"))
   (let ((dir default-directory))
@@ -747,24 +763,28 @@ file for (applied) copies and renames."
 (defun stgit-next-line (&optional arg)
   "Move cursor vertically down ARG lines"
   (interactive "p")
 (defun stgit-next-line (&optional arg)
   "Move cursor vertically down ARG lines"
   (interactive "p")
+  (stgit-assert-mode)
   (next-line arg)
   (move-to-column (stgit-goal-column)))
 
 (defun stgit-previous-line (&optional arg)
   "Move cursor vertically up ARG lines"
   (interactive "p")
   (next-line arg)
   (move-to-column (stgit-goal-column)))
 
 (defun stgit-previous-line (&optional arg)
   "Move cursor vertically up ARG lines"
   (interactive "p")
+  (stgit-assert-mode)
   (previous-line arg)
   (move-to-column (stgit-goal-column)))
 
 (defun stgit-next-patch (&optional arg)
   "Move cursor down ARG patches."
   (interactive "p")
   (previous-line arg)
   (move-to-column (stgit-goal-column)))
 
 (defun stgit-next-patch (&optional arg)
   "Move cursor down ARG patches."
   (interactive "p")
+  (stgit-assert-mode)
   (ewoc-goto-next stgit-ewoc (or arg 1))
   (move-to-column goal-column))
 
 (defun stgit-previous-patch (&optional arg)
   "Move cursor up ARG patches."
   (interactive "p")
   (ewoc-goto-next stgit-ewoc (or arg 1))
   (move-to-column goal-column))
 
 (defun stgit-previous-patch (&optional arg)
   "Move cursor up ARG patches."
   (interactive "p")
+  (stgit-assert-mode)
   (ewoc-goto-prev stgit-ewoc (or arg 1))
   (move-to-column goal-column))
 
   (ewoc-goto-prev stgit-ewoc (or arg 1))
   (move-to-column goal-column))
 
@@ -817,13 +837,13 @@ file for (applied) copies and renames."
             ("c" .        stgit-new-and-refresh)
             ("\C-c\C-c" . stgit-commit)
             ("\C-c\C-u" . stgit-uncommit)
             ("c" .        stgit-new-and-refresh)
             ("\C-c\C-c" . stgit-commit)
             ("\C-c\C-u" . stgit-uncommit)
-            ("U" .        stgit-revert-file)
+            ("U" .        stgit-revert)
             ("R" .        stgit-resolve-file)
             ("\r" .       stgit-select)
             ("+" .        stgit-expand)
             ("-" .        stgit-collapse)
             ("o" .        stgit-find-file-other-window)
             ("R" .        stgit-resolve-file)
             ("\r" .       stgit-select)
             ("+" .        stgit-expand)
             ("-" .        stgit-collapse)
             ("o" .        stgit-find-file-other-window)
-            ("i" .        stgit-file-toggle-index)
+            ("i" .        stgit-toggle-index)
             (">" .        stgit-push-next)
             ("<" .        stgit-pop-next)
             ("P" .        stgit-push-or-pop)
             (">" .        stgit-push-next)
             ("<" .        stgit-pop-next)
             ("P" .        stgit-push-or-pop)
@@ -883,6 +903,9 @@ Commands for patches:
 \\[stgit-edit] Edit patch description
 \\[stgit-delete]       Delete patch(es)
 
 \\[stgit-edit] Edit patch description
 \\[stgit-delete]       Delete patch(es)
 
+\\[stgit-revert]       Revert all changes in index or work tree
+\\[stgit-toggle-index] Toggle all changes between index and work tree
+
 \\[stgit-push-next]    Push next patch onto stack
 \\[stgit-pop-next]     Pop current patch from stack
 \\[stgit-push-or-pop]  Push or pop patch at point
 \\[stgit-push-next]    Push next patch onto stack
 \\[stgit-pop-next]     Pop current patch from stack
 \\[stgit-push-or-pop]  Push or pop patch at point
@@ -899,8 +922,8 @@ Commands for files:
 \\[stgit-find-file-other-window]       Open the file in another window
 \\[stgit-diff] Show the file's diff
 
 \\[stgit-find-file-other-window]       Open the file in another window
 \\[stgit-diff] Show the file's diff
 
-\\[stgit-file-toggle-index]    Toggle change between index and work tree
-\\[stgit-revert-file]  Revert changes to file
+\\[stgit-toggle-index] Toggle change between index and work tree
+\\[stgit-revert]       Revert changes to file
 
 Display commands:
 \\[stgit-toggle-worktree]      Toggle showing index and work tree
 
 Display commands:
 \\[stgit-toggle-worktree]      Toggle showing index and work tree
@@ -1029,6 +1052,7 @@ PATCHSYM."
 (defun stgit-init ()
   "Run stg init."
   (interactive)
 (defun stgit-init ()
   "Run stg init."
   (interactive)
+  (stgit-assert-mode)
   (stgit-capture-output nil
     (stgit-run "init"))
   (stgit-reload))
   (stgit-capture-output nil
     (stgit-run "init"))
   (stgit-reload))
@@ -1036,6 +1060,7 @@ PATCHSYM."
 (defun stgit-mark ()
   "Mark the patch under point."
   (interactive)
 (defun stgit-mark ()
   "Mark the patch under point."
   (interactive)
+  (stgit-assert-mode)
   (let* ((node (ewoc-locate stgit-ewoc))
          (patch (ewoc-data node))
          (name (stgit-patch-name patch)))
   (let* ((node (ewoc-locate stgit-ewoc))
          (patch (ewoc-data node))
          (name (stgit-patch-name patch)))
@@ -1050,6 +1075,7 @@ PATCHSYM."
 (defun stgit-unmark-up ()
   "Remove mark from the patch on the previous line."
   (interactive)
 (defun stgit-unmark-up ()
   "Remove mark from the patch on the previous line."
   (interactive)
+  (stgit-assert-mode)
   (stgit-previous-patch)
   (let* ((node (ewoc-locate stgit-ewoc))
          (patch (ewoc-data node)))
   (stgit-previous-patch)
   (let* ((node (ewoc-locate stgit-ewoc))
          (patch (ewoc-data node)))
@@ -1060,6 +1086,7 @@ PATCHSYM."
 (defun stgit-unmark-down ()
   "Remove mark from the patch on the current line."
   (interactive)
 (defun stgit-unmark-down ()
   "Remove mark from the patch on the current line."
   (interactive)
+  (stgit-assert-mode)
   (let* ((node (ewoc-locate stgit-ewoc))
          (patch (ewoc-data node)))
     (stgit-remove-mark (stgit-patch-name patch))
   (let* ((node (ewoc-locate stgit-ewoc))
          (patch (ewoc-data node)))
     (stgit-remove-mark (stgit-patch-name patch))
@@ -1071,6 +1098,7 @@ PATCHSYM."
   (interactive (list
                 (read-string "Patch name: "
                              (symbol-name (stgit-patch-name-at-point t t)))))
   (interactive (list
                 (read-string "Patch name: "
                              (symbol-name (stgit-patch-name-at-point t t)))))
+  (stgit-assert-mode)
   (let ((old-patchsym (stgit-patch-name-at-point t t)))
     (stgit-capture-output nil
       (stgit-run "rename" old-patchsym name))
   (let ((old-patchsym (stgit-patch-name-at-point t t)))
     (stgit-capture-output nil
       (stgit-run "rename" old-patchsym name))
@@ -1090,6 +1118,7 @@ PATCHSYM."
 With a prefix argument, repair the StGit metadata if the branch
 was modified with git commands (`stgit-repair')."
   (interactive "P")
 With a prefix argument, repair the StGit metadata if the branch
 was modified with git commands (`stgit-repair')."
   (interactive "P")
+  (stgit-assert-mode)
   (if repair
       (stgit-repair)
     (stgit-reload)))
   (if repair
       (stgit-repair)
     (stgit-reload)))
@@ -1097,6 +1126,7 @@ was modified with git commands (`stgit-repair')."
 (defun stgit-repair ()
   "Run stg repair."
   (interactive)
 (defun stgit-repair ()
   "Run stg repair."
   (interactive)
+  (stgit-assert-mode)
   (stgit-capture-output nil
     (stgit-run "repair"))
   (stgit-reload))
   (stgit-capture-output nil
     (stgit-run "repair"))
   (stgit-reload))
@@ -1116,6 +1146,7 @@ was modified with git commands (`stgit-repair')."
   "Switch to branch BRANCH."
   (interactive (list (completing-read "Switch to branch: "
                                       (stgit-available-branches))))
   "Switch to branch BRANCH."
   (interactive (list (completing-read "Switch to branch: "
                                       (stgit-available-branches))))
+  (stgit-assert-mode)
   (stgit-capture-output nil (stgit-run "branch" "--" branch))
   (stgit-reload))
 
   (stgit-capture-output nil (stgit-run "branch" "--" branch))
   (stgit-reload))
 
@@ -1141,6 +1172,7 @@ If OMIT-STGIT is not nil, filter out \"resf/heads/*.stgit\"."
   "Rebase to NEW-BASE."
   (interactive (list (completing-read "Rebase to: "
                                       (stgit-available-refs t))))
   "Rebase to NEW-BASE."
   (interactive (list (completing-read "Rebase to: "
                                       (stgit-available-refs t))))
+  (stgit-assert-mode)
   (stgit-capture-output nil (stgit-run "rebase" new-base))
   (stgit-reload))
 
   (stgit-capture-output nil (stgit-run "rebase" new-base))
   (stgit-reload))
 
@@ -1149,6 +1181,7 @@ If OMIT-STGIT is not nil, filter out \"resf/heads/*.stgit\"."
 Interactively, the prefix argument is used as COUNT.
 A negative COUNT will uncommit instead."
   (interactive "p")
 Interactively, the prefix argument is used as COUNT.
 A negative COUNT will uncommit instead."
   (interactive "p")
+  (stgit-assert-mode)
   (if (< count 0)
       (stgit-uncommit (- count))
     (stgit-capture-output nil (stgit-run "commit" "-n" count))
   (if (< count 0)
       (stgit-uncommit (- count))
     (stgit-capture-output nil (stgit-run "commit" "-n" count))
@@ -1159,6 +1192,7 @@ A negative COUNT will uncommit instead."
 Interactively, the prefix argument is used as COUNT.
 A negative COUNT will commit instead."
   (interactive "p")
 Interactively, the prefix argument is used as COUNT.
 A negative COUNT will commit instead."
   (interactive "p")
+  (stgit-assert-mode)
   (if (< count 0)
       (stgit-commit (- count))
     (stgit-capture-output nil (stgit-run "uncommit" "-n" count))
   (if (< count 0)
       (stgit-commit (- count))
     (stgit-capture-output nil (stgit-run "uncommit" "-n" count))
@@ -1184,6 +1218,7 @@ previous file if point is at the last file within a patch."
   "Revert the file at point, which must be in the index or the
 working tree."
   (interactive)
   "Revert the file at point, which must be in the index or the
 working tree."
   (interactive)
+  (stgit-assert-mode)
   (let* ((patched-file (or (stgit-patched-file-at-point)
                            (error "No file on the current line")))
          (patch-name   (stgit-patch-name-at-point))
   (let* ((patched-file (or (stgit-patched-file-at-point)
                            (error "No file on the current line")))
          (patch-name   (stgit-patch-name-at-point))
@@ -1219,9 +1254,43 @@ working tree."
         (stgit-reload)
         (stgit-goto-patch patch-name next-file)))))
 
         (stgit-reload)
         (stgit-goto-patch patch-name next-file)))))
 
+(defun stgit-revert ()
+  "Revert the change at point, which must be the index, the work
+tree, or a single change in either."
+  (interactive)
+  (stgit-assert-mode)
+  (let ((patched-file (stgit-patched-file-at-point)))
+    (if patched-file
+        (stgit-revert-file)
+      (let* ((patch-name (or (stgit-patch-name-at-point)
+                             (error "No patch or file at point")))
+             (patch-desc (case patch-name
+                           (:index "index")
+                           (:work  "work tree")
+                           (t (error (substitute-command-keys
+                                      "Use \\[stgit-delete] to delete a patch"))))))
+        (when (if (eq patch-name :work)
+                  (stgit-work-tree-empty-p)
+                (stgit-index-empty-p))
+          (error (format "There are no changes in the %s to revert"
+                         patch-desc)))
+        (and (eq patch-name :index)
+             (not (stgit-work-tree-empty-p))
+             (error "Cannot revert index as work tree contains unstaged changes"))
+
+        (when (yes-or-no-p (format "Revert all changes in the %s? "
+                                   patch-desc))
+          (if (eq patch-name :index)
+              (stgit-run-git-silent "reset" "--hard" "-q")
+            (stgit-run-git-silent "checkout" "--" "."))
+          (stgit-refresh-index)
+          (stgit-refresh-worktree)
+          (stgit-goto-patch patch-name))))))
+
 (defun stgit-resolve-file ()
   "Resolve conflict in the file at point."
   (interactive)
 (defun stgit-resolve-file ()
   "Resolve conflict in the file at point."
   (interactive)
+  (stgit-assert-mode)
   (let* ((patched-file (stgit-patched-file-at-point))
          (patch        (stgit-patch-at-point))
          (patch-name   (and patch (stgit-patch-name patch)))
   (let* ((patched-file (stgit-patched-file-at-point))
          (patch        (stgit-patch-at-point))
          (patch-name   (and patch (stgit-patch-name patch)))
@@ -1242,6 +1311,7 @@ working tree."
   "Push the first unapplied patch.
 With numeric prefix argument, push that many patches."
   (interactive "p")
   "Push the first unapplied patch.
 With numeric prefix argument, push that many patches."
   (interactive "p")
+  (stgit-assert-mode)
   (stgit-capture-output nil (stgit-run "push" "-n" npatches))
   (stgit-reload)
   (stgit-refresh-git-status))
   (stgit-capture-output nil (stgit-run "push" "-n" npatches))
   (stgit-reload)
   (stgit-refresh-git-status))
@@ -1250,6 +1320,7 @@ With numeric prefix argument, push that many patches."
   "Pop the topmost applied patch.
 With numeric prefix argument, pop that many patches."
   (interactive "p")
   "Pop the topmost applied patch.
 With numeric prefix argument, pop that many patches."
   (interactive "p")
+  (stgit-assert-mode)
   (stgit-capture-output nil (stgit-run "pop" "-n" npatches))
   (stgit-reload)
   (stgit-refresh-git-status))
   (stgit-capture-output nil (stgit-run "pop" "-n" npatches))
   (stgit-reload)
   (stgit-refresh-git-status))
@@ -1262,6 +1333,7 @@ With numeric prefix argument, pop that many patches."
 (defun stgit-push-or-pop ()
   "Push or pop the patch on the current line."
   (interactive)
 (defun stgit-push-or-pop ()
   "Push or pop the patch on the current line."
   (interactive)
+  (stgit-assert-mode)
   (let ((patchsym (stgit-patch-name-at-point t t))
         (applied (stgit-applied-at-point-p)))
     (stgit-capture-output nil
   (let ((patchsym (stgit-patch-name-at-point t t))
         (applied (stgit-applied-at-point-p)))
     (stgit-capture-output nil
@@ -1271,6 +1343,7 @@ With numeric prefix argument, pop that many patches."
 (defun stgit-goto ()
   "Go to the patch on the current line."
   (interactive)
 (defun stgit-goto ()
   "Go to the patch on the current line."
   (interactive)
+  (stgit-assert-mode)
   (let ((patchsym (stgit-patch-name-at-point t)))
     (stgit-capture-output nil
       (stgit-run "goto" patchsym))
   (let ((patchsym (stgit-patch-name-at-point t)))
     (stgit-capture-output nil
       (stgit-run "goto" patchsym))
@@ -1354,6 +1427,7 @@ greater than four (e.g., \\[universal-argument] \
                 "")
               name)
      (interactive "p")
                 "")
               name)
      (interactive "p")
+     (stgit-assert-mode)
      (stgit-show-patch ,diff-arg ignore-whitespace)))
 
 (stgit-define-diff stgit-diff
      (stgit-show-patch ,diff-arg ignore-whitespace)))
 
 (stgit-define-diff stgit-diff
@@ -1386,6 +1460,14 @@ If FORCE is not nil, use --force."
   (stgit-capture-output "*git output*"
     (stgit-run-git "reset" "-q" "--" file)))
 
   (stgit-capture-output "*git output*"
     (stgit-run-git "reset" "-q" "--" file)))
 
+(defun stgit-git-index-unmerged-p ()
+  (let (result)
+    (with-output-to-string
+      (setq result (not (zerop (stgit-run-git-silent "diff-index" "--cached"
+                                                     "--diff-filter=U"
+                                                     "--quiet" "HEAD")))))
+    result))
+
 (defun stgit-file-toggle-index ()
   "Move modified file in or out of the index.
 
 (defun stgit-file-toggle-index ()
   "Move modified file in or out of the index.
 
@@ -1393,6 +1475,7 @@ Leaves the point where it is, but moves the mark to where the
 file ended up. You can then jump to the file with \
 \\[exchange-point-and-mark]."
   (interactive)
 file ended up. You can then jump to the file with \
 \\[exchange-point-and-mark]."
   (interactive)
+  (stgit-assert-mode)
   (let* ((patched-file   (or (stgit-patched-file-at-point)
                             (error "No file on the current line")))
         (patched-status (stgit-file-status patched-file)))
   (let* ((patched-file   (or (stgit-patched-file-at-point)
                             (error "No file on the current line")))
         (patched-status (stgit-file-status patched-file)))
@@ -1420,9 +1503,39 @@ file ended up. You can then jump to the file with \
       (push-mark nil t t)
       (stgit-goto-patch patch-name point-file))))
 
       (push-mark nil t t)
       (stgit-goto-patch patch-name point-file))))
 
+(defun stgit-toggle-index ()
+  "Move change in or out of the index.
+
+Works on index and work tree, as well as files in either.
+
+Leaves the point where it is, but moves the mark to where the
+file ended up. You can then jump to the file with \
+\\[exchange-point-and-mark]."
+  (interactive)
+  (stgit-assert-mode)
+  (if (stgit-patched-file-at-point)
+      (stgit-file-toggle-index)
+    (let ((patch-name (stgit-patch-name-at-point)))
+      (unless (memq patch-name '(:index :work))
+        (error "Can only move changes between working tree and index"))
+      (when (stgit-git-index-unmerged-p)
+        (error "Resolve unmerged changes with \\[stgit-resolve-file] first"))
+      (if (if (eq patch-name :index)
+              (stgit-index-empty-p)
+            (stgit-work-tree-empty-p))
+          (message "No changes to be moved")
+        (stgit-capture-output nil
+          (if (eq patch-name :work)
+              (stgit-run-git "add" "--update")
+            (stgit-run-git "reset" "--mixed" "-q")))
+        (stgit-refresh-worktree)
+        (stgit-refresh-index))
+      (stgit-goto-patch (if (eq patch-name :index) :work :index)))))
+
 (defun stgit-edit ()
   "Edit the patch on the current line."
   (interactive)
 (defun stgit-edit ()
   "Edit the patch on the current line."
   (interactive)
+  (stgit-assert-mode)
   (let ((patchsym (stgit-patch-name-at-point t t))
         (edit-buf (get-buffer-create "*StGit edit*"))
         (dir default-directory))
   (let ((patchsym (stgit-patch-name-at-point t t))
         (edit-buf (get-buffer-create "*StGit edit*"))
         (dir default-directory))
@@ -1446,6 +1559,7 @@ file ended up. You can then jump to the file with \
 With a prefix argument, include a \"Signed-off-by:\" line at the
 end of the patch."
   (interactive "P")
 With a prefix argument, include a \"Signed-off-by:\" line at the
 end of the patch."
   (interactive "P")
+  (stgit-assert-mode)
   (let ((edit-buf (get-buffer-create "*StGit edit*"))
         (dir default-directory))
     (log-edit 'stgit-confirm-new t nil edit-buf)
   (let ((edit-buf (get-buffer-create "*StGit edit*"))
         (dir default-directory))
     (log-edit 'stgit-confirm-new t nil edit-buf)
@@ -1476,6 +1590,7 @@ end of the patch.
 
 This works just like running `stgit-new' followed by `stgit-refresh'."
   (interactive "P")
 
 This works just like running `stgit-new' followed by `stgit-refresh'."
   (interactive "P")
+  (stgit-assert-mode)
   (stgit-new add-sign t))
 
 (defun stgit-create-patch-name (description)
   (stgit-new add-sign t))
 
 (defun stgit-create-patch-name (description)
@@ -1505,6 +1620,7 @@ 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))
 the work tree and index."
   (interactive (list (stgit-patches-marked-or-at-point)
                      current-prefix-arg))
+  (stgit-assert-mode)
   (unless patchsyms
     (error "No patches to delete"))
   (when (memq :index patchsyms)
   (unless patchsyms
     (error "No patches to delete"))
   (when (memq :index patchsyms)
@@ -1568,6 +1684,7 @@ 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)))
 Interactively, move the marked patches to where the point is."
   (interactive (list stgit-marked-patches
                      (stgit-move-patches-target)))
+  (stgit-assert-mode)
   (unless patchsyms
     (error "Need at least one patch to move"))
 
   (unless patchsyms
     (error "Need at least one patch to move"))
 
@@ -1598,6 +1715,7 @@ Unless there are any conflicts, the patches will be merged into
 one patch, which will occupy the same spot in the series as the
 deepest patch had before the squash."
   (interactive (list stgit-marked-patches))
 one patch, which will occupy the same spot in the series as the
 deepest patch had before the squash."
   (interactive (list stgit-marked-patches))
+  (stgit-assert-mode)
   (when (< (length patchsyms) 2)
     (error "Need at least two patches to squash"))
   (let ((stgit-buffer (current-buffer))
   (when (< (length patchsyms) 2)
     (error "Need at least two patches to squash"))
   (let ((stgit-buffer (current-buffer))
@@ -1649,6 +1767,7 @@ With prefix argument, run it with the --hard flag.
 
 See also `stgit-redo'."
   (interactive "P")
 
 See also `stgit-redo'."
   (interactive "P")
+  (stgit-assert-mode)
   (stgit-capture-output nil
     (if arg
         (stgit-run "undo" "--hard")
   (stgit-capture-output nil
     (if arg
         (stgit-run "undo" "--hard")
@@ -1661,6 +1780,7 @@ With prefix argument, run it with the --hard flag.
 
 See also `stgit-undo'."
   (interactive "P")
 
 See also `stgit-undo'."
   (interactive "P")
+  (stgit-assert-mode)
   (stgit-capture-output nil
     (if arg
         (stgit-run "redo" "--hard")
   (stgit-capture-output nil
     (if arg
         (stgit-run "redo" "--hard")
@@ -1673,6 +1793,7 @@ If the index contains any changes, only refresh from index.
 
 With prefix argument, refresh the marked patch or the patch under point."
   (interactive "P")
 
 With prefix argument, refresh the marked patch or the patch under point."
   (interactive "P")
+  (stgit-assert-mode)
   (let ((patchargs (if arg
                        (let ((patches (stgit-patches-marked-or-at-point)))
                          (cond ((null patches)
   (let ((patchargs (if arg
                        (let ((patches (stgit-patches-marked-or-at-point)))
                          (cond ((null patches)
@@ -1709,6 +1830,7 @@ Its initial setting is controlled by `stgit-default-show-worktree'.
 `stgit-show-worktree-mode' controls where on screen the index and
 work tree will show up."
   (interactive)
 `stgit-show-worktree-mode' controls where on screen the index and
 work tree will show up."
   (interactive)
+  (stgit-assert-mode)
   (setq stgit-show-worktree
         (if (numberp arg)
             (> arg 0)
   (setq stgit-show-worktree
         (if (numberp arg)
             (> arg 0)
@@ -1721,6 +1843,7 @@ tree. With ARG, show these files if ARG is positive.
 
 Use \\[stgit-toggle-worktree] to show the work tree."
   (interactive)
 
 Use \\[stgit-toggle-worktree] to show the work tree."
   (interactive)
+  (stgit-assert-mode)
   (setq stgit-show-ignored
         (if (numberp arg)
             (> arg 0)
   (setq stgit-show-ignored
         (if (numberp arg)
             (> arg 0)
@@ -1733,6 +1856,7 @@ work tree. With ARG, show these files if ARG is positive.
 
 Use \\[stgit-toggle-worktree] to show the work tree."
   (interactive)
 
 Use \\[stgit-toggle-worktree] to show the work tree."
   (interactive)
+  (stgit-assert-mode)
   (setq stgit-show-unknown
         (if (numberp arg)
             (> arg 0)
   (setq stgit-show-unknown
         (if (numberp arg)
             (> arg 0)