Commits

Anonymous committed fbd3c65

Major update, see ChangeLog

  • Participants
  • Parent commits c09e376

Comments (0)

Files changed (4)

+1998-04-27  Greg Klanderman  <greg@alphatech.com>
+
+	* pcl-cvs.el (cvs-find-program): use decode-path-internal.
+
+1998-04-24  Greg Klanderman  <greg@alphatech.com>
+
+	* pcl-cvs.el (cvs-execute-list): remove unused binding of
+	`arg-str'.
+	(cvs-mode-commit): remove unused binding of `cvs-buf'.
+	(cvs-mode-emerge): ditto.
+	(cvs-old-ediff-interface): ditto.
+	(cvs-mode-changelog-commit): ditto.
+
+	* pcl-cvs.el (cvs-mode-toggle-marks): new function.
+	(cvs-mode-map): bind it to `T'.
+	(cvs-default-ignore-marks): New variable to specify default mark
+	behavior for non-diffing commands. 
+	(cvs-diff-ignore-marks): Update docstring.
+	(cvs-ignore-marks-p): simple predicate added.
+	(cvs-mode-commit): use cvs-ignore-marks-p in the call to
+	cvs-get-marked. 
+	(cvs-mode-diff-cvs): ditto.
+	(cvs-mode-diff-head): ditto.
+	(cvs-mode-diff-backup): ditto.
+	(cvs-mode-diff-vendor): ditto.
+	(cvs-mode-remove-file): ditto.
+	(cvs-mode-undo-local-changes): ditto.
+	(cvs-mode-acknowledge): ditto.
+	(cvs-mode-add): ditto.
+	(cvs-mode-ignore): ditto.
+	(cvs-mode-status): ditto.
+	(cvs-mode-log): ditto.
+	(cvs-mode-tag): ditto.
+	(cvs-mode-rtag): ditto.
+	(cvs-mode-byte-compile-files): ditto.
+	(cvs-mode-changelog-commit): ditto.
+
+	* pcl-cvs.el: eval-when-compile compiler pacification.
+
+	* pcl-cvs.el (cvs-examine): use cvs-maybe-use-local-flags and
+	cvs-*-flags.  Argument now means `set flags', *not* `local'.
+	(cvs-update): ditto.
+	(cvs-update-other-window): ditto.
+	(cvs-mode-update-no-prompt): ditto (but had no arg previously).
+	(cvs-do-update): remove `local' arg.
+	(cvs-mode-commit): use cvs-maybe-use-local-flags and cvs-*-flags.
+	(cvs-mode-changelog-commit): ditto.
+	(cvs-edit-done): use cvs-commit-flags-to-use, set from either
+	cvs-mode-commit or cvs-mode-changelog-commit.
+
+1998-04-23  Greg Klanderman  <greg@alphatech.com>
+
+	* pcl-cvs.el (cvs-commit-flags): new flags variable.
+	(cvs-remove-flags): ditto.
+	(cvs-undo-flags): ditto.
+	(cvs-*-flags-local): add defvars for local flags
+	(cvs-*-flags-history): add defvars for flag histories.
+	(cvs-mode-add): use cvs-maybe-use-local-flags and cvs-*-flags.
+	(cvs-mode-status): ditto.
+	(cvs-mode-log): ditto.
+	(cvs-mode-tag): ditto
+	(cvs-mode-rtag): ditto
+	(cvs-mode-remove-file): ditto
+	(cvs-mode-undo-local-changes): Don't update cvs fileinfo state
+	until we know we're not going to signal an error on an unhandled case.
+	(cvs-mode-undo-local-changes): use cvs-maybe-use-local-flags and
+	cvs-*-flags. 
+	(cvs-mode-diff-cvs): only construct the argument list once.
+	(cvs-mode-diff-head): ditto.
+	(cvs-mode-diff-backup): ditto.
+	(cvs-mode-diff-vendor): ditto.
+	(cvs-mode-diff-cvs): use cvs-maybe-use-local-flags and
+	cvs-*-flags.  Argument now means `set flags', *not* `toggle marks'.
+	(cvs-mode-diff-head): ditto.
+	(cvs-mode-diff-backup): ditto.
+	(cvs-mode-diff-vendor): ditto.
+
+1998-04-16  Greg Klanderman  <greg@alphatech.com>
+
+	* pcl-cvs.el (cvs-add-flags): new flags variable for cvs add.
+	(cvs-maybe-use-local-flags): new macro to use for handling C-u
+	argument to cvs-mode commands for setting flags.
+
+	* pcl-cvs.el (cvs-startup-message): take out CVS ID tags
+
+	* pcl-cvs.el (cvs-do-update): tweak buffer formatting
+
+	* pcl-cvs.el (cvs-default-directory): new var to save the
+	working/update 	directory.
+	(cvs-do-update): set it.
+	(cvs-dir-name-relative-to-root): new function - give the directory 
+	name relative to cvs-default-root.
+	(cvs-pp): use it to format DIRCHANGE entries, show the path only
+	relative to the root update directory.
+
+	* pcl-cvs.el (cvs-add-file-update-buffer): update docs
+	(cvs-add-do-update): new function - just update the buffer and tins
+	(cvs-add-buffer-how): new function - has just the part of
+	cvs-add-file-update-buffer that wants to be done prior to actually 
+	running cvs.
+	(cvs-add-how): new function - separate files to be added into new
+	files, new directories, and resurrected files.
+	(cvs-mode-add): Use the above to avoid modifying the
+	buffer before the add is actually performed.  this way we don't
+	get confused if the user quits out of the add while entering the
+	description.  also, if directories are added, we now resort the
+	buffer as directories sort differently than files.
+
+1998-04-24  Greg Klanderman  <greg@alphatech.com>
+
+	* pcl-cvs-xemacs.el (pcl-cvs-font-lock-keywords): fix these so
+	they work reasonably.
+
+1998-04-26  Oscar Figueiredo  <Oscar.Figueiredo@di.epfl.ch>
+
+	* pcl-cvs.el (cvs-find-backup-file): Added an optional argument to
+	find a preferred revision backup instead of the first backup file
+	found
+	(cvs-parse-stdout): Deal with the special case when a file already 
+	contains the modifications from the repository (no merge nor
+	conflict on update)
+
 1998-04-19  Oscar Figueiredo  <Oscar.Figueiredo@di.epfl.ch>
 
 	* pcl-cvs.el (cvs-parse-stderr): Accept standalone conflict
 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 # Boston, MA 02111-1307, USA.
 
-VERSION = 1.05
+VERSION = 1.06
 AUTHOR_VERSION =
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = pcl-cvs

File pcl-cvs-xemacs.el

 		 (looking-at "^[* ] ")))))
       (mode-motion-highlight-line event)))
 
