stgit.el: Forbid stgit-{delete,edit,mark,rename} on index and work tree
[stgit] / contrib / stgit.el
index 00e54d6..9bbc87d 100644 (file)
@@ -472,15 +472,21 @@ at point."
           (let ((file
                  (cond ((looking-at
                          "\\([CR]\\)\\([0-9]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0")
-                        (make-stgit-file
-                         :old-perm       old-perm
-                         :new-perm       new-perm
-                         :copy-or-rename t
-                         :cr-score       (string-to-number (match-string 2))
-                         :cr-from        (match-string 3)
-                         :cr-to          (match-string 4)
-                         :status         (stgit-file-status-code (match-string 1))
-                         :file           (match-string 3)))
+                        (let* ((patch-status (stgit-patch-status patch))
+                               (file-subexp  (if (eq patch-status 'unapplied)
+                                                 3
+                                               4))
+                               (file         (match-string file-subexp)))
+                          (make-stgit-file
+                           :old-perm       old-perm
+                           :new-perm       new-perm
+                           :copy-or-rename t
+                           :cr-score       (string-to-number (match-string 2))
+                           :cr-from        (match-string 3)
+                           :cr-to          (match-string 4)
+                           :status         (stgit-file-status-code
+                                            (match-string 1))
+                           :file           file)))
                        ((looking-at "\\([ABD-QS-Z]\\)\0\\([^\0]*\\)\0")
                         (make-stgit-file
                          :old-perm       old-perm
@@ -489,7 +495,8 @@ at point."
                          :cr-score       nil
                          :cr-from        nil
                          :cr-to          nil
-                         :status         (stgit-file-status-code (match-string 1))
+                         :status         (stgit-file-status-code
+                                          (match-string 1))
                          :file           (match-string 2))))))
             (ewoc-enter-last ewoc file))
           (goto-char (match-end 0))))
@@ -682,10 +689,16 @@ Commands:
 (defun stgit-patch-at-point (&optional cause-error)
   (get-text-property (point) 'patch-data))
 
-(defun stgit-patch-name-at-point (&optional cause-error)
+(defun stgit-patch-name-at-point (&optional cause-error only-patches)
   "Return the patch name on the current line as a symbol.
-If CAUSE-ERROR is not nil, signal an error if none found."
+If CAUSE-ERROR is not nil, signal an error if none found.
+If ONLY-PATCHES is not nil, only allow real patches, and not
+index or work tree."
   (let ((patch (stgit-patch-at-point)))
+    (and patch
+         only-patches
+         (memq (stgit-patch-status patch) '(work index))
+         (setq patch nil))
     (cond (patch
            (stgit-patch-name patch))
           (cause-error
@@ -725,7 +738,12 @@ If that patch cannot be found, do nothing."
   "Mark the patch under point."
   (interactive)
   (let* ((node (ewoc-locate stgit-ewoc))
-         (patch (ewoc-data node)))
+         (patch (ewoc-data node))
+         (name (stgit-patch-name patch)))
+    (when (eq name :work)
+      (error "Cannot mark the work tree"))
+    (when (eq name :index)
+      (error "Cannot mark the index"))
     (stgit-add-mark (stgit-patch-name patch))
     (ewoc-invalidate stgit-ewoc node))
   (stgit-next-patch))
@@ -751,9 +769,10 @@ If that patch cannot be found, do nothing."
 
 (defun stgit-rename (name)
   "Rename the patch under point to NAME."
-  (interactive (list (read-string "Patch name: "
-                                  (symbol-name (stgit-patch-name-at-point t)))))
-  (let ((old-patchsym (stgit-patch-name-at-point t)))
+  (interactive (list
+                (read-string "Patch name: "
+                             (symbol-name (stgit-patch-name-at-point t t)))))
+  (let ((old-patchsym (stgit-patch-name-at-point t t)))
     (stgit-capture-output nil
       (stgit-run "rename" old-patchsym name))
     (let ((name-sym (intern name)))
@@ -987,7 +1006,7 @@ If PATCHSYM is a keyword, returns PATCHSYM unmodified."
 (defun stgit-edit ()
   "Edit the patch on the current line."
   (interactive)
-  (let ((patchsym (stgit-patch-name-at-point t))
+  (let ((patchsym (stgit-patch-name-at-point t t))
         (edit-buf (get-buffer-create "*StGit edit*"))
         (dir default-directory))
     (log-edit 'stgit-confirm-edit t nil edit-buf)
@@ -1057,6 +1076,11 @@ the work tree and index."
                      current-prefix-arg))
   (unless patchsyms
     (error "No patches to delete"))
+  (when (memq :index patchsyms)
+    (error "Cannot delete the index"))
+  (when (memq :work  patchsyms)
+    (error "Cannot delete the work tree"))
+
   (let ((npatches (length patchsyms)))
     (when (yes-or-no-p (format "Really delete %d patch%s%s? "
                               npatches