+(defconst pcl-cvs-status-list
+  '("Updated"
+    "Patched"
+    "Modified"
+    "Merged"
+    "Conflict"
+    "Added"
+    "Removed"
+    "Unknown dir"
+    "Unknown"
+    "Removed from repository:"
+    "Conflict: Removed from repository, changed by you:"
+    "Conflict: Removed by you, changed in repository:"
+    "Conflict: Removed by you, but still exists:")
+  "List of status values in pcl-cvs")
+
 (defconst pcl-cvs-font-lock-keywords
-  '(("^In directory \\(.+\\)$" 1 cvs-header-face)
-    ("^[* ] \\w+ +\\(ci\\)" 1 cvs-status-face)
-    ("^[* ] \\(Conflict\\|Merged\\)" 1 cvs-status-face)
-    ("^[* ] \\w+ +\\(ci +\\)?\\(.+\\)$" 2 cvs-filename-face)
-    )
+  (let ((file-line (concat "^[* ] \\(\\("
+                           (mapconcat 'identity
+                                      pcl-cvs-status-list
+                                      "\\|")
+                           "\\)\\( +ci\\)?\\)\\(.+\\)$"))
+        (move-away "\\(Move away\\) \\(.*\\) \\(- it is in the way\\)"))
+    `(("^In directory \\(.+\\)[:]$" 1 cvs-header-face)
+      (,file-line 1 cvs-status-face)
+      (,file-line 4 cvs-filename-face)
+      (,move-away 1 cvs-status-face)
+      (,move-away 3 cvs-status-face)
+      (,move-away 2 cvs-filename-face)
+      ("This repository directory is missing!  Remove this directory manually."
+       0 cvs-status-face)))
   "Patterns to highlight in the *cvs* buffer.")
 
 ;;;###autoload
 ;; also use $GNU here, since may folks might install CVS as a GNU package
 ;;
 (defun cvs-find-program (program)
-  (let ((path (list (getenv "LOCAL")
-		    (getenv "GNU")
-		    "/usr/local/bin"
-		    "/usr/bin"
-		    "/bin")))
+  (let ((path (if (getenv "PATH")
+                  (decode-path-internal (getenv "PATH"))
+                (list (getenv "LOCAL")
+                      (getenv "GNU")
+                      "/usr/local/bin"
+                      "/usr/bin"
+                      "/bin"))))
     (while path
       (if (stringp (car path))
 	  (let ((abs-program (expand-file-name program (car path))))
 
 (defconst cvs-startup-message
   (if cvs-inhibit-copyright-message
-      "PCL-CVS release 1.05-CVS-$Name$"
-    "PCL-CVS release 1.05 from CVS release $Name$.
+      "PCL-CVS release 1.05-CVS"
+    "PCL-CVS release 1.05 from CVS release.
 Copyright (C) 1992, 1993 Per Cederqvist
 Pcl-cvs comes with absolutely no warranty; for details consult the manual.
 This is free software, and you are welcome to redistribute it under certain
   "*Name of the cvs temporary buffer.
 Output from cvs is placed here by synchronous commands.")
 
+(defvar cvs-default-ignore-marks nil
+  "*Non-nil if non-diffing cvs mode commands should ignore any marked files.
+Normally they run on the files that are marked (with cvs-mode-mark),
+or the file under the cursor if no files are marked.  If this variable
+is set to a non-nil value they will by default run on the file on the
+current line.  See also `cvs-diff-ignore-marks'")
+
 (defvar cvs-diff-ignore-marks nil
   "*Non-nil if cvs-diff and cvs-mode-diff-backup should ignore any marked files.
 Normally they run diff on the files that are marked (with cvs-mode-mark),
 or the file under the cursor if no files are marked.  If this variable
-is set to a non-nil value they will always run diff on the file on the
+is set to a non-nil value they will by default run diff on the file on the
 current line.")
 
 ;;; (setq cvs-status-flags '("-v"))
 
 To restrict the update to the current working directory, set this to \"-l\".")
 
+(defvar cvs-add-flags nil
+  "*List of strings to use as flags to pass to ``cvs add''.  Default is none")
+
+(defvar cvs-commit-flags nil
+  "*List of strings to use as flags to pass to ``cvs commit''.  Default is none")
+
+(defvar cvs-remove-flags nil
+  "*List of strings to use as flags to pass to ``cvs remove''.  Default is none")
+
+(defvar cvs-undo-flags nil
+  "*List of strings to use as flags to pass to ``cvs update'' from
+cvs-mode-undo-local-changes.  Default is none")
+
 (defvar cvs-update-prog-output-skip-regexp "$"
   "*A regexp that matches the end of the output from all cvs update programs.
 That is, output from any programs that are run by CVS (by the flag -u in the
 (defvar cvs-commit-list nil
   "Used internally by pcl-cvs.")
 
+(defvar cvs-default-directory nil
+  "Used internally by pcl-cvs.")
+
+;;; save the last locally set flags for each command
+;;; so we can offer them again next time.
+;;;
+(defvar cvs-status-flags-local nil)
+(defvar cvs-log-flags-local nil)
+(defvar cvs-tag-flags-local nil)
+(defvar cvs-rtag-flags-local nil)
+(defvar cvs-diff-flags-local nil)
+(defvar cvs-update-optional-flags-local '("-l"))
+(defvar cvs-add-flags-local nil)
+(defvar cvs-commit-flags-local nil)
+(defvar cvs-remove-flags-local nil)
+(defvar cvs-undo-flags-local   nil)
+
+;;; save entire history of flags for each command.
+;;;
+(defvar cvs-status-flags-history nil)
+(defvar cvs-log-flags-history nil)
+(defvar cvs-tag-flags-history nil)
+(defvar cvs-rtag-flags-history nil)
+(defvar cvs-diff-flags-history nil)
+(defvar cvs-update-optional-flags-history nil)
+(defvar cvs-add-flags-history nil)
+(defvar cvs-commit-flags-history nil)
+(defvar cvs-remove-flags-history nil)
+(defvar cvs-undo-flags-history   nil)
+
+;;; ----------------------------------
+;;; compiler pacification
+;;;
+(eval-when-compile
+  (defvar cvs-commit-flags-to-use)
+  (defvar ediff-version)
+  (defvar cvs-emerge-tmp-head-file)
+  (defvar cvs-ediff-tmp-head-file))
+
 ;;; The cvs data structure:
 ;;;
 ;;; When the `cvs update' is ready we parse the output.  Every file
     (erase-buffer)))
 
 ;;----------
-;;;###autoload
-(defun cvs-examine (directory &optional local)
+(defmacro cvs-maybe-use-local-flags (arg flags desc &rest body)
+  "Macro to use to handle local argument setting."
+  (let ((local-flags (gensym))
+        (global      (gensym))
+        (local-save  (intern (concat (symbol-name flags) "-local")))
+        (history     (intern (concat (symbol-name flags) "-history"))))
+    `(let ((,local-flags ,flags)
+           (,global (and (> (prefix-numeric-value ,arg) 4)
+                         (< (prefix-numeric-value ,arg) 64))))
+       (when ,arg
+         (setq ,local-flags
+               (cvs-make-list
+                (read-string (concat (if ,global "Globally" "Locally")
+                                     " set "
+                                     ,desc
+                                     ": ")
+                             (mapconcat 'identity
+                                        (if ,global
+                                            ,flags
+                                          ,local-save)
+                                        " ")
+                             ',history)))
+         (setq ,local-save ,local-flags)
+         (if ,global
+             (setq ,flags ,local-flags)))
+       (let ((,flags ,local-flags))
+         ,@body))))
+(put 'cvs-maybe-use-local-flags 'lisp-indent-function 3)
+
+;;----------
+(defun cvs-examine (directory &optional arg)
   "Run a 'cvs -n update' in the current working directory.
 That is, check what needs to be done, but don't change the disc.
 Feed the output to a *cvs* buffer and run cvs-mode on it.
   (interactive (list (read-file-name "CVS Update (directory): "
 				     nil default-directory nil)
 		     current-prefix-arg))
+  (cvs-maybe-use-local-flags arg cvs-update-optional-flags
+                             "`cvs update -n' flags"
   (let ((use-dialog-box nil))
-    (cvs-do-update directory local 'noupdate))
-  (switch-to-buffer cvs-buffer-name))
+    (cvs-do-update directory 'noupdate))
+  (switch-to-buffer cvs-buffer-name)))
 
 ;;----------
 ;;;###autoload
-(defun cvs-update (directory &optional local)
+(defun cvs-update (directory &optional arg)
   "Run a 'cvs update' in the current working directory.  Feed the
 output to a *cvs* buffer and run cvs-mode on it.
 If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
   ;; If the previous prompt was in a dialog box, the save-some-buffers
   ;; call in cvs-do-update will lose.
   (let ((use-dialog-box nil))
-    (cvs-do-update directory local nil))
+    (cvs-maybe-use-local-flags arg cvs-update-optional-flags
+                               "`cvs update' flags"
+      (cvs-do-update directory nil)))
   (switch-to-buffer cvs-buffer-name))
 
 ;;----------
 ;;;###autoload
-(defun cvs-update-other-window (directory &optional local)
+(defun cvs-update-other-window (directory &optional arg)
   "Run a 'cvs update' in the current working directory.  Feed the
 output to a *cvs* buffer, display it in the other window, and run
 cvs-mode on it.
   (interactive (list (read-file-name "CVS Update other window (directory): "
 				     nil default-directory nil)
 		     current-prefix-arg))
-  (cvs-do-update directory local nil)
+  (cvs-maybe-use-local-flags arg cvs-update-optional-flags
+                             "`cvs update' flags"
+    (cvs-do-update directory nil))
   (switch-to-buffer-other-window cvs-buffer-name))
 
 ;;----------
     (cdr head)))
 
 ;;----------
-(defun cvs-mode-update-no-prompt ()
+(defun cvs-mode-update-no-prompt (&optional arg)
   "Run cvs update in current directory."
 
-  (interactive)
-  (cvs-do-update default-directory nil nil))
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-update-optional-flags
+                             "`cvs update' flags"
+    (cvs-do-update default-directory nil)))
 
 ;;----------
-(defun cvs-do-update (directory local dont-change-disc)
+(defun cvs-do-update (directory dont-change-disc)
   "Do a 'cvs update' in DIRECTORY.
 Args:  DIRECTORY LOCAL DONT-CHANGE-DISC.
 
     (setq args (concat (if cvs-cvsroot (concat " -d " cvs-cvsroot))
 		       (if dont-change-disc " -n ")
 		       " update "
-		       (if local " -l ")
 		       (if cvs-update-optional-flags
 			   (mapconcat 'identity
 				      (copy-sequence cvs-update-optional-flags)
     ;; Set up the buffer that receives the stderr output from "cvs update".
     (set-buffer update-buffer)
     (setq default-directory this-dir)
+    (setq cvs-default-directory this-dir)
     (make-local-variable 'cvs-stdout-file)
     (setq cvs-stdout-file temp-name)
 
     (setq cvs-cookie-handle
 	  (collection-create
 	   cvs-buffer-name 'cvs-pp
-	   cvs-startup-message		;See comment above cvs-startup-message.
-	   "---------- End -----"))
+           (format "%s\n\nCVSROOT directory: %s\nWorking directory: %s\n"
+                   cvs-startup-message       ;See comment above cvs-startup-message.
+                   (if (stringp cvs-default-directory)
+                       (directory-file-name cvs-default-directory)
+                     "?????")
+                   (if (stringp cvs-cvsroot)
+                       (directory-file-name cvs-cvsroot)
+                     "?????"))
+	   "\n---------- End -----"))
 
     (cookie-enter-first
      cvs-cookie-handle
 	   (eq (cvs-fileinfo->type curr) 'REMOVED))))))
 
 ;;----------
-(defun cvs-find-backup-file (filename &optional dirname)
-  "Look for a backup file for FILENAME, optionally in directory DIRNAME, and if
-there is one, return the name of the first file found as a string."
+(defun cvs-find-backup-file (filename &optional dirname revision)
+  "Look for a backup file for FILENAME.
+Optionally work in directory DIRNAME.
+If there is a backup file for REVISION return that file name otherwise
+return the name of the first file found."
 
   (if (eq dirname nil)
       (setq dirname default-directory))
-  (car (directory-files dirname nil (concat "^\\" cvs-bakprefix filename
-					    "\\."))))
+  (or (and revision
+	   (file-exists-p (concat cvs-bakprefix filename "." revision))
+	   (concat cvs-bakprefix filename "." revision))
+      (car (directory-files dirname nil 
+			    (concat "^\\" cvs-bakprefix filename
+				    "\\.")))))
 
 ;;----------
 (defun cvs-find-backup-revision (filename)
 			       "^Merging differences between [0-9.]+ and [0-9.]+ into \\(.*\\)$"
 			       1))
 	  
-	  (if (looking-at "^[CM] \\(.*\\)$")
+	  (if (looking-at (concat "^[CM] \\(.*" filename "\\)$"))
 	      (setq current-dir
 		    (cvs-get-current-dir
 		     root-dir
-		     (file-name-directory (match-string 1)))))
-
-	  (setq backup-file
-		(cvs-find-backup-file filename current-dir))
-	  (setq backup-revision
-		(cvs-find-backup-revision backup-file))
+		     (file-name-directory (match-string 1))))
+	      ;;; If there is no merge or conflict indication on this line
+	      ;;; then the file certainly already contained the diffs
+	      (setq current-dir nil))
+
+	  (if current-dir
+	      (setq backup-file
+		    (cvs-find-backup-file filename current-dir base-revision)
+		    backup-revision
+		    (cvs-find-backup-revision backup-file))
+	    (setq backup-file nil
+		  backup-revision nil))
+	    
 
 	  ;; Was there a conflict during the merge?
 
 	  (cond
-
-	   ((looking-at "^C")
-
+	   ;; Conflict
+	   ((looking-at (concat "^C \\(.*" filename "\\)$"))
 	    (let ((fileinfo
 		   (cvs-create-fileinfo
 		    'CONFLICT current-dir
 		    filename
 		    (buffer-substring complex-start (point)))))
-
 	      ;; squirrel away info about the files that were retrieved for merging
 	      (cvs-set-fileinfo->base-revision fileinfo base-revision)
 	      (cvs-set-fileinfo->head-revision fileinfo head-revision)
 	      (cvs-set-fileinfo->backup-revision fileinfo backup-revision)
 	      (cvs-set-fileinfo->backup-file fileinfo backup-file)
-
 	      (setcdr head (list fileinfo))
 	      (setq head (cdr head))))
-
-	   ((looking-at "^M")
+	   ;; Successfull merge
+	   ((looking-at (concat "^M \\(.*" filename "\\)$"))
 	    (let ((fileinfo
 		   (cvs-create-fileinfo
 		    'MERGED current-dir
 	      (cvs-set-fileinfo->backup-revision fileinfo backup-revision)
 	      (cvs-set-fileinfo->backup-file fileinfo backup-file)
 	      (setcdr head (list fileinfo))
+	      (setq head (cdr head))))
+	   ;; The file probably already contained the modifications
+	   ((null current-dir)
+	    (let ((fileinfo
+		   (cvs-create-fileinfo
+		    'MERGED nil
+		    filename
+		    nil)))
+	      (cvs-set-fileinfo->base-revision fileinfo base-revision)
+	      (cvs-set-fileinfo->head-revision fileinfo head-revision)
+	      (cvs-set-fileinfo->handled fileinfo t)
+	      (setcdr head (list fileinfo))
 	      (setq head (cdr head)))))))
 
        ;; Executing a program because of the -u option in modules.
 			 "cvs-parse-stdout"))))))
 
 ;;----------
+(defun cvs-dir-name-relative-to-root (dir)
+  (if (stringp cvs-default-directory)
+      (let ((base (directory-file-name
+                   (file-name-as-directory
+                    (expand-file-name cvs-default-directory))))
+            (child (expand-file-name dir)))
+        (if (and (>= (length child) (length base))
+                 (string= base (substring child 0 (length base))))
+            (concat "." (substring child (length base)))
+          dir))
+    dir))
+
+;;----------
 (defun cvs-pp (fileinfo)
   "Pretty print FILEINFO.  Insert a printed representation in current buffer.
 For use by the cookie package."
       ((eq a 'REM-EXIST)
        (format "%s Conflict: Removed by you, but still exists: %s" s f))
       ((eq a 'DIRCHANGE)
-       (format "\nIn directory %s:" (cvs-fileinfo->dir fileinfo)))
+       (format "\nIn directory %s:" (cvs-dir-name-relative-to-root
+                                     (cvs-fileinfo->dir fileinfo))))
       ((eq a 'MOVE-AWAY)
        (format "%s Move away %s - it is in the way" s f))
       ((eq a 'REPOS-MISSING)
   (define-key cvs-mode-map "M"	'cvs-mode-mark-all-files)
   (define-key cvs-mode-map "Q"	'cvs-examine)
   (define-key cvs-mode-map "R"	'cvs-mode-revert-updated-buffers)
+  (define-key cvs-mode-map "T"	'cvs-mode-toggle-marks)
   (define-key cvs-mode-map "U"	'cvs-mode-undo-local-changes)
   (define-key cvs-mode-map "a"	'cvs-mode-add)
   (define-key cvs-mode-map "b"	'cvs-mode-diff-backup)
   (define-key cvs-mode-map "x"	'cvs-mode-remove-handled))
 
 ;;----------
+(defun cvs-mode-toggle-marks ()
+  "Toggle whether the next CVS command uses marks."
+  (interactive)
+  (cond ((eq last-command 'cvs-mode-toggle-marks)
+         (setq this-command 'cvs-mode-untoggle-marks))
+        (t
+         (setq this-command 'cvs-mode-toggle-marks)))
+  (let ((last-command this-command))
+    (let ((dflt (cvs-ignore-marks-p cvs-default-ignore-marks))
+          (diff (cvs-ignore-marks-p cvs-diff-ignore-marks)))
+      (cond ((and dflt diff)
+             (message "Ignore marks for next command..."))
+            ((and (not dflt) (not diff))
+             (message "Using marks for next command..."))
+            ((and (not dflt) diff)
+             (message "Ignore marks for diff, use for other commands..."))
+            ((and dflt (not diff))
+             (message "Use marks for diff, ignore for other commands..."))))))
+
+;;----------
+(defun cvs-ignore-marks-p (default)
+  (let ((toggled (eq last-command 'cvs-mode-toggle-marks)))
+    (or (and default (not toggled))
+        (and toggled (not default)))))
+
+;;----------
 (defun cvs-get-marked (&optional ignore-marks ignore-contents)
   "Return a list of all selected tins.
 Args:  &optional IGNORE-MARKS IGNORE-CONTENTS.
 	     (eq type 'CONFLICT)))))
 
 ;;----------
-(defun cvs-mode-commit ()
+(defun cvs-mode-commit (&optional arg)
   "Check in all marked files, or the current file.
 The user will be asked for a log message in a buffer.
 If cvs-erase-input-buffer is non-nil that buffer will be erased.
 Otherwise mark and point will be set around the entire contents of the
 buffer so that it is easy to kill the contents of the buffer with \\[kill-region]."
 
-  (interactive)
-  (let* ((cvs-buf (current-buffer))
-	 (marked (cvs-filter (function cvs-committable)
-			     (cvs-get-marked))))
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-commit-flags "`cvs commit' flags"
+  (let* ((marked (cvs-filter (function cvs-committable)
+			     (cvs-get-marked (cvs-ignore-marks-p
+                                              cvs-default-ignore-marks)))))
     (if (null marked)
 	(error "Nothing to commit!")
       (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
       (cvs-edit-mode)
       (make-local-variable 'cvs-commit-list)
       (setq cvs-commit-list marked)
-      (message "Press C-c C-c when you are done editing."))))
+      (make-local-variable 'cvs-commit-flags-to-use)
+      (setq cvs-commit-flags-to-use cvs-commit-flags)
+      (message "Press C-c C-c when you are done editing.")))))
 
 ;;----------
 (defun cvs-edit-done ()
   "Commit the files to the repository."
 
   (interactive)
-  (if (null cvs-commit-list)
+  (if (or (null cvs-commit-list)
+          (not (boundp 'cvs-commit-flags-to-use)))
       (error "You have already committed the files"))
   (if (and (> (point-max) 1)
 	   (/= (char-after (1- (point-max))) ?\n)
 	(insert ?\n)))
   (save-some-buffers)
   (let ((cc-list cvs-commit-list)
+        (cvs-commit-flags cvs-commit-flags-to-use)
 	(cc-buffer (get-buffer cvs-buffer-name))
 	(msg-buffer (current-buffer))
 	(msg (buffer-substring (point-min) (point-max))))
     (bury-buffer msg-buffer)
     (cvs-use-temp-buffer)
     (message "Committing...")
-    (if (cvs-execute-list cc-list cvs-program
-			  (if cvs-cvsroot
-			      (list "-d" cvs-cvsroot "commit" "-m" msg)
-			    (list "commit" "-m" msg))
+    (if (cvs-execute-list cc-list
+                          cvs-program
+			  (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                                  (list "commit" "-m" msg)
+                                  cvs-commit-flags)
 			  "Committing %s...")
 	(error "Something went wrong.  Check the %s buffer carefully."
 	       cvs-temp-buffer-name))
     (apply 'tin-invalidate cvs-cookie-handle cc-list)
     (set-buffer msg-buffer)
     (setq cvs-commit-list nil)
+    (makunbound 'cvs-commit-flags-to-use)
     (set-buffer cc-buffer)
     (if cvs-auto-remove-handled
 	(cvs-mode-remove-handled)))
     (while tin-list
       (let ((current-dir (cvs-fileinfo->dir (tin-cookie cvs-cookie-handle
 							(car tin-list))))
-	    arg-list
-	    arg-str)
+	    arg-list)
 
 	;; Collect all marked files in this directory.
 
 	    (setq result (cons (car tins) result)))
 	(setq tins (cdr tins))))
     (nreverse result)))
-	  
+
 ;;----------
-(defun cvs-mode-diff-cvs (&optional ignore-marks)
+(defun cvs-mode-diff-cvs (&optional arg ignore-marks)
   "Diff the selected files against the base revisions in the repository.
 
 If the variable cvs-diff-ignore-marks is non-nil any marked files will not be
   (if (not (listp cvs-diff-flags))
       (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
   (save-some-buffers)
+  (cvs-maybe-use-local-flags arg cvs-diff-flags "`cvs diff' flags"
   (message "cvsdiffing...")
   (let ((marked-file-list (cvs-diffable
-		 (cvs-get-marked
-		  (or (and ignore-marks (not cvs-diff-ignore-marks))
-		      (and (not ignore-marks) cvs-diff-ignore-marks))))))
+		 (cvs-get-marked (cvs-ignore-marks-p
+                                  cvs-diff-ignore-marks)))))
     (while marked-file-list
       (let ((fileinfo-to-diff (tin-cookie cvs-cookie-handle
 					  (car marked-file-list)))
 	(setq buffer-read-only nil)
 	(setq default-directory local-def-directory)
 	(erase-buffer)
+        (let ((arglist (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                               '("diff")
+                               cvs-diff-flags
+                               (list (cvs-fileinfo->file-name
+                                      fileinfo-to-diff)))))
 	(insert (format "=== cd %s\n" default-directory))
 	(insert (format "=== cvs %s\n\n"
-			(mapconcat 'cvs-quote-multiword-string
-				   (nconc (if cvs-cvsroot
-					      (list "-d" cvs-cvsroot "diff")
-					    '("diff"))
-					  (copy-sequence cvs-diff-flags)
-					  (list (cvs-fileinfo->file-name
-						 fileinfo-to-diff)))
-				   " ")))
-	(if (apply 'call-process cvs-program nil t t
-		   (nconc (if cvs-cvsroot
-			      (list "-d" cvs-cvsroot "diff")
-			    '("diff"))
-			  (copy-sequence cvs-diff-flags)
-			  (list (cvs-fileinfo->file-name fileinfo-to-diff))))
+			(mapconcat 'cvs-quote-multiword-string arglist " ")))
+	(if (apply 'call-process cvs-program nil t t arglist)
 	    (message "cvsdiffing %s... Done."
 		     (cvs-fileinfo->file-name fileinfo-to-diff))
 	  (message "cvsdiffing %s... No differences found."
-		   (cvs-fileinfo->file-name fileinfo-to-diff)))
+		   (cvs-fileinfo->file-name fileinfo-to-diff))))
 	(goto-char (point-max))
 	(setq marked-file-list (cdr marked-file-list)))))
-  (message "cvsdiffing... Done."))
+  (message "cvsdiffing... Done.")))
 
 ;;----------
-(defun cvs-mode-diff-head (&optional ignore-marks)
+(defun cvs-mode-diff-head (&optional arg ignore-marks)
   "Diff the selected files against the head revisions in the repository.
 
 If the variable cvs-diff-ignore-marks is non-nil any marked files will not be
   (if (not (listp cvs-diff-flags))
       (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
   (save-some-buffers)
+  (cvs-maybe-use-local-flags arg cvs-diff-flags "`cvs diff' flags"
   (message "cvsdiffing...")
   (let ((marked-file-list (cvs-diffable
-		 (cvs-get-marked
-		  (or (and ignore-marks (not cvs-diff-ignore-marks))
-		      (and (not ignore-marks) cvs-diff-ignore-marks))))))
+		 (cvs-get-marked (cvs-ignore-marks-p
+                                  cvs-diff-ignore-marks)))))
     (while marked-file-list
       (let ((fileinfo-to-diff (tin-cookie cvs-cookie-handle
 					  (car marked-file-list)))
 	(setq buffer-read-only nil)
 	(setq default-directory local-def-directory)
 	(erase-buffer)
+        (let ((arglist (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                               '("diff" "-rHEAD")
+                               cvs-diff-flags
+                               (list (cvs-fileinfo->file-name
+                                      fileinfo-to-diff)))))
 	(insert (format "=== cd %s\n" default-directory))
 	(insert (format "=== cvs %s\n\n"
-			(mapconcat 'cvs-quote-multiword-string
-				   (nconc (if cvs-cvsroot
-					      (list "-d" cvs-cvsroot "diff" "-rHEAD")
-					    '("diff" "-rHEAD"))
-					  (copy-sequence cvs-diff-flags)
-					  (list (cvs-fileinfo->file-name
-						 fileinfo-to-diff)))
-				   " ")))
-	(if (apply 'call-process cvs-program nil t t
-		   (nconc (if cvs-cvsroot
-			      (list "-d" cvs-cvsroot "diff" "-rHEAD")
-			    '("diff" "-rHEAD"))
-			  (copy-sequence cvs-diff-flags)
-			  (list (cvs-fileinfo->file-name fileinfo-to-diff))))
+			(mapconcat 'cvs-quote-multiword-string arglist " ")))
+	(if (apply 'call-process cvs-program nil t t arglist)
 	    (message "cvsdiffing %s... Done."
 		     (cvs-fileinfo->file-name fileinfo-to-diff))
 	  (message "cvsdiffing %s... No differences found."
-		   (cvs-fileinfo->file-name fileinfo-to-diff)))
+		   (cvs-fileinfo->file-name fileinfo-to-diff))))
 	(goto-char (point-max))
 	(setq marked-file-list (cdr marked-file-list)))))
-  (message "cvsdiffing... Done."))
+  (message "cvsdiffing... Done.")))
 
 ;;----------
-(defun cvs-mode-diff-backup (&optional ignore-marks)
+(defun cvs-mode-diff-backup (&optional arg ignore-marks)
   "Diff the files against the backup file.
 This command can be used on files that are marked with \"Merged\"
 or \"Conflict\" in the *cvs* buffer.
   (if (not (listp cvs-diff-flags))
       (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
   (save-some-buffers)
+  (cvs-maybe-use-local-flags arg cvs-diff-flags "`cvs diff' flags"
   (let ((marked-file-list (cvs-filter
 			   (function cvs-backup-diffable)
-			   (cvs-get-marked
-			    (or
-			     (and ignore-marks (not cvs-diff-ignore-marks))
-			     (and (not ignore-marks) cvs-diff-ignore-marks))))))
+			   (cvs-get-marked (cvs-ignore-marks-p
+                                            cvs-diff-ignore-marks)))))
     (if (null marked-file-list)
 	(error "No ``Conflict'' or ``Merged'' file selected!"))
     (message "backup diff...")
 	(setq buffer-read-only nil)
 	(setq default-directory local-def-directory)
 	(erase-buffer)
+        (let ((arglist (append cvs-diff-flags
+                               backup-temp-files)))
 	(insert (format "=== cd %s\n" default-directory))
 	(insert (format "=== %s %s\n\n"
 			cvs-diff-program
-			(mapconcat 'cvs-quote-multiword-string
-				   (nconc (copy-sequence cvs-diff-flags)
-					  backup-temp-files)
-				   " ")))
-	(apply 'call-process cvs-diff-program nil t t
-	       (nconc (copy-sequence cvs-diff-flags) backup-temp-files))
+			(mapconcat 'cvs-quote-multiword-string arglist " ")))
+	(apply 'call-process cvs-diff-program nil t t arglist))
 	(goto-char (point-max))
 	(message "backup diff %s... Done."
 		 (cvs-fileinfo->file-name fileinfo-to-diff))
 	(setq marked-file-list (cdr marked-file-list)))))
-  (message "backup diff... Done."))
+  (message "backup diff... Done.")))
 
 ;;----------
-(defun cvs-mode-diff-vendor (&optional ignore-marks)
+(defun cvs-mode-diff-vendor (&optional arg ignore-marks)
   "Diff the revisions merged into the current file.  I.e. show what changes
 were merged in.
 
   (if (not (listp cvs-diff-flags))
       (error "cvs-diff-flags should be set using cvs-set-diff-flags."))
   (save-some-buffers)
+  (cvs-maybe-use-local-flags arg cvs-diff-flags "`cvs diff' flags"
   (let ((marked-file-list (cvs-filter
 			   (function cvs-vendor-diffable)
-			   (cvs-get-marked
-			    (or
-			     (and ignore-marks (not cvs-diff-ignore-marks))
-			     (and (not ignore-marks) cvs-diff-ignore-marks))))))
+			   (cvs-get-marked (cvs-ignore-marks-p
+                                            cvs-diff-ignore-marks)))))
     (if (null marked-file-list)
 	(error "No ``Conflict'' or ``Merged'' file selected!"))
     (message "vendor diff...")
 	(setq buffer-read-only nil)
 	(setq default-directory local-def-directory)
 	(erase-buffer)
+        (let ((arglist (append cvs-diff-flags
+                               vendor-temp-files)))
 	(insert (format "=== cd %s\n" default-directory))
 	(insert (format "=== %s %s\n\n"
 			cvs-diff-program
-			(mapconcat 'cvs-quote-multiword-string
-				   (nconc (copy-sequence cvs-diff-flags)
-					  vendor-temp-files)
-				   " ")))
-	(apply 'call-process cvs-diff-program nil t t
-	       (nconc (copy-sequence cvs-diff-flags) vendor-temp-files))
+			(mapconcat 'cvs-quote-multiword-string arglist " ")))
+	(apply 'call-process cvs-diff-program nil t t arglist))
 	(goto-char (point-max))
 	(message "vendor diff %s... Done."
 		     (cvs-fileinfo->file-name fileinfo-to-diff))
 	  (delete-file (car vendor-temp-files))
 	  (setq vendor-temp-files (cdr vendor-temp-files)))
 	(setq marked-file-list (cdr marked-file-list)))))
-  (message "vendor diff... Done."))
+  (message "vendor diff... Done.")))
 
 ;;----------
 (defun cvs-backup-diffable (tin)
    (t nil)))
 
 ;;----------
-(defun cvs-mode-remove-file ()
+(defun cvs-mode-remove-file (&optional arg)
   "Remove all marked files."
 
-  (interactive)
-  (let ((files-to-remove (cvs-do-removal (cvs-get-marked))))
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-remove-flags "`cvs remove' flags"
+  (let ((files-to-remove (cvs-do-removal (cvs-get-marked
+                                          (cvs-ignore-marks-p
+                                           cvs-default-ignore-marks)))))
     (if (null files-to-remove)
 	nil
       (cvs-use-temp-buffer)
       (message "removing from repository...")
-      (if (cvs-execute-list files-to-remove cvs-program
-			    (if cvs-cvsroot
-				(list "-d" cvs-cvsroot "remove")
-			      '("remove"))
+      (if (cvs-execute-list files-to-remove
+                            cvs-program
+			    (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                                    '("remove")
+                                    cvs-remove-flags)
 			    "removing %s from repository...")
 	  (error "CVS exited with non-zero exit status.")
-	(message "removing from repository... Done.")))))
+	(message "removing from repository... Done."))))))
 
 ;;----------
-(defun cvs-mode-undo-local-changes ()
+(defun cvs-mode-undo-local-changes (&optional arg)
   "Undo local changes to all marked files.
 The file is removed and `cvs update FILE' is run."
 
-  (interactive)
-  (let ((tins-to-undo (cvs-get-marked)))
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-undo-flags "undo local changes flags"
+  (let ((tins-to-undo (cvs-get-marked (cvs-ignore-marks-p
+                                       cvs-default-ignore-marks))))
     (cvs-use-temp-buffer)
     (mapcar 'cvs-insert-full-path tins-to-undo)
     (cond
 		 (fileinfo (tin-cookie cvs-cookie-handle tin))
 		 (type (cvs-fileinfo->type fileinfo)))
 	    (cond
-	     ((or
-	       (eq type 'UPDATED)
-	       (eq type 'PATCHED)
-	       (eq type 'MODIFIED)
-	       (eq type 'MERGED)
-	       (eq type 'CONFLICT)
-	       (eq type 'CVS-REMOVED)
-	       (eq type 'REM-CONFLICT)
-	       (eq type 'MOVE-AWAY)
-	       (eq type 'REMOVED))
+	     ((memq type '(UPDATED PATCHED MODIFIED MERGED CONFLICT
+                           CVS-REMOVED REM-CONFLICT MOVE-AWAY REMOVED))
+	      (setq files-to-update (cons tin files-to-update)))
+
+	     ((eq type 'MOD-CONFLICT)
+	      (error "Use cvs-mode-add instead on %s."
+		     (cvs-fileinfo->file-name fileinfo)))
+
+	     ((eq type 'REM-CONFLICT)
+	      (error "Can't deal with a file you have removed and recreated: %s."
+                     (cvs-fileinfo->file-name fileinfo)))
+
+	     ((eq type 'DIRCHANGE)
+	      (error "Undo on directories not supported (yet)."))
+
+	     ((eq type 'ADDED)
+	      (error "There is no old revision to get for %s"
+		     (cvs-fileinfo->file-name fileinfo)))
+	     (t (error "cvs-mode-undo-local-changes: can't handle type %s"
+		       type)))
+
+	    (setq tins-to-undo (cdr tins-to-undo))))
+        (setq tins-to-undo files-to-update)
+	(while tins-to-undo
+	  (let* ((tin (car tins-to-undo))
+		 (fileinfo (tin-cookie cvs-cookie-handle tin))
+		 (type (cvs-fileinfo->type fileinfo)))
+	    (cond
+	     ((memq type '(UPDATED PATCHED MODIFIED MERGED CONFLICT
+                           CVS-REMOVED REM-CONFLICT MOVE-AWAY REMOVED))
 	      (if (not (eq type 'REMOVED))
 		  (delete-file (cvs-full-path tin)))
-	      (setq files-to-update (cons tin files-to-update))
 	      (cvs-set-fileinfo->type fileinfo 'UPDATED)
 	      (cvs-set-fileinfo->handled fileinfo t)
 	      (tin-invalidate cvs-cookie-handle tin))
 
-	     ((eq type 'MOD-CONFLICT)
-	      (error "Use cvs-mode-add instead on %s."
-		     (cvs-fileinfo->file-name fileinfo)))
-
-	     ((eq type 'REM-CONFLICT)
-	      (error "Can't deal with a file you have removed and recreated."))
-
-	     ((eq type 'DIRCHANGE)
-	      (error "Undo on directories not supported (yet)."))
-
-	     ((eq type 'ADDED)
-	      (error "There is no old revision to get for %s"
-		     (cvs-fileinfo->file-name fileinfo)))
-	     (t (error "cvs-mode-undo-local-changes: can't handle an %s"
-		       type)))
-
-	    (setq tins-to-undo (cdr tins-to-undo))))
+             (t (error "serious error in cvs-mode-undo-local-changes")))
+
+            (setq tins-to-undo (cdr tins-to-undo))))
 	(cvs-use-temp-buffer)
 	(message "Re-getting files from repository...")
-	(if (cvs-execute-list files-to-update cvs-program
-			      (if cvs-cvsroot
-				  (list "-d" cvs-cvsroot "update")
-				'("update"))
+	(if (cvs-execute-list files-to-update
+                              cvs-program
+			      (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                                      '("update")
+                                      cvs-undo-flags)
 			      "Re-getting %s from repository...")
 	    (error "CVS exited with non-zero exit status.")
-	  (message "Re-getting files from repository... Done.")))))))
+	  (message "Re-getting files from repository... Done."))))))))
 
 ;;----------
 (defun cvs-mode-acknowledge ()
   (interactive)
   (mapcar (function (lambda (tin)
 		      (tin-delete cvs-cookie-handle tin)))
-	  (cvs-get-marked)))
+	  (cvs-get-marked (cvs-ignore-marks-p
+                           cvs-default-ignore-marks))))
 
 ;;----------
 (defun cvs-mode-unmark-up (pos)
 
 ;;----------
 (defun cvs-add-file-update-buffer (tin)
-  "Sub-function to cvs-mode-add.  Internal use only.  Update the display.  Return
-non-nil if `cvs add' should be called on this file.
+  "Sub-function to cvs-mode-add.  Internal use only.
+Update the display for tin.
 Args:  TIN.
 
-Returns 'DIR, 'ADD, 'ADD-DIR, or 'RESURRECT."
+Returns 'ADD, 'ADD-DIR, or 'RESURRECT."
 
   (let ((fileinfo (tin-cookie cvs-cookie-handle tin)))
     (cond
       'RESURRECT))))
 
 ;;----------
-(defun cvs-add-sub (cvs-buf candidates)
+(defun cvs-add-do-update (cvs-buf candidates)
+  "Internal use only.  Update display for CANDIDATES.
+Args:  CVS-BUF CANDIDATES.
+
+CANDIDATES is a list of tins.  Updates the CVS-BUF."
+
+  (while candidates
+    (cvs-add-file-update-buffer (car candidates))
+    (setq candidates (cdr candidates))))
+
+;;----------
+(defun cvs-add-buffer-how (tin)
+  "Sub-function to cvs-mode-add.  Internal use only.
+Return non-nil if `cvs add' should be called on this file.
+Args:  TIN.
+
+Returns 'ADD, 'ADD-DIR, or 'RESURRECT."
+
+  (let ((fileinfo (tin-cookie cvs-cookie-handle tin)))
+    (cond
+     ((eq (cvs-fileinfo->type fileinfo) 'UNKNOWN-DIR)
+      'ADD-DIR)
+     ((eq (cvs-fileinfo->type fileinfo) 'UNKNOWN)
+      'ADD)
+     ((eq (cvs-fileinfo->type fileinfo) 'REMOVED)
+      'RESURRECT))))
+
+;;----------
+(defun cvs-add-how (cvs-buf candidates)
   "Internal use only.
 Args:  CVS-BUF CANDIDATES.
 
-CANDIDATES is a list of tins.  Updates the CVS-BUF and returns a list of lists.
+CANDIDATES is a list of tins.  Returns a list of lists.
 The first list is unknown tins that shall be `cvs add -m msg'ed.
 The second list is unknown directory tins that shall be `cvs add -m msg'ed.
 The third list is removed files that shall be `cvs add'ed (resurrected)."
 
   (let (add add-dir resurrect)
     (while candidates
-      (let ((type (cvs-add-file-update-buffer (car candidates))))
+      (let ((type (cvs-add-buffer-how (car candidates))))
 	(cond ((eq type 'ADD)
 	       (setq add (cons (car candidates) add)))
 	      ((eq type 'ADD-DIR)
     (list add add-dir resurrect)))
 
 ;;----------
-(defun cvs-mode-add ()
+(defun cvs-mode-add (&optional arg)
   "Add marked files to the cvs repository."
 
-  (interactive)
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-add-flags "`cvs add' flags"
+  ;;  (message "add flags = %s" cvs-add-flags) (sit-for 5)
   (let* ((buf (current-buffer))
-	 (marked (cvs-get-marked))
-	 (result (cvs-add-sub buf marked))
+	 (marked (cvs-get-marked (cvs-ignore-marks-p
+                                  cvs-default-ignore-marks)))
+	 (result (cvs-add-how buf marked))
 	 (added (car result))
 	 (newdirs (car (cdr result)))
 	 (resurrect (car (cdr (cdr result))))
 	   (message "Resurrecting files from repository...")
 	   (if (cvs-execute-list resurrect
 				 cvs-program
-				 (if cvs-cvsroot
-				     (list "-d" cvs-cvsroot "add")
-				   '("add"))
+                                 (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                                         (list "add")
+                                         cvs-add-flags)
 				 "Resurrecting %s from repository...")
 	       (error "CVS exited with non-zero exit status.")
+             (cvs-add-do-update buf resurrect)
 	     (message "Resurrecting files from repository... Done."))))
 
     (cond (added
 	   (message "Adding new files to repository...")
 	   (if (cvs-execute-list added
 				 cvs-program
-				 (if cvs-cvsroot
-				     (list "-d" cvs-cvsroot "add" "-m" msg)
-				   (list "add" "-m" msg))
+                                 (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                                         (list "add" "-m" msg)
+                                         cvs-add-flags)
 				 "Adding %s to repository...")
 	       (error "CVS exited with non-zero exit status.")
+             (cvs-add-do-update buf added)
 	     (message "Adding new files to repository... Done."))))
 
     (cond (newdirs
 	   (message "Adding new directories to repository...")
 	   (if (cvs-execute-list newdirs
 				 cvs-program
-				 (if cvs-cvsroot
-				     (list "-d" cvs-cvsroot "add" "-m" msg)
-				   (list "add" "-m" msg))
+                                 (append (if cvs-cvsroot (list "-d" cvs-cvsroot))
+                                         (list "add" "-m" msg)
+                                         cvs-add-flags)
 				 "Adding %s to repository...")
 	       (error "CVS exited with non-zero exit status.")
 	     (while newdirs
 		 (cvs-set-fileinfo->file-name fileinfo ".")
 		 (tin-invalidate cvs-cookie-handle tin)
 		 (setq newdirs (cdr newdirs))))
+             (cvs-add-do-update buf newdirs)
+             (cookie-sort cvs-cookie-handle
+                          (function cvs-compare-fileinfos))
 	     ;; FIXME: this should really run cvs-update-no-prompt on the
 	     ;; subdir and insert everthing in the current list.
-	     (message "You must re-update to visit the new directories."))))))
+	     (message "You must re-update to visit the new directories.")))))))
 
 ;;----------
 (defun cvs-mode-ignore ()
 				   (eq type 'UNKNOWN-DIR))
 			       (cvs-append-to-ignore fileinfo)
 			       (tin-delete cvs-cookie-handle tin))))))
-	  (cvs-get-marked)))
+	  (cvs-get-marked (cvs-ignore-marks-p
+                           cvs-default-ignore-marks))))
 
 ;;----------
 (defun cvs-append-to-ignore (fileinfo)
     (save-buffer)))
 
 ;;----------
-(defun cvs-mode-status ()
+(defun cvs-mode-status (&optional arg)
   "Show cvs status for all marked files."
 
-  (interactive)
+  (interactive "P")
   (save-some-buffers)
+  (cvs-maybe-use-local-flags arg cvs-status-flags "`cvs status' flags"
   (if (not (listp cvs-status-flags))
       (error "cvs-status-flags should be set using cvs-set-status-flags."))
-  (let ((marked (cvs-get-marked nil t)))
+  (let ((marked (cvs-get-marked (cvs-ignore-marks-p
+                                 cvs-default-ignore-marks)
+                                t)))
     (cvs-use-temp-buffer)
     (message "Running cvs status ...")
     (if (cvs-execute-list marked
 				  cvs-status-flags)
 			  "Running cvs -Q status %s...")
 	(error "CVS exited with non-zero exit status.")
-      (message "Running cvs -Q status ... Done."))))
+      (message "Running cvs -Q status ... Done.")))))
 
 ;;----------
-(defun cvs-mode-log ()
+(defun cvs-mode-log (&optional arg)
   "Display the cvs log of all selected files."
 
-  (interactive)
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-log-flags "`cvs log' flags"
   (if (not (listp cvs-log-flags))
       (error "cvs-log-flags should be set using cvs-set-log-flags."))
-  (let ((marked (cvs-get-marked nil t)))
+  (let ((marked (cvs-get-marked (cvs-ignore-marks-p
+                                 cvs-default-ignore-marks)
+                                t)))
     (cvs-use-temp-buffer)
     (message "Running cvs log ...")
     (if (cvs-execute-list marked
 				  cvs-log-flags)
 			  "Running cvs log %s...")
 	(error "CVS exited with non-zero exit status.")
-      (message "Running cvs log ... Done."))))
+      (message "Running cvs log ... Done.")))))
 
 ;;----------
-(defun cvs-mode-tag ()
+(defun cvs-mode-tag (&optional arg)
   "Run 'cvs tag' on all selected files."
 
-  (interactive)
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-tag-flags "`cvs tag' flags"
   (if (not (listp cvs-tag-flags))
       (error "cvs-tag-flags should be set using cvs-set-tag-flags."))
-  (let ((marked (cvs-get-marked nil t))
+  (let ((marked (cvs-get-marked (cvs-ignore-marks-p
+                                 cvs-default-ignore-marks)
+                                t))
 	(tag-args (cvs-make-list (read-string "Tag name (and flags): "))))
     (cvs-use-temp-buffer)
     (message "Running cvs tag ...")
 				  tag-args)
 			  "Running cvs tag %s...")
 	(error "CVS exited with non-zero exit status.")
-      (message "Running cvs tag ... Done."))))
+      (message "Running cvs tag ... Done.")))))
 
 ;;----------
-(defun cvs-mode-rtag ()
+(defun cvs-mode-rtag (&optional arg)
   "Run 'cvs rtag' on all selected files."
 
-  (interactive)
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-rtag-flags "`cvs rtag' flags"
   (if (not (listp cvs-rtag-flags))
       (error "cvs-rtag-flags should be set using cvs-set-rtag-flags."))
-  (let ((marked (cvs-get-marked nil t))
+  (let ((marked (cvs-get-marked (cvs-ignore-marks-p
+                                 cvs-default-ignore-marks)
+                                t))
 	;; FIXME:  should give selection from the modules file
 	(module-name (read-string "Module name: "))
 	;; FIXME:  should also ask for an existing tag *or* date
 				  (list module-name))
 			  "Running cvs rtag %s...")
 	(error "CVS rtag exited with non-zero exit status.")
-      (message "Running cvs rtag ... Done."))))
+      (message "Running cvs rtag ... Done.")))))
 
 ;;----------
 (defun cvs-mode-byte-compile-files ()
   "Run byte-compile-file on all selected files that end in '.el'."
 
   (interactive)
-  (let ((marked (cvs-get-marked)))
+  (let ((marked (cvs-get-marked (cvs-ignore-marks-p
+                                 cvs-default-ignore-marks))))
     (while marked
       (let ((filename (cvs-full-path (car marked))))
 	(if (string-match "\\.el$" filename)
 Args:  POS."
 
   (interactive "d")
-  (let* ((cvs-buf (current-buffer))
-	 (tin (tin-locate cvs-cookie-handle pos)))
+  (let* ((tin (tin-locate cvs-cookie-handle pos)))
     (if (boundp 'cvs-emerge-tmp-head-file)
 	(error "There can only be one emerge session active at a time."))
     (if tin
   "Emerge like interface for older ediffs.
 Args:  POS"
 
-  (let* ((cvs-buf (current-buffer))
-	 (tin (tin-locate cvs-cookie-handle pos)))
+  (let* ((tin (tin-locate cvs-cookie-handle pos)))
     (if tin
 	(let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
 	       (type (cvs-fileinfo->type fileinfo)))
         (forward-line 1))
       (indent-rigidly (point-min) (point-max) (- common)))))
 
-(defun cvs-mode-changelog-commit ()
+(defun cvs-mode-changelog-commit (&optional arg)
   "Check in all marked files, or the current file.
 Ask the user for a log message in a buffer.
 
   the files we're checking in, and finally
 - use those paragraphs as the log text."
 
-  (interactive)
-
-  (let* ((cvs-buf (current-buffer))
-         (marked (cvs-filter (function cvs-committable)
-                             (cvs-get-marked))))
+  (interactive "P")
+  (cvs-maybe-use-local-flags arg cvs-commit-flags "`cvs commit' flags"
+  (let* ((marked (cvs-filter (function cvs-committable)
+                             (cvs-get-marked (cvs-ignore-marks-p
+                                              cvs-default-ignore-marks)))))
     (if (null marked)
         (error "Nothing to commit!")
       (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
       (cvs-edit-mode)
       (make-local-variable 'cvs-commit-list)
       (setq cvs-commit-list marked)
-      (message "Press C-c C-c when you are done editing."))))
+      (make-local-variable 'cvs-commit-flags-to-use)
+      (setq cvs-commit-flags-to-use cvs-commit-flags)
+      (message "Press C-c C-c when you are done editing.")))))
 
 (provide 'pcl-cvs)