changeset 111350:8027e412df98

Backport VC improvements from trunk. * vc/log-edit.el (log-edit-rewrite-fixes): New var. (log-edit-author): New dynamic var. (log-edit-changelog-ours-p, log-edit-insert-changelog-entries): Use it to return the author if different from committer. (log-edit-insert-changelog): Use them to add Author: and Fixes headers. * vc/vc-hooks.el (vc-default-mode-line-string): Doc fix. * vc/vc.el (vc-deduce-backend): New fun. Handle diff buffers. (vc-root-diff, vc-print-root-log, vc-log-incoming) (vc-log-outgoing): Use it. (vc-diff-internal): Set diff-vc-backend. * vc/diff-mode.el (diff-vc-backend): New var. * vc/vc.el (vc-diff-internal): Set `revert-buffer-function' buffer-locally to lambda that re-runs the vc diff command. (Bug#6447) * vc/log-view.el (log-view-mode-map): Bind revert-buffer. Make 'g' (AKA revert-buffer) rerun VC log, log-incoming and log-outgoing commands. * vc/vc.el (vc-log-internal-common): Add a new argument and use it to create a buffer local revert-buffer-function variable. (vc-print-log-internal, vc-log-incoming, vc-log-outgoing): Pass a revert-buffer-function lambda. Improve VC create/retrieve tag/branch. * vc.el (vc-create-tag): Do not read the directory name for VCs with repository revision granularity. Adjust the tag/branch prompt. Reset VC properties. (vc-retrieve-tag): Do not read the directory name for VCs with repository revision granularity. Reset VC properties. Add optional support for resetting VC properties. * vc-dispatcher.el (vc-resynch-window): Add new optional argument, call vc-file-clearprops when true. (vc-resynch-buffer): Add new optional argument, pass it down. (vc-resynch-buffers-in-directory): Likewise. Improve support for special markup in the VC commit message. * vc-mtn.el (vc-mtn-checkin): Support Author: and Date: markup. * vc-hg.el (vc-hg-checkin): Add support for Date:. * vc-git.el (vc-git-checkin): * vc-bzr.el (vc-bzr-checkin): Likewise. Add support for vc-log-incoming, improve vc-log-outgoing for Git. * vc-git.el (vc-git-log-view-mode): Fix font lock for incoming/outgoing logs. (vc-git-log-outgoing, vc-git-log-incoming): New functions. * vc-git.el (vc-git-log-outgoing): Use the same format as the short log. (vc-git-log-incoming): Likewise. Run "git fetch" before the log command Add bindings for vc-log-incoming and vc-log-outgoing. * vc-hooks.el (vc-prefix-map): Add bindings for vc-log-incoming and vc-log-outgoing. * vc-dir.el (vc-dir-menu-map): Add menu bindings for vc-log-incoming and vc-log-outgoing. Improve state updating for VC tag commands. * vc.el (vc-create-tag, vc-retrieve-tag): Call vc-resynch-buffer to update the state of all buffers in the directory. * vc-dir.el (vc-dir): Don't pop-up-windows. (Bug#6204) * vc.el (vc-checkin, vc-modify-change-comment): Adjust to new vc-start/finish-logentry. (vc-find-conflicted-file): New command. (vc-transfer-file): Adjust to new vc-checkin. (vc-next-action): Improve scoping. * vc-git.el (vc-git-checkin): Use log-edit-extract-headers. (vc-git-commits-coding-system): Rename from git-commits-coding-system. * vc-dispatcher.el (vc-log-edit): Shorten names for log-edit-show-files. * vc-bzr.el (vc-bzr-checkin): Use log-edit-extract-headers. (vc-bzr-conflicted-files): New function. * log-edit.el (log-edit-summary, log-edit-header) (log-edit-unknown-header): New faces. (log-edit-headers-alist): New var. (log-edit-header-contents-regexp): New const. (log-edit-match-to-eoh): New function. (log-edit-font-lock-keywords): Use them. (log-edit): Insert a "Summary:" header as default. (log-edit-mode): Mark font-lock rules as case-insensitive. (log-edit-done): Cleanup headers. (log-edit-extract-headers): New function to replace it. * vc-dispatcher.el (vc-finish-logentry): Don't mess so badly with the windows/frames. * vc-bzr.el (vc-bzr-shelve-apply): Don't use *vc-bzr-shelve*. * vc-dir.el (vc-dir-kill-line): New command. (vc-dir-mode-map): Bind it to C-k. (vc-dir-headers): Abbreviate the working dir. * vc-git.el (vc-git-revision-table): Include remote branches. New VC methods: vc-log-incoming and vc-log-outgoing. * vc.el (vc-print-log-setup-buttons, vc-log-internal-common) (vc-incoming-outgoing-internal, vc-log-incoming, vc-log-outgoing): New functions. (vc-print-log-internal): Just call vc-log-internal-common. (vc-log-view-type): New permanent local variable. * vc-hooks.el (vc-menu-map): Bind vc-log-incoming and vc-log-outgoing. * vc-bzr.el (vc-bzr-log-view-mode): Use vc-log-view-type instead of the dynamic bound vc-short-log. (vc-bzr-log-incoming, vc-bzr-log-outgoing): New functions. * vc-git.el (vc-git-log-outgoing): New function. (vc-git-log-view-mode): Use vc-log-view-type instead of the dynamic bound vc-short-log. * vc-hg.el (vc-hg-log-view-mode): Use vc-log-view-type instead of the dynamic bound vc-short-log. Highlight the tag. (vc-hg-log-incoming, vc-hg-log-outgoing): New functions. (vc-hg-outgoing, vc-hg-incoming, vc-hg-outgoing-mode): (vc-hg-incoming-mode): Remove. (vc-hg-extra-menu-map): Do not bind vc-hg-incoming and vc-hg-outgoing. Fix default-directory for vc-root-diff. * vc.el (vc-root-diff): Bind default-directory to the root directory for the diff command. * vc-hg.el (vc-hg-push, vc-hg-pull): Use `apply' when calling `vc-hg-command' with a list of flags. * vc-bzr.el (vc-bzr-log-edit-mode): Add --fixes support to log-edit-before-checkin-process. * vc.el (vc-modify-change-comment): Pass MODE to vc-start-logentry. * vc-bzr.el, vc-hg.el (log-edit-mode): Declare. * vc-dispatcher.el (vc-start-logentry): Doc fix. (log-view-process-buffer, log-edit-extra-flags): Declare. Add special markup processing for commit logs. * log-edit.el (log-edit): Add new argument MODE. Use that mode when non-nil instead of the log-view-mode. * vc.el (vc-default-log-edit-mode): New function. * vc-dispatcher.el (vc-log-edit): Add a mode argument, pass it to log-edit. Support for shelving snapshots and for showing shelves. * vc-bzr.el (vc-bzr-shelve-show, vc-bzr-shelve-show-at-point) (vc-bzr-shelve-apply-and-keep-at-point, vc-bzr-shelve-snapshot): New functions. (vc-bzr-shelve-map, vc-bzr-shelve-menu-map) (vc-bzr-extra-menu-map): Map them.
author Chong Yidong <cyd@stupidchicken.com>
date Sun, 31 Oct 2010 23:13:42 -0400
parents 518ba8ef471b
children 83594fbec156
files etc/NEWS lisp/ChangeLog lisp/diff-mode.el lisp/log-edit.el lisp/log-view.el lisp/vc-arch.el lisp/vc-bzr.el lisp/vc-dir.el lisp/vc-dispatcher.el lisp/vc-git.el lisp/vc-hg.el lisp/vc-hooks.el lisp/vc-mtn.el lisp/vc.el
diffstat 14 files changed, 955 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Sun Oct 31 19:30:15 2010 -0700
+++ b/etc/NEWS	Sun Oct 31 23:13:42 2010 -0400
@@ -34,6 +34,42 @@
 ** The appt-add command takes an optional argument for the warning time.
 This can be used in place of the default appt-message-warning-time.
 
+** VC and related modes
+
+*** New VC commands: vc-log-incoming, vc-log-outgoing, vc-find-conflicted-file.
+
+**** vc-log-incoming for Git runs "git fetch" so that the necessary
+data is available locally.
+
+**** vc-log-incoming and vc-log-outgoing for Git require version 1.7 (or newer).
+
+*** New key bindings: C-x v I and C-x v O bound to vc-log-incoming and
+vc-log-outgoing, respectively.
+
+*** The 'g' key in VC diff, log, log-incoming and log-outgoing buffers
+reruns the corresponding VC command to compute an up to date version
+of the buffer.
+
+*** vc-dir for Bzr supports viewing shelve contents and shelving snapshots.
+
+*** Special markup can be added to log-edit buffers.
+The log-edit buffers are expected to have a format similar to email messages
+with headers of the form:
+  Author: <author of this change>
+  Summary: <one line summary of this change>
+  Fixes: <reference to the bug fixed by this change>
+Some backends handle some of those headers specially, but any unknown header
+is just left as is in the message, so it is not lost.
+
+**** vc-git handles Author: and Date:
+**** vc-hg handles  Author: and Date:
+**** vc-bzr handles Author:, Date: and Fixes:
+**** vc-mtn handles Author: and Date:
+
+*** Pressing g in a *vc-diff* buffer reruns vc-diff, so it will
+produce an up to date diff.
+
+
 ** Obsolete packages
 
 +++
--- a/lisp/ChangeLog	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/ChangeLog	Sun Oct 31 23:13:42 2010 -0400
@@ -1,3 +1,188 @@
+2010-10-31  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* vc/log-edit.el (log-edit-rewrite-fixes): New var.
+	(log-edit-author): New dynamic var.
+	(log-edit-changelog-ours-p, log-edit-insert-changelog-entries):
+	Use it to return the author if different from committer.
+	(log-edit-insert-changelog): Use them to add Author: and Fixes headers.
+
+2010-10-31  Eli Zaretskii  <eliz@gnu.org>
+
+	* vc/vc-hooks.el (vc-default-mode-line-string): Doc fix.
+
+2010-10-31  Chong Yidong  <cyd@stupidchicken.com>
+
+	* vc/vc.el (vc-deduce-backend): New fun.  Handle diff buffers.
+	(vc-root-diff, vc-print-root-log, vc-log-incoming)
+	(vc-log-outgoing): Use it.
+	(vc-diff-internal): Set diff-vc-backend.
+
+	* vc/diff-mode.el (diff-vc-backend): New var.
+
+2010-10-31  Juri Linkov  <juri@jurta.org>
+
+	* vc/vc.el (vc-diff-internal): Set `revert-buffer-function'
+	buffer-locally to lambda that re-runs the vc diff command.
+	(Bug#6447)
+
+2010-10-31  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc/log-view.el (log-view-mode-map): Bind revert-buffer.
+
+	Make 'g' (AKA revert-buffer) rerun VC log, log-incoming and
+	log-outgoing commands.
+	* vc/vc.el (vc-log-internal-common): Add a new argument and use it
+	to create a buffer local revert-buffer-function variable.
+	(vc-print-log-internal, vc-log-incoming, vc-log-outgoing): Pass a
+	revert-buffer-function lambda.
+
+	Improve VC create/retrieve tag/branch.
+	* vc.el (vc-create-tag): Do not read the directory name for VCs
+	with repository revision granularity.  Adjust the tag/branch
+	prompt.  Reset VC properties.
+	(vc-retrieve-tag): Do not read the directory name for VCs
+	with repository revision granularity.  Reset VC properties.
+
+	Add optional support for resetting VC properties.
+	* vc-dispatcher.el (vc-resynch-window): Add new optional argument,
+	call vc-file-clearprops when true.
+	(vc-resynch-buffer): Add new optional argument, pass it down.
+	(vc-resynch-buffers-in-directory): Likewise.
+
+	Improve support for special markup in the VC commit message.
+	* vc-mtn.el (vc-mtn-checkin): Support Author: and Date: markup.
+	* vc-hg.el (vc-hg-checkin): Add support for Date:.
+	* vc-git.el (vc-git-checkin):
+	* vc-bzr.el (vc-bzr-checkin): Likewise.
+
+	Add support for vc-log-incoming, improve vc-log-outgoing for Git.
+	* vc-git.el (vc-git-log-view-mode): Fix font lock for
+	incoming/outgoing logs.
+	(vc-git-log-outgoing, vc-git-log-incoming): New functions.
+
+	* vc-git.el (vc-git-log-outgoing): Use the same format as the
+	short log.
+	(vc-git-log-incoming): Likewise.  Run "git fetch" before the log
+	command
+
+	Add bindings for vc-log-incoming and vc-log-outgoing.
+	* vc-hooks.el (vc-prefix-map): Add bindings for vc-log-incoming
+	and vc-log-outgoing.
+	* vc-dir.el (vc-dir-menu-map): Add menu bindings for vc-log-incoming
+	and vc-log-outgoing.
+
+	Improve state updating for VC tag commands.
+	* vc.el (vc-create-tag, vc-retrieve-tag): Call vc-resynch-buffer
+	to update the state of all buffers in the directory.
+
+2010-05-19  Glenn Morris  <rgm@gnu.org>
+
+	* vc-dir.el (vc-dir): Don't pop-up-windows.  (Bug#6204)
+
+2010-10-31  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* vc.el (vc-checkin, vc-modify-change-comment):
+	Adjust to new vc-start/finish-logentry.
+	(vc-find-conflicted-file): New command.
+	(vc-transfer-file): Adjust to new vc-checkin.
+	(vc-next-action): Improve scoping.
+
+	* vc-git.el (vc-git-checkin): Use log-edit-extract-headers.
+	(vc-git-commits-coding-system): Rename from git-commits-coding-system.
+
+	* vc-dispatcher.el (vc-log-edit): Shorten names for
+	log-edit-show-files.
+
+	* vc-bzr.el (vc-bzr-checkin): Use log-edit-extract-headers.
+	(vc-bzr-conflicted-files): New function.
+
+	* log-edit.el (log-edit-summary, log-edit-header)
+	(log-edit-unknown-header): New faces.
+	(log-edit-headers-alist): New var.
+	(log-edit-header-contents-regexp): New const.
+	(log-edit-match-to-eoh): New function.
+	(log-edit-font-lock-keywords): Use them.
+	(log-edit): Insert a "Summary:" header as default.
+	(log-edit-mode): Mark font-lock rules as case-insensitive.
+	(log-edit-done): Cleanup headers.
+	(log-edit-extract-headers): New function to replace it.
+
+	* vc-dispatcher.el (vc-finish-logentry): Don't mess so badly with
+	the windows/frames.
+
+	* vc-bzr.el (vc-bzr-shelve-apply): Don't use *vc-bzr-shelve*.
+
+	* vc-dir.el (vc-dir-kill-line): New command.
+	(vc-dir-mode-map): Bind it to C-k.
+	(vc-dir-headers): Abbreviate the working dir.
+
+	* vc-git.el (vc-git-revision-table): Include remote branches.
+
+2010-10-31  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	New VC methods: vc-log-incoming and vc-log-outgoing.
+	* vc.el (vc-print-log-setup-buttons, vc-log-internal-common)
+	(vc-incoming-outgoing-internal, vc-log-incoming, vc-log-outgoing):
+	New functions.
+	(vc-print-log-internal): Just call vc-log-internal-common.
+	(vc-log-view-type): New permanent local variable.
+
+	* vc-hooks.el (vc-menu-map): Bind vc-log-incoming and vc-log-outgoing.
+
+	* vc-bzr.el (vc-bzr-log-view-mode): Use vc-log-view-type instead
+	of the dynamic bound vc-short-log.
+	(vc-bzr-log-incoming, vc-bzr-log-outgoing): New functions.
+
+	* vc-git.el (vc-git-log-outgoing): New function.
+	(vc-git-log-view-mode): Use vc-log-view-type instead
+	of the dynamic bound vc-short-log.
+
+	* vc-hg.el (vc-hg-log-view-mode): Use vc-log-view-type instead of
+	the dynamic bound vc-short-log.  Highlight the tag.
+	(vc-hg-log-incoming, vc-hg-log-outgoing): New functions.
+	(vc-hg-outgoing, vc-hg-incoming, vc-hg-outgoing-mode):
+	(vc-hg-incoming-mode): Remove.
+	(vc-hg-extra-menu-map): Do not bind vc-hg-incoming and vc-hg-outgoing.
+
+	Fix default-directory for vc-root-diff.
+	* vc.el (vc-root-diff): Bind default-directory to the root
+	directory for the diff command.
+
+2010-10-31  Sam Steingold  <sds@gnu.org>
+
+	* vc-hg.el (vc-hg-push, vc-hg-pull): Use `apply' when calling
+	`vc-hg-command' with a list of flags.
+
+2010-10-31  Glenn Morris  <rgm@gnu.org>
+
+	* vc-bzr.el (vc-bzr-log-edit-mode): Add --fixes support to
+	log-edit-before-checkin-process.
+
+	* vc.el (vc-modify-change-comment): Pass MODE to vc-start-logentry.
+
+	* vc-bzr.el, vc-hg.el (log-edit-mode): Declare.
+
+	* vc-dispatcher.el (vc-start-logentry): Doc fix.
+	(log-view-process-buffer, log-edit-extra-flags): Declare.
+
+2010-10-31  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	Add special markup processing for commit logs.
+	* log-edit.el (log-edit): Add new argument MODE.  Use that mode
+	when non-nil instead of the log-view-mode.
+
+	* vc.el (vc-default-log-edit-mode): New function.
+
+	* vc-dispatcher.el (vc-log-edit): Add a mode argument, pass it to
+	log-edit.
+
+	Support for shelving snapshots and for showing shelves.
+	* vc-bzr.el (vc-bzr-shelve-show, vc-bzr-shelve-show-at-point)
+	(vc-bzr-shelve-apply-and-keep-at-point, vc-bzr-shelve-snapshot):
+	New functions.
+	(vc-bzr-shelve-map, vc-bzr-shelve-menu-map)
+	(vc-bzr-extra-menu-map): Map them.
+
 2010-10-30  Michael Albinus  <michael.albinus@gmx.de>
 
 	* net/tramp.el (tramp-handle-insert-file-contents): For root,
--- a/lisp/diff-mode.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/diff-mode.el	Sun Oct 31 23:13:42 2010 -0400
@@ -97,6 +97,9 @@
   :options '(diff-delete-empty-files diff-make-unified)
   :group 'diff-mode)
 
+(defvar diff-vc-backend nil
+  "The VC backend that created the current Diff buffer, if any.")
+
 (defvar diff-outline-regexp
   "\\([*+][*+][*+] [^0-9]\\|@@ ...\\|\\*\\*\\* [0-9].\\|--- [0-9]..\\)")
 
@@ -138,6 +141,7 @@
     ;; Standard M-r is useful, so don't change M-r or M-R.
     ;;("r" . diff-restrict-view)
     ;;("R" . diff-reverse-direction)
+    ("g" . revert-buffer)
     ("q" . quit-window))
   "Basic keymap for `diff-mode', bound to various prefix keys.")
 
--- a/lisp/log-edit.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/log-edit.el	Sun Oct 31 23:13:42 2010 -0400
@@ -125,6 +125,7 @@
   :type 'boolean)
 
 (defcustom log-edit-hook '(log-edit-insert-cvs-template
+                           log-edit-show-files
 			   log-edit-insert-changelog)
   "Hook run at the end of `log-edit'."
   :group 'log-edit
@@ -188,6 +189,7 @@
 (defvar log-edit-callback nil)
 (defvar log-edit-diff-function nil)
 (defvar log-edit-listfun nil)
+
 (defvar log-edit-parent-buffer nil)
 
 ;;; Originally taken from VC-Log mode
@@ -312,15 +314,59 @@
 ;;; Actual code
 ;;;
 
+(defface log-edit-summary '((t :inherit font-lock-function-name-face))
+  "Face for the summary in `log-edit-mode' buffers.")
+
+(defface log-edit-header '((t :inherit font-lock-keyword-face))
+  "Face for the headers in `log-edit-mode' buffers.")
+
+(defface log-edit-unknown-header '((t :inherit font-lock-comment-face))
+  "Face for unknown headers in `log-edit-mode' buffers.")
+
+(defvar log-edit-headers-alist '(("Summary" . log-edit-summary)
+                                 ("Fixes") ("Author"))
+  "AList of known headers and the face to use to highlight them.")
+
+(defconst log-edit-header-contents-regexp
+  "[ \t]*\\(.*\\(\n[ \t].*\\)*\\)\n?")
+
+(defun log-edit-match-to-eoh (limit)
+  ;; FIXME: copied from message-match-to-eoh.
+  (let ((start (point)))
+    (rfc822-goto-eoh)
+    ;; Typical situation: some temporary change causes the header to be
+    ;; incorrect, so EOH comes earlier than intended: the last lines of the
+    ;; intended headers are now not considered part of the header any more,
+    ;; so they don't have the multiline property set.  When the change is
+    ;; completed and the header has its correct shape again, the lack of the
+    ;; multiline property means we won't rehighlight the last lines of
+    ;; the header.
+    (if (< (point) start)
+        nil                             ;No header within start..limit.
+      ;; Here we disregard LIMIT so that we may extend the area again.
+      (set-match-data (list start (point)))
+      (point))))
+
 (defvar log-edit-font-lock-keywords
-  '(("\\`\\(Summary:\\)\\(.*\\)"
-     (1 font-lock-keyword-face)
-     (2 font-lock-function-name-face))))
+  ;; Copied/inspired by message-font-lock-keywords.
+  `((log-edit-match-to-eoh
+     (,(concat "^\\(\\([a-z]+\\):\\)" log-edit-header-contents-regexp
+               "\\|\\(.*\\)")
+      (progn (goto-char (match-beginning 0)) (match-end 0)) nil
+      (1 (if (assoc (match-string 2) log-edit-headers-alist)
+             'log-edit-header
+           'log-edit-unknown-header)
+         nil lax)
+      (3 (or (cdr (assoc (match-string 2) log-edit-headers-alist))
+             'log-edit-header)
+         nil lax)
+      (4 font-lock-warning-face)))))
 
 ;;;###autoload
-(defun log-edit (callback &optional setup params buffer &rest ignore)
+(defun log-edit (callback &optional setup params buffer mode &rest ignore)
   "Setup a buffer to enter a log message.
-\\<log-edit-mode-map>The buffer will be put in `log-edit-mode'.
+\\<log-edit-mode-map>The buffer will be put in mode MODE or `log-edit-mode'
+if MODE is nil.
 If SETUP is non-nil, the buffer is then erased and `log-edit-hook' is run.
 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].
@@ -340,8 +386,13 @@
     (if buffer (pop-to-buffer buffer))
     (when (and log-edit-setup-invert (not (eq setup 'force)))
       (setq setup (not setup)))
-    (when setup (erase-buffer))
-    (log-edit-mode)
+    (when setup
+      (erase-buffer)
+      (insert "Summary: ")
+      (save-excursion (insert "\n\n")))
+    (if mode
+	(funcall mode)
+      (log-edit-mode))
     (set (make-local-variable 'log-edit-callback) callback)
     (if (listp params)
 	(dolist (crt params)
@@ -367,7 +418,7 @@
 
 \\{log-edit-mode-map}"
   (set (make-local-variable 'font-lock-defaults)
-       '(log-edit-font-lock-keywords t))
+       '(log-edit-font-lock-keywords t t))
   (make-local-variable 'log-edit-comment-ring-index))
 
 (defun log-edit-hide-buf (&optional buf where)
@@ -380,6 +431,17 @@
   "Finish editing the log message and commit the files.
 If you want to abort the commit, simply delete the buffer."
   (interactive)
+  ;; Clean up empty headers.
+  (goto-char (point-min))
+  (while (looking-at (concat "^[a-z]*:" log-edit-header-contents-regexp))
+    (let ((beg (match-beginning 0)))
+      (goto-char (match-end 0))
+      (if (string-match "\\`[ \n\t]*\\'" (match-string 1))
+          (delete-region beg (point)))))
+  ;; Get rid of leading empty lines.
+  (goto-char (point-min))
+  (when (looking-at "\\([ \t]*\n\\)+")
+    (delete-region (match-beginning 0) (match-end 0)))
   ;; Get rid of trailing empty lines
   (goto-char (point-max))
   (skip-syntax-backward " ")
@@ -437,12 +499,13 @@
   "(Un)Indent the current buffer rigidly to `log-edit-common-indent'."
   (save-excursion
     (let ((common (point-max)))
-      (goto-char (point-min))
+      (rfc822-goto-eoh)
       (while (< (point) (point-max))
         (if (not (looking-at "^[ \t]*$"))
             (setq common (min common (current-indentation))))
         (forward-line 1))
-      (indent-rigidly (point-min) (point-max)
+      (rfc822-goto-eoh)
+      (indent-rigidly (point) (point-max)
 		      (- log-edit-common-indent common)))))
 
 (defun log-edit-show-diff ()
@@ -508,6 +571,16 @@
 	(log-edit-comment-to-change-log)))))
 
 (defvar log-edit-changelog-use-first nil)
+
+(defvar log-edit-rewrite-fixes nil
+  "Rule to rewrite bug numbers into Fixes: headers.
+The value should be of the form (REGEXP . REPLACEMENT)
+where REGEXP should match the expression referring to a bug number
+in the text, and REPLACEMENT is an expression to pass to `replace-match'
+to build the Fixes: header.")
+(put 'log-edit-rewrite-fixes 'safe-local-variable
+     (lambda (v) (and (stringp (car-safe v)) (stringp (cdr v)))))
+
 (defun log-edit-insert-changelog (&optional use-first)
   "Insert a log message by looking at the ChangeLog.
 The idea is to write your ChangeLog entries first, and then use this
@@ -525,18 +598,38 @@
 or if the command is repeated a second time in a row, use the first log entry
 regardless of user name or time."
   (interactive "P")
-  (let ((log-edit-changelog-use-first
-	 (or use-first (eq last-command 'log-edit-insert-changelog))))
-    (log-edit-insert-changelog-entries (log-edit-files)))
-  (log-edit-set-common-indentation)
-  (goto-char (point-min))
-  (when (and log-edit-strip-single-file-name (looking-at "\\*\\s-+"))
-    (forward-line 1)
-    (when (not (re-search-forward "^\\*\\s-+" nil t))
-      (goto-char (point-min))
-      (skip-chars-forward "^():")
-      (skip-chars-forward ": ")
-      (delete-region (point-min) (point)))))
+  (let ((eoh (save-excursion (rfc822-goto-eoh) (point))))
+    (when (<= (point) eoh)
+      (goto-char eoh)
+      (if (looking-at "\n") (forward-char 1))))
+  (let ((author
+         (let ((log-edit-changelog-use-first
+                (or use-first (eq last-command 'log-edit-insert-changelog))))
+           (log-edit-insert-changelog-entries (log-edit-files)))))
+    (log-edit-set-common-indentation)
+    ;; Add an Author: field if appropriate.
+    (when author
+      (rfc822-goto-eoh)
+      (insert "Author: " author "\n" (if (looking-at "\n") "" "\n")))
+    ;; Add a Fixes: field if applicable.
+    (when (consp log-edit-rewrite-fixes)
+      (rfc822-goto-eoh)
+      (when (re-search-forward (car log-edit-rewrite-fixes) nil t)
+        (let ((start (match-beginning 0))
+              (end (match-end 0))
+              (fixes (match-substitute-replacement
+                      (cdr log-edit-rewrite-fixes))))
+          (delete-region start end)
+          (rfc822-goto-eoh)
+          (insert "Fixes: " fixes "\n" (if (looking-at "\n") "" "\n")))))
+    (goto-char (point-min))
+    (when (and log-edit-strip-single-file-name (looking-at "\\*\\s-+"))
+      (forward-line 1)
+      (when (not (re-search-forward "^\\*\\s-+" nil t))
+        (goto-char (point-min))
+        (skip-chars-forward "^():")
+        (skip-chars-forward ": ")
+        (delete-region (point-min) (point))))))
 
 ;;;;
 ;;;; functions for getting commit message from ChangeLog a file...
@@ -602,6 +695,9 @@
 
 (defvar user-full-name)
 (defvar user-mail-address)
+
+(defvar log-edit-author)                ;Dynamically scoped.
+
 (defun log-edit-changelog-ours-p ()
   "See if ChangeLog entry at point is for the current user, today.
 Return non-nil if it is."
@@ -616,14 +712,28 @@
 		       (functionp add-log-time-format)
 		       (funcall add-log-time-format))
 		  (format-time-string "%Y-%m-%d"))))
-    (looking-at (if log-edit-changelog-use-first
-                    "[^ \t]"
-                  (regexp-quote (format "%s  %s  <%s>" time name mail))))))
+    (if (null log-edit-changelog-use-first)
+        (looking-at (regexp-quote (format "%s  %s  <%s>" time name mail)))
+      ;; Check the author, to potentially add it as a "Author: " header.
+      (when (looking-at "[^ \t]")
+        (when (and (boundp 'log-edit-author)
+                   (not (looking-at (format ".+  .+  <%s>"
+                                            (regexp-quote mail))))
+                   (looking-at ".+  \\(.+  <.+>\\)"))
+          (let ((author (replace-regexp-in-string "  " " "
+                                                  (match-string 1))))
+            (unless (and log-edit-author
+                         (string-match (regexp-quote author) log-edit-author))
+              (setq log-edit-author
+                    (if log-edit-author
+                        (concat log-edit-author ", " author)
+                      author)))))
+        t))))
 
 (defun log-edit-changelog-entries (file)
   "Return the ChangeLog entries for FILE, and the ChangeLog they came from.
 The return value looks like this:
-  (LOGBUFFER (ENTRYSTART . ENTRYEND) ...)
+  (LOGBUFFER (ENTRYSTART ENTRYEND) ...)
 where LOGBUFFER is the name of the ChangeLog buffer, and each
 \(ENTRYSTART . ENTRYEND\) pair is a buffer region."
   (let ((changelog-file-name
@@ -681,34 +791,87 @@
 
 	      (cons (current-buffer) texts))))))))
 
-(defun log-edit-changelog-insert-entries (buffer regions)
-  "Insert those regions in BUFFER specified in REGIONS.
-Sort REGIONS front-to-back first."
-  (let ((regions (sort regions 'car-less-than-car))
-        (last))
-    (dolist (region regions)
-      (when (and last (< last (car region))) (newline))
-      (setq last (elt region 1))
-      (apply 'insert-buffer-substring buffer region))))
+(defun log-edit-changelog-insert-entries (buffer beg end &rest files)
+  "Insert the text from BUFFER between BEG and END.
+Rename relative filenames in the ChangeLog entry as FILES."
+  (let ((opoint (point))
+	(log-name (buffer-file-name buffer))
+	(case-fold-search nil)
+	bound)
+    (insert-buffer-substring buffer beg end)
+    (setq bound (point-marker))
+    (when log-name
+      (dolist (f files)
+	(save-excursion
+	  (goto-char opoint)
+	  (when (re-search-forward
+		 (concat "\\(^\\|[ \t]\\)\\("
+			 (file-relative-name f (file-name-directory log-name))
+			 "\\)[, :\n]")
+		 bound t)
+	    (replace-match f t t nil 2)))))
+    ;; Eliminate tabs at the beginning of the line.
+    (save-excursion
+      (goto-char opoint)
+      (while (re-search-forward "^\\(\t+\\)" bound t)
+	(replace-match "")))))
 
 (defun log-edit-insert-changelog-entries (files)
   "Given a list of files FILES, insert the ChangeLog entries for them."
-  (let ((buffer-entries nil))
-
-    ;; Add each buffer to buffer-entries, and associate it with the list
-    ;; of entries we want from that file.
+  (let ((log-entries nil)
+        (log-edit-author nil))
+    ;; Note that any ChangeLog entry can apply to more than one file.
+    ;; Here we construct a log-entries list with elements of the form
+    ;;   ((LOGBUFFER ENTRYSTART ENTRYEND) FILE1 FILE2...)
     (dolist (file files)
       (let* ((entries (log-edit-changelog-entries file))
-             (pair (assq (car entries) buffer-entries)))
-        (if pair
-            (setcdr pair (cvs-union (cdr pair) (cdr entries)))
-          (push entries buffer-entries))))
+	     (buf (car entries))
+	     key entry)
+	(dolist (region (cdr entries))
+	  (setq key (cons buf region))
+	  (if (setq entry (assoc key log-entries))
+	      (setcdr entry (append (cdr entry) (list file)))
+	    (push (list key file) log-entries)))))
+    ;; Now map over log-entries, and extract the strings.
+    (dolist (log-entry (nreverse log-entries))
+      (apply 'log-edit-changelog-insert-entries
+	     (append (car log-entry) (cdr log-entry)))
+      (insert "\n"))
+    log-edit-author))
 
-    ;; Now map over each buffer in buffer-entries, sort the entries for
-    ;; each buffer, and extract them as strings.
-    (dolist (buffer-entry buffer-entries)
-      (log-edit-changelog-insert-entries (car buffer-entry) (cdr buffer-entry))
-      (when (cdr buffer-entry) (newline)))))
+(defun log-edit-extract-headers (headers comment)
+  "Extract headers from COMMENT to form command line arguments.
+HEADERS should be an alist with elements of the form (HEADER . CMDARG)
+associating header names to the corresponding cmdline option name and the
+result is then a list of the form (MSG CMDARG1 HDRTEXT1 CMDARG2 HDRTEXT2...).
+where MSG is the remaining text from STRING.
+If \"Summary\" is not in HEADERS, then the \"Summary\" header is extracted
+anyway and put back as the first line of MSG."
+  (with-temp-buffer
+    (insert comment)
+    (rfc822-goto-eoh)
+    (narrow-to-region (point-min) (point))
+    (let ((case-fold-search t)
+          (summary ())
+          (res ()))
+      (dolist (header (if (assoc "Summary" headers) headers
+                        (cons '("Summary" . t) headers)))
+        (goto-char (point-min))
+        (while (re-search-forward (concat "^" (car header)
+                                          ":" log-edit-header-contents-regexp)
+                                  nil t)
+          (if (eq t (cdr header))
+              (setq summary (match-string 1))
+            (push (match-string 1) res)
+            (push (or (cdr header) (car header)) res))
+          (replace-match "" t t)))
+      ;; Remove header separator if the header is empty.
+      (widen)
+      (goto-char (point-min))
+      (when (looking-at "\\([ \t]*\n\\)+")
+        (delete-region (match-beginning 0) (match-end 0)))
+      (if summary (insert summary "\n"))
+      (cons (buffer-string) res))))
 
 (provide 'log-edit)
 
--- a/lisp/log-view.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/log-view.el	Sun Oct 31 23:13:42 2010 -0400
@@ -128,6 +128,7 @@
 (easy-mmode-defmap log-view-mode-map
   '(("z" . kill-this-buffer)
     ("q" . quit-window)
+    ("g" . revert-buffer)
     ("m" . log-view-toggle-mark-entry)
     ("e" . log-view-modify-change-comment)
     ("d" . log-view-diff)
--- a/lisp/vc-arch.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-arch.el	Sun Oct 31 23:13:42 2010 -0400
@@ -254,8 +254,7 @@
 	       (buffer-substring (point-min) (1- (point-max)))))))))
 
 (defun vc-arch-workfile-unchanged-p (file)
-  "Check if FILE is unchanged by diffing against the master version.
-Return non-nil if FILE is unchanged."
+  "Stub: arch workfiles are always considered to be in a changed state,"
   nil)
 
 (defun vc-arch-state (file)
--- a/lisp/vc-bzr.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-bzr.el	Sun Oct 31 23:13:42 2010 -0400
@@ -451,11 +451,17 @@
   "Unregister FILE from bzr."
   (vc-bzr-command "remove" nil 0 file "--keep"))
 
+(declare-function log-edit-extract-headers "log-edit" (headers string))
+
 (defun vc-bzr-checkin (files rev comment)
   "Check FILE in to bzr with log message COMMENT.
 REV non-nil gets an error."
   (if rev (error "Can't check in a specific revision with bzr"))
-  (vc-bzr-command "commit" nil 0 files "-m" comment))
+  (apply 'vc-bzr-command "commit" nil 0
+         files (cons "-m" (log-edit-extract-headers '(("Author" . "--author")
+						      ("Date" . "--commit-time")
+                                                      ("Fixes" . "--fixes"))
+                                                    comment))))
 
 (defun vc-bzr-find-revision (file rev buffer)
   "Fetch revision REV of file FILE and put it into BUFFER."
@@ -478,7 +484,6 @@
 (defvar log-view-font-lock-keywords)
 (defvar log-view-current-tag-function)
 (defvar log-view-per-file-logs)
-(defvar vc-short-log)
 
 (define-derived-mode vc-bzr-log-view-mode log-view-mode "Bzr-Log-View"
   (remove-hook 'log-view-mode-hook 'vc-bzr-log-view-mode) ;Deactivate the hack.
@@ -486,13 +491,13 @@
   (set (make-local-variable 'log-view-per-file-logs) nil)
   (set (make-local-variable 'log-view-file-re) "\\`a\\`")
   (set (make-local-variable 'log-view-message-re)
-       (if vc-short-log
+       (if (eq vc-log-view-type 'short)
 	   "^ *\\([0-9.]+\\): \\(.*?\\)[ \t]+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)\\( \\[merge\\]\\)?"
 	 "^ *\\(?:revno: \\([0-9.]+\\)\\|merged: .+\\)"))
   (set (make-local-variable 'log-view-font-lock-keywords)
        ;; log-view-font-lock-keywords is careful to use the buffer-local
        ;; value of log-view-message-re only since Emacs-23.
-       (if vc-short-log
+       (if (eq vc-log-view-type 'short)
 	 (append `((,log-view-message-re
 		    (1 'log-view-message-face)
 		    (2 'change-log-name)
@@ -526,6 +531,14 @@
 		(list vc-bzr-log-switches)
 	      vc-bzr-log-switches)))))
 
+(defun vc-bzr-log-incoming (buffer remote-location)
+  (apply 'vc-bzr-command "missing" buffer 'async nil
+	 (list "--theirs-only" (unless (string= remote-location "") remote-location))))
+
+(defun vc-bzr-log-outgoing (buffer remote-location)
+  (apply 'vc-bzr-command "missing" buffer 'async nil
+	 (list "--mine-only" (unless (string= remote-location "") remote-location))))
+
 (defun vc-bzr-show-log-entry (revision)
   "Find entry for patch name REVISION in bzr change log buffer."
   (goto-char (point-min))
@@ -758,9 +771,11 @@
 
     (define-key map [down-mouse-3] 'vc-bzr-shelve-menu)
     (define-key map "\C-k" 'vc-bzr-shelve-delete-at-point)
-    ;; (define-key map "=" 'vc-bzr-shelve-show-at-point)
-    ;; (define-key map "\C-m" 'vc-bzr-shelve-show-at-point)
+    (define-key map "=" 'vc-bzr-shelve-show-at-point)
+    (define-key map "\C-m" 'vc-bzr-shelve-show-at-point)
+    (define-key map "A" 'vc-bzr-shelve-apply-and-keep-at-point)
     (define-key map "P" 'vc-bzr-shelve-apply-at-point)
+    (define-key map "S" 'vc-bzr-shelve-snapshot)
     map))
 
 (defvar vc-bzr-shelve-menu-map
@@ -768,16 +783,22 @@
     (define-key map [de]
       '(menu-item "Delete shelf" vc-bzr-shelve-delete-at-point
 		  :help "Delete the current shelf"))
+    (define-key map [ap]
+      '(menu-item "Apply and keep shelf" vc-bzr-shelve-apply-and-keep-at-point
+		  :help "Apply the current shelf and keep it"))
     (define-key map [po]
       '(menu-item "Apply and remove shelf (pop)" vc-bzr-shelve-apply-at-point
 		  :help "Apply the current shelf and remove it"))
-    ;; (define-key map [sh]
-    ;;   '(menu-item "Show shelve" vc-bzr-shelve-show-at-point
-    ;; 		  :help "Show the contents of the current shelve"))
+    (define-key map [sh]
+      '(menu-item "Show shelve" vc-bzr-shelve-show-at-point
+    		  :help "Show the contents of the current shelve"))
     map))
 
 (defvar vc-bzr-extra-menu-map
   (let ((map (make-sparse-keymap)))
+    (define-key map [bzr-sn]
+      '(menu-item "Shelve a snapshot" vc-bzr-shelve-snapshot
+		  :help "Shelve the current state of the tree and keep the current state"))
     (define-key map [bzr-sh]
       '(menu-item "Shelve..." vc-bzr-shelve
 		  :help "Shelve changes"))
@@ -864,21 +885,38 @@
       (vc-bzr-command "shelve" nil 0 nil "--all" "-m" name)
       (vc-resynch-buffer root t t))))
 
-;; (defun vc-bzr-shelve-show (name)
-;;   "Show the contents of shelve NAME."
-;;   (interactive "sShelve name: ")
-;;   (vc-setup-buffer "*vc-bzr-shelve*")
-;;   ;; FIXME: how can you show the contents of a shelf?
-;;   (vc-bzr-command "shelve" "*vc-bzr-shelve*" 'async nil name)
-;;   (set-buffer "*vc-bzr-shelve*")
-;;   (diff-mode)
-;;   (setq buffer-read-only t)
-;;   (pop-to-buffer (current-buffer)))
+(defun vc-bzr-shelve-show (name)
+  "Show the contents of shelve NAME."
+  (interactive "sShelve name: ")
+  (vc-setup-buffer "*vc-diff*")
+  ;; FIXME: how can you show the contents of a shelf?
+  (vc-bzr-command "unshelve" "*vc-diff*" 'async nil "--preview" name)
+  (set-buffer "*vc-diff*")
+  (diff-mode)
+  (setq buffer-read-only t)
+  (pop-to-buffer (current-buffer)))
 
 (defun vc-bzr-shelve-apply (name)
   "Apply shelve NAME and remove it afterwards."
   (interactive "sApply (and remove) shelf: ")
-  (vc-bzr-command "unshelve" "*vc-bzr-shelve*" 0 nil "--apply" name)
+  (vc-bzr-command "unshelve" nil 0 nil "--apply" name)
+  (vc-resynch-buffer (vc-bzr-root default-directory) t t))
+
+(defun vc-bzr-shelve-apply-and-keep (name)
+  "Apply shelve NAME and keep it afterwards."
+  (interactive "sApply (and keep) shelf: ")
+  (vc-bzr-command "unshelve" nil 0 nil "--apply" "--keep" name)
+  (vc-resynch-buffer (vc-bzr-root default-directory) t t))
+
+(defun vc-bzr-shelve-snapshot ()
+  "Create a stash with the current tree state."
+  (interactive)
+  (vc-bzr-command "shelve" nil 0 nil "--all" "-m"
+		  (let ((ct (current-time)))
+		    (concat
+		     (format-time-string "Snapshot on %Y-%m-%d" ct)
+		     (format-time-string " at %H:%M" ct))))
+  (vc-bzr-command "unshelve" nil 0 nil "--apply" "--keep")
   (vc-resynch-buffer (vc-bzr-root default-directory) t t))
 
 (defun vc-bzr-shelve-list ()
@@ -905,14 +943,18 @@
       (vc-bzr-command "unshelve" nil 0 nil "--delete-only" shelve)
       (vc-dir-refresh))))
 
-;; (defun vc-bzr-shelve-show-at-point ()
-;;   (interactive)
-;;   (vc-bzr-shelve-show (vc-bzr-shelve-get-at-point (point))))
+(defun vc-bzr-shelve-show-at-point ()
+  (interactive)
+  (vc-bzr-shelve-show (vc-bzr-shelve-get-at-point (point))))
 
 (defun vc-bzr-shelve-apply-at-point ()
   (interactive)
   (vc-bzr-shelve-apply (vc-bzr-shelve-get-at-point (point))))
 
+(defun vc-bzr-shelve-apply-and-keep-at-point ()
+  (interactive)
+  (vc-bzr-shelve-apply-and-keep (vc-bzr-shelve-get-at-point (point))))
+
 (defun vc-bzr-shelve-menu (e)
   (interactive "e")
   (vc-dir-at-event e (popup-menu vc-bzr-shelve-menu-map e)))
@@ -930,6 +972,19 @@
           (setq loglines (buffer-substring-no-properties start (point-max))))))
     vc-bzr-revisions))
 
+(defun vc-bzr-conflicted-files (dir)
+  (let ((default-directory (vc-bzr-root dir))
+        (files ()))
+    (with-temp-buffer
+      (vc-bzr-command "status" t 0 default-directory)
+      (goto-char (point-min))
+      (when (re-search-forward "^conflicts:\n" nil t)
+        (while (looking-at "  \\(?:Text conflict in \\(.*\\)\\|.*\\)\n")
+          (if (match-end 1)
+              (push (expand-file-name (match-string 1)) files))
+          (goto-char (match-end 0)))))
+    files))
+
 ;;; Revision completion
 
 (eval-and-compile
--- a/lisp/vc-dir.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-dir.el	Sun Oct 31 23:13:42 2010 -0400
@@ -188,9 +188,18 @@
     (define-key map [diff]
       '(menu-item "Compare with Base Version" vc-diff
 		  :help "Compare file set with the base version"))
+    (define-key map [logo]
+      '(menu-item "Show Outgoing Log" vc-log-outgoing
+		  :help "Show a log of changes that will be sent with a push operation"))
+    (define-key map [logi]
+      '(menu-item "Show Incoming Log" vc-log-incoming
+		  :help "Show a log of changes that will be received with a pull operation"))
     (define-key map [log]
-     '(menu-item "Show history" vc-print-log
-     :help "List the change log of the current file set in a window"))
+      '(menu-item "Show history" vc-print-log
+		  :help "List the change log of the current file set in a window"))
+    (define-key map [rlog]
+      '(menu-item "Show Top of the Tree History " vc-print-root-log
+		  :help "List the change log for the current tree in a window"))
     ;; VC commands.
     (define-key map [sepvccmd] '("--"))
     (define-key map [update]
@@ -263,6 +272,7 @@
     (define-key map [mouse-2] 'vc-dir-toggle-mark)
     (define-key map [follow-link] 'mouse-face)
     (define-key map "x" 'vc-dir-hide-up-to-date)
+    (define-key map [?\C-k] 'vc-dir-kill-line)
     (define-key map "S" 'vc-dir-search) ;; FIXME: Maybe use A like dired?
     (define-key map "Q" 'vc-dir-query-replace-regexp)
     (define-key map (kbd "M-s a C-s")   'vc-dir-isearch)
@@ -963,7 +973,8 @@
    (propertize "VC backend : " 'face 'font-lock-type-face)
    (propertize (format "%s\n" backend) 'face 'font-lock-variable-name-face)
    (propertize "Working dir: " 'face 'font-lock-type-face)
-   (propertize (format "%s\n" dir) 'face 'font-lock-variable-name-face)
+   (propertize (format "%s\n" (abbreviate-file-name dir))
+               'face 'font-lock-variable-name-face)
    ;; Then the backend specific ones.
    (vc-call-backend backend 'dir-extra-headers dir)
    "\n"))
@@ -1100,6 +1111,13 @@
 	    (ewoc-delete vc-ewoc crt))
 	  (setq crt prev)))))
 
+(defun vc-dir-kill-line ()
+  "Remove the current line from display."
+  (interactive)
+  (let ((crt (ewoc-locate vc-ewoc))
+        (inhibit-read-only t))
+    (ewoc-delete vc-ewoc crt)))
+
 (defun vc-dir-printer (fileentry)
   (vc-call-backend vc-dir-backend 'dir-printer fileentry))
 
@@ -1169,7 +1187,8 @@
 	  nil t nil nil)))))
   (unless backend
     (setq backend (vc-responsible-backend dir)))
-  (pop-to-buffer (vc-dir-prepare-status-buffer "*vc-dir*" dir backend))
+  (let (pop-up-windows)		      ; based on cvs-examine; bug#6204
+    (pop-to-buffer (vc-dir-prepare-status-buffer "*vc-dir*" dir backend)))
   (if (derived-mode-p 'vc-dir-mode)
       (vc-dir-refresh)
     ;; FIXME: find a better way to pass the backend to `vc-dir-mode'.
--- a/lisp/vc-dispatcher.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-dispatcher.el	Sun Oct 31 23:13:42 2010 -0400
@@ -141,7 +141,6 @@
 (defvar vc-log-operation nil)
 (defvar vc-log-after-operation-hook nil)
 (defvar vc-log-fileset)
-(defvar vc-log-extra)
 
 ;; In a log entry buffer, this is a local variable
 ;; that points to the buffer for which it was made
@@ -458,7 +457,7 @@
 (make-variable-buffer-local 'vc-mode-line-hook)
 (put 'vc-mode-line-hook 'permanent-local t)
 
-(defun vc-resynch-window (file &optional keep noquery)
+(defun vc-resynch-window (file &optional keep noquery reset-vc-info)
   "If FILE is in the current buffer, either revert or unvisit it.
 The choice between revert (to see expanded keywords) and unvisit
 depends on KEEP.  NOQUERY if non-nil inhibits confirmation for
@@ -469,6 +468,8 @@
   (and (string= buffer-file-name file)
        (if keep
 	   (when (file-exists-p file)
+	     (when reset-vc-info
+	       (vc-file-clearprops file))
 	     (vc-revert-buffer-internal t noquery)
 
 	     ;; VC operations might toggle the read-only state.  In
@@ -490,24 +491,24 @@
 (declare-function vc-dir-resynch-file "vc-dir" (&optional fname))
 (declare-function vc-string-prefix-p "vc" (prefix string))
 
-(defun vc-resynch-buffers-in-directory (directory &optional keep noquery)
+(defun vc-resynch-buffers-in-directory (directory &optional keep noquery reset-vc-info)
   "Resync all buffers that visit files in DIRECTORY."
   (dolist (buffer (buffer-list))
     (let ((fname (buffer-file-name buffer)))
       (when (and fname (vc-string-prefix-p directory fname))
 	(with-current-buffer buffer
-	  (vc-resynch-buffer fname keep noquery))))))
+	  (vc-resynch-buffer fname keep noquery reset-vc-info))))))
 
-(defun vc-resynch-buffer (file &optional keep noquery)
+(defun vc-resynch-buffer (file &optional keep noquery reset-vc-info)
   "If FILE is currently visited, resynch its buffer."
   (if (string= buffer-file-name file)
-      (vc-resynch-window file keep noquery)
+      (vc-resynch-window file keep noquery reset-vc-info)
     (if (file-directory-p file)
-	(vc-resynch-buffers-in-directory file keep noquery)
+	(vc-resynch-buffers-in-directory file keep noquery reset-vc-info)
       (let ((buffer (get-file-buffer file)))
 	(when buffer
 	  (with-current-buffer buffer
-	    (vc-resynch-window file keep noquery))))))
+	    (vc-resynch-window file keep noquery reset-vc-info))))))
   ;; Try to avoid unnecessary work, a *vc-dir* buffer is only present
   ;; if this is true.
   (when vc-dir-buffers
@@ -527,21 +528,26 @@
 
 ;; Set up key bindings for use while editing log messages
 
-(defun vc-log-edit (fileset)
+(defun vc-log-edit (fileset mode)
   "Set up `log-edit' for use on FILE."
   (setq default-directory
 	(with-current-buffer vc-parent-buffer default-directory))
   (log-edit 'vc-finish-logentry
 	    nil
-	    `((log-edit-listfun . (lambda () ',fileset))
-	      (log-edit-diff-function . (lambda () (vc-diff nil)))))
+	    `((log-edit-listfun . (lambda ()
+                                    ;; FIXME: Should expand the list
+                                    ;; for directories.
+                                    (mapcar 'file-relative-name
+                                            ',fileset)))
+	      (log-edit-diff-function . (lambda () (vc-diff nil))))
+	    nil
+	    mode)
   (set (make-local-variable 'vc-log-fileset) fileset)
-  (make-local-variable 'vc-log-extra)
   (set-buffer-modified-p nil)
   (setq buffer-file-name nil))
 
-(defun vc-start-logentry (files extra comment initial-contents msg logbuf action &optional after-hook)
-  "Accept a comment for an operation on FILES with extra data EXTRA.
+(defun vc-start-logentry (files comment initial-contents msg logbuf mode action &optional after-hook)
+  "Accept a comment for an operation on FILES.
 If COMMENT is nil, pop up a LOGBUF buffer, emit MSG, and set the
 action on close to ACTION.  If COMMENT is a string and
 INITIAL-CONTENTS is non-nil, then COMMENT is used as the initial
@@ -549,8 +555,9 @@
 INITIAL-CONTENTS is nil, do action immediately as if the user had
 entered COMMENT.  If COMMENT is t, also do action immediately with an
 empty comment.  Remember the file's buffer in `vc-parent-buffer'
-\(current one if no file).  AFTER-HOOK specifies the local value
-for `vc-log-after-operation-hook'."
+\(current one if no file).  Puts the log-entry buffer in major-mode
+MODE, defaulting to `log-edit-mode' if MODE is nil.
+AFTER-HOOK specifies the local value for `vc-log-after-operation-hook'."
   (let ((parent
          (if (vc-dispatcher-browsing)
              ;; If we are called from a directory browser, the parent buffer is
@@ -565,12 +572,11 @@
     (set (make-local-variable 'vc-parent-buffer) parent)
     (set (make-local-variable 'vc-parent-buffer-name)
 	 (concat " from " (buffer-name vc-parent-buffer)))
-    (vc-log-edit files)
+    (vc-log-edit files mode)
     (make-local-variable 'vc-log-after-operation-hook)
     (when after-hook
       (setq vc-log-after-operation-hook after-hook))
     (setq vc-log-operation action)
-    (setq vc-log-extra extra)
     (when comment
       (erase-buffer)
       (when (stringp comment) (insert comment)))
@@ -579,7 +585,8 @@
       (vc-finish-logentry (eq comment t)))))
 
 (declare-function vc-dir-move-to-goal-column "vc-dir" ())
-
+;; vc-finish-logentry is typically called from a log-edit buffer (see
+;; vc-start-logentry).
 (defun vc-finish-logentry (&optional nocomment)
   "Complete the operation implied by the current log entry.
 Use the contents of the current buffer as a check-in or registration
@@ -595,20 +602,21 @@
     (or (vc-dispatcher-browsing) (vc-buffer-sync)))
   (unless vc-log-operation
     (error "No log operation is pending"))
+
   ;; save the parameters held in buffer-local variables
   (let ((logbuf (current-buffer))
 	(log-operation vc-log-operation)
+        ;; FIXME: When coming from VC-Dir, we should check that the
+        ;; set of selected files is still equal to vc-log-fileset,
+        ;; to avoid surprises.
 	(log-fileset vc-log-fileset)
-	(log-extra vc-log-extra)
 	(log-entry (buffer-string))
-	(after-hook vc-log-after-operation-hook)
-	(tmp-vc-parent-buffer vc-parent-buffer))
+	(after-hook vc-log-after-operation-hook))
     (pop-to-buffer vc-parent-buffer)
     ;; OK, do it to it
     (save-excursion
       (funcall log-operation
 	       log-fileset
-	       log-extra
 	       log-entry))
     ;; Remove checkin window (after the checkin so that if that fails
     ;; we don't zap the log buffer and the typing therein).
@@ -617,9 +625,11 @@
 	   (delete-windows-on logbuf (selected-frame))
 	   ;; Kill buffer and delete any other dedicated windows/frames.
 	   (kill-buffer logbuf))
-	  (logbuf (pop-to-buffer logbuf)
-		  (bury-buffer)
-		  (pop-to-buffer tmp-vc-parent-buffer)))
+	  (logbuf
+           (with-selected-window (or (get-buffer-window logbuf 0)
+                                     (selected-window))
+             (with-current-buffer logbuf
+               (bury-buffer)))))
     ;; Now make sure we see the expanded headers
     (when log-fileset
       (mapc
--- a/lisp/vc-git.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-git.el	Sun Oct 31 23:13:42 2010 -0400
@@ -118,7 +118,7 @@
   :version "23.1"
   :group 'vc)
 
-(defvar git-commits-coding-system 'utf-8
+(defvar vc-git-commits-coding-system 'utf-8
   "Default coding system for git commits.")
 
 ;;; BACKEND PROPERTIES
@@ -171,7 +171,14 @@
 
 (defun vc-git-state (file)
   "Git-specific version of `vc-state'."
-  ;; FIXME: This can't set 'ignored yet
+  ;; FIXME: This can't set 'ignored or 'conflict yet
+  ;; The 'ignored state could be detected with `git ls-files -i -o
+  ;; --exclude-standard` It also can't set 'needs-update or
+  ;; 'needs-merge. The rough equivalent would be that upstream branch
+  ;; for current branch is in fast-forward state i.e. current branch
+  ;; is direct ancestor of corresponding upstream branch, and the file
+  ;; was modified upstream.  But we can't check that without a network
+  ;; operation.
   (if (not (vc-git-registered file))
       'unregistered
     (vc-git--call nil "add" "--refresh" "--" (file-relative-name file))
@@ -541,11 +548,16 @@
 (defun vc-git-unregister (file)
   (vc-git-command nil 0 file "rm" "-f" "--cached" "--"))
 
+(declare-function log-edit-extract-headers "log-edit" (headers string))
 
 (defun vc-git-checkin (files rev comment)
-  (let ((coding-system-for-write git-commits-coding-system))
-    (vc-git-command nil 0 files "commit"
-		    "-m" comment "--only" "--")))
+  (let ((coding-system-for-write vc-git-commits-coding-system))
+    (apply 'vc-git-command nil 0 files
+	   (nconc (list "commit" "-m")
+                  (log-edit-extract-headers '(("Author" . "--author")
+					      ("Date" . "--date"))
+                                            comment)
+                  (list "--only" "--")))))
 
 (defun vc-git-find-revision (file rev buffer)
   (let* (process-file-side-effects
@@ -580,7 +592,7 @@
   "Get change log associated with FILES.
 Note that using SHORTLOG requires at least Git version 1.5.6,
 for the --graph option."
-  (let ((coding-system-for-read git-commits-coding-system))
+  (let ((coding-system-for-read vc-git-commits-coding-system))
     ;; `vc-do-command' creates the buffer, but we need it before running
     ;; the command.
     (vc-setup-buffer buffer)
@@ -600,25 +612,46 @@
 		(when start-revision (list start-revision))
 		'("--")))))))
 
+(defun vc-git-log-outgoing (buffer remote-location)
+  (interactive)
+  (vc-git-command
+   buffer 0 nil
+   "log"
+   "--no-color" "--graph" "--decorate" "--date=short"
+   "--pretty=tformat:%d%h  %ad  %s" "--abbrev-commit"
+   (concat (if (string= remote-location "")
+	       "@{upstream}"
+	     remote-location)
+	   "..HEAD")))
+
+(defun vc-git-log-incoming (buffer remote-location)
+  (interactive)
+  (vc-git-command nil 0 nil "fetch")
+  (vc-git-command
+   buffer 0 nil
+   "log"
+   "--no-color" "--graph" "--decorate" "--date=short"
+   "--pretty=tformat:%d%h  %ad  %s" "--abbrev-commit"
+   (concat "HEAD.." (if (string= remote-location "")
+			"@{upstream}"
+		      remote-location))))
+
 (defvar log-view-message-re)
 (defvar log-view-file-re)
 (defvar log-view-font-lock-keywords)
 (defvar log-view-per-file-logs)
 
-;; Dynamically bound.
-(defvar vc-short-log)
-
 (define-derived-mode vc-git-log-view-mode log-view-mode "Git-Log-View"
   (require 'add-log) ;; We need the faces add-log.
   ;; Don't have file markers, so use impossible regexp.
   (set (make-local-variable 'log-view-file-re) "\\`a\\`")
   (set (make-local-variable 'log-view-per-file-logs) nil)
   (set (make-local-variable 'log-view-message-re)
-       (if vc-short-log
+       (if (not (eq vc-log-view-type 'long))
 	   "^\\(?:[*/\\| ]+ \\)?\\(?: ([^)]+)\\)?\\([0-9a-z]+\\)  \\([-a-z0-9]+\\)  \\(.*\\)"
 	 "^commit *\\([0-9a-z]+\\)"))
   (set (make-local-variable 'log-view-font-lock-keywords)
-       (if vc-short-log
+       (if (not (eq vc-log-view-type 'long))
 	   '(
 	     ;; Same as log-view-message-re, except that we don't
 	     ;; want the shy group for the tag name.
@@ -681,7 +714,8 @@
     (with-temp-buffer
       (vc-git-command t nil nil "for-each-ref" "--format=%(refname)")
       (goto-char (point-min))
-      (while (re-search-forward "^refs/\\(heads\\|tags\\)/\\(.*\\)$" nil t)
+      (while (re-search-forward "^refs/\\(heads\\|tags\\|remotes\\)/\\(.*\\)$"
+                                nil t)
         (push (match-string 2) table)))
     table))
 
--- a/lisp/vc-hg.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-hg.el	Sun Oct 31 23:13:42 2010 -0400
@@ -256,33 +256,33 @@
     (with-current-buffer
 	buffer
       (apply 'vc-hg-command buffer 0 files "log"
-	     (append
+	     (nconc
 	      (when start-revision (list (format "-r%s:" start-revision)))
 	      (when limit (list "-l" (format "%s" limit)))
-	      (when shortlog '("--style" "compact"))
+	      (when shortlog (list "--style" "compact"))
 	      vc-hg-log-switches)))))
 
 (defvar log-view-message-re)
 (defvar log-view-file-re)
 (defvar log-view-font-lock-keywords)
 (defvar log-view-per-file-logs)
-(defvar vc-short-log)
 
 (define-derived-mode vc-hg-log-view-mode log-view-mode "Hg-Log-View"
   (require 'add-log) ;; we need the add-log faces
   (set (make-local-variable 'log-view-file-re) "\\`a\\`")
   (set (make-local-variable 'log-view-per-file-logs) nil)
   (set (make-local-variable 'log-view-message-re)
-       (if vc-short-log
-           "^\\([0-9]+\\)\\(?:\\[.*\\]\\)? +\\([0-9a-z]\\{12\\}\\) +\\(\\(?:[0-9]+\\)-\\(?:[0-9]+\\)-\\(?:[0-9]+\\) \\(?:[0-9]+\\):\\(?:[0-9]+\\) \\(?:[-+0-9]+\\)\\) +\\(.*\\)$"
+       (if (eq vc-log-view-type 'short)
+           "^\\([0-9]+\\)\\(\\[.*\\]\\)? +\\([0-9a-z]\\{12\\}\\) +\\(\\(?:[0-9]+\\)-\\(?:[0-9]+\\)-\\(?:[0-9]+\\) \\(?:[0-9]+\\):\\(?:[0-9]+\\) \\(?:[-+0-9]+\\)\\) +\\(.*\\)$"
          "^changeset:[ \t]*\\([0-9]+\\):\\(.+\\)"))
   (set (make-local-variable 'log-view-font-lock-keywords)
-       (if vc-short-log
+       (if (eq vc-log-view-type 'short)
            (append `((,log-view-message-re
                       (1 'log-view-message-face)
-                      (2 'log-view-message-face)
-                      (3 'change-log-date)
-                      (4 'change-log-name))))
+                      (2 'highlight nil lax)
+                      (3 'log-view-message-face)
+                      (4 'change-log-date)
+                      (5 'change-log-name))))
        (append
         log-view-font-lock-keywords
         '(
@@ -298,7 +298,8 @@
           ("^user:[ \t]+\\([A-Za-z0-9_.+-]+\\(?:@[A-Za-z0-9_.-]+\\)?\\)"
            (1 'change-log-email))
           ("^date: \\(.+\\)" (1 'change-log-date))
-            ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message)))))))
+	  ("^tag: +\\([^ ]+\\)$" (1 'highlight))
+	  ("^summary:[ \t]+\\(.+\\)" (1 'log-view-message)))))))
 
 (defun vc-hg-diff (files &optional oldvers newvers buffer)
   "Get a difference report using hg between two revisions of FILES."
@@ -423,10 +424,16 @@
 ;;   "Unregister FILE from hg."
 ;;   (vc-hg-command nil nil file "remove"))
 
+(declare-function log-edit-extract-headers "log-edit" (headers string))
+
 (defun vc-hg-checkin (files rev comment)
   "Hg-specific version of `vc-backend-checkin'.
 REV is ignored."
-  (vc-hg-command nil 0 files  "commit" "-m" comment))
+  (apply 'vc-hg-command nil 0 files
+         (nconc (list "commit" "-m")
+                (log-edit-extract-headers '(("Author" . "--user")
+					    ("Date" . "--date"))
+                                          comment))))
 
 (defun vc-hg-find-revision (file rev buffer)
   (let ((coding-system-for-read 'binary)
@@ -460,8 +467,6 @@
 
 (defvar vc-hg-extra-menu-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [incoming] '(menu-item "Show incoming" vc-hg-incoming))
-    (define-key map [outgoing] '(menu-item "Show outgoing" vc-hg-outgoing))
     map))
 
 (defun vc-hg-extra-menu () vc-hg-extra-menu-map)
@@ -470,14 +475,6 @@
 
 (defvar log-view-vc-backend)
 
-(define-derived-mode vc-hg-outgoing-mode vc-hg-log-view-mode "Hg-Outgoing"
-  "Mode for browsing Hg outgoing changes."
-  (set (make-local-variable 'log-view-vc-backend) 'Hg))
-
-(define-derived-mode vc-hg-incoming-mode vc-hg-log-view-mode "Hg-Incoming"
-  "Mode for browsing Hg incoming changes."
-  (set (make-local-variable 'log-view-vc-backend) 'Hg))
-
 (defstruct (vc-hg-extra-fileinfo
             (:copier nil)
             (:constructor vc-hg-create-extra-fileinfo (rename-state extra-name))
@@ -583,33 +580,13 @@
      ;; (vc-hg-dir-extra-header "Global id  : " "id" "-i")
      )))
 
-;; FIXME: this adds another top level menu, instead figure out how to
-;; replace the Log-View menu.
-(easy-menu-define log-view-mode-menu vc-hg-outgoing-mode-map
-  "Hg-outgoing Display Menu"
-  `("Hg-outgoing"
-    ["Push selected"  vc-hg-push]))
-
-(easy-menu-define log-view-mode-menu vc-hg-incoming-mode-map
-  "Hg-incoming Display Menu"
-  `("Hg-incoming"
-    ["Pull selected"  vc-hg-pull]))
+(defun vc-hg-log-incoming (buffer remote-location)
+  (vc-hg-command buffer 1 nil "incoming" "-n" (unless (string= remote-location "")
+						remote-location)))
 
-(defun vc-hg-outgoing ()
-  (interactive)
-  (let ((bname "*Hg outgoing*")
-	(vc-short-log nil))
-    (vc-hg-command bname 1 nil "outgoing" "-n")
-    (pop-to-buffer bname)
-    (vc-hg-outgoing-mode)))
-
-(defun vc-hg-incoming ()
-  (interactive)
-  (let ((bname "*Hg incoming*")
-	(vc-short-log nil))
-    (vc-hg-command bname 0 nil "incoming" "-n")
-    (pop-to-buffer bname)
-    (vc-hg-incoming-mode)))
+(defun vc-hg-log-outgoing (buffer remote-location)
+  (vc-hg-command buffer 1 nil "outgoing" "-n" (unless (string= remote-location "")
+						remote-location)))
 
 (declare-function log-view-get-marked "log-view" ())
 
@@ -618,22 +595,22 @@
   (interactive)
   (let ((marked-list (log-view-get-marked)))
     (if marked-list
-        (vc-hg-command
-         nil 0 nil
-         (cons "push"
+        (apply #'vc-hg-command
+               nil 0 nil
+               "push"
                (apply 'nconc
-                      (mapcar (lambda (arg) (list "-r" arg)) marked-list))))
-         (error "No log entries selected for push"))))
+                      (mapcar (lambda (arg) (list "-r" arg)) marked-list)))
+      (error "No log entries selected for push"))))
 
 (defun vc-hg-pull ()
   (interactive)
   (let ((marked-list (log-view-get-marked)))
     (if marked-list
-        (vc-hg-command
-         nil 0 nil
-         (cons "pull"
+        (apply #'vc-hg-command
+               nil 0 nil
+               "pull"
                (apply 'nconc
-                      (mapcar (lambda (arg) (list "-r" arg)) marked-list))))
+                      (mapcar (lambda (arg) (list "-r" arg)) marked-list)))
       (error "No log entries selected for pull"))))
 
 ;;; Internal functions
--- a/lisp/vc-hooks.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-hooks.el	Sun Oct 31 23:13:42 2010 -0400
@@ -403,7 +403,7 @@
 
 
 (defun vc-backend-subdirectory-name (file)
-  "Return where the master and lock FILEs for the current directory are kept."
+  "Return where the repository for the current directory is kept."
   (symbol-name (vc-backend file)))
 
 (defun vc-name (file)
@@ -471,13 +471,13 @@
   USER               The current version of the working file is locked by
                      some other USER (a string).
 
-  'needs-update       The file has not been edited by the user, but there is
+  'needs-update      The file has not been edited by the user, but there is
                      a more recent version on the current branch stored
-                     in the master file.
+                     in the repository.
 
   'needs-merge       The file has been edited by the user, and there is also
                      a more recent version on the current branch stored in
-                     the master file.  This state can only occur if locking
+                     the repository.  This state can only occur if locking
                      is not used for the file.
 
   'unlocked-changes  The working version of the file is not locked,
@@ -556,7 +556,7 @@
 	unchanged))))
 
 (defun vc-default-workfile-unchanged-p (backend file)
-  "Check if FILE is unchanged by diffing against the master version.
+  "Check if FILE is unchanged by diffing against the repository version.
 Return non-nil if FILE is unchanged."
   (zerop (condition-case err
              ;; If the implementation supports it, let the output
@@ -818,6 +818,9 @@
   \"BACKEND-REV\"        if the file is up-to-date
   \"BACKEND:REV\"        if the file is edited (or locked by the calling user)
   \"BACKEND:LOCKER:REV\" if the file is locked by somebody else
+  \"BACKEND@REV\"        if the file was locally added
+  \"BACKEND!REV\"        if the file contains conflicts or was removed
+  \"BACKEND?REV\"        if the file is under VC, but is missing
 
 This function assumes that the file is registered."
   (let* ((backend-name (symbol-name backend))
@@ -947,6 +950,8 @@
     (define-key map "i" 'vc-register)
     (define-key map "l" 'vc-print-log)
     (define-key map "L" 'vc-print-root-log)
+    (define-key map "I" 'vc-log-incoming)
+    (define-key map "O" 'vc-log-outgoing)
     (define-key map "m" 'vc-merge)
     (define-key map "r" 'vc-retrieve-tag)
     (define-key map "s" 'vc-create-tag)
@@ -989,6 +994,12 @@
     (define-key map [vc-update-change-log]
       `(menu-item ,(purecopy "Update ChangeLog") vc-update-change-log
 		  :help ,(purecopy "Find change log file and add entries from recent version control logs")))
+    (define-key map [vc-log-out]
+      `(menu-item ,(purecopy "Show Outgoing Log") vc-log-outgoing
+		  :help ,(purecopy "Show a log of changes that will be sent with a push operation")))
+    (define-key map [vc-log-in]
+      `(menu-item ,(purecopy "Show Incoming Log") vc-log-incoming
+		  :help ,(purecopy "Show a log of changes that will be received with a pull operation")))
     (define-key map [vc-print-log]
       `(menu-item ,(purecopy "Show History") vc-print-log
 		  :help ,(purecopy "List the change log of the current file set in a window")))
--- a/lisp/vc-mtn.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc-mtn.el	Sun Oct 31 23:13:42 2010 -0400
@@ -172,8 +172,14 @@
 (defun vc-mtn-responsible-p (file) (vc-mtn-root file))
 (defun vc-mtn-could-register (file) (vc-mtn-root file))
 
+(declare-function log-edit-extract-headers "log-edit" (headers string))
+
 (defun vc-mtn-checkin (files rev comment)
-  (vc-mtn-command nil 0 files "commit" "-m" comment))
+  (apply 'vc-mtn-command nil 0 files
+	 (nconc (list "commit" "-m")
+		(log-edit-extract-headers '(("Author" . "--author")
+					    ("Date" . "--date"))
+					  comment))))
 
 (defun vc-mtn-find-revision (file rev buffer)
   (vc-mtn-command buffer 0 file "cat" "-r" rev))
--- a/lisp/vc.el	Sun Oct 31 19:30:15 2010 -0700
+++ b/lisp/vc.el	Sun Oct 31 23:13:42 2010 -0400
@@ -63,11 +63,18 @@
 ;; although you might prefer to use C-c C-a (i.e. `log-edit-insert-changelog')
 ;; from the commit buffer instead or to set `log-edit-setup-invert'.
 ;;
-;; The vc code maintains some internal state in order to reduce expensive
-;; version-control operations to a minimum.  Some names are only computed
-;; once.  If you perform version control operations with the backend while
-;; vc's back is turned, or move/rename master files while vc is running,
-;; vc may get seriously confused.  Don't do these things!
+;; When using SCCS, RCS, CVS: be careful not to do repo surgery, or
+;; operations like registrations and deletions and renames, outside VC
+;; while VC is running. The support for these systems was designed
+;; when disks were much slower, and the code maintains a lot of
+;; internal state in order to reduce expensive operations to a
+;; minimum. Thus, if you mess with the repo while VC's back is turned,
+;; VC may get seriously confused.
+;;
+;; When using Subversion or a later system, anything you do outside VC
+;; *through the VCS tools* should safely interlock with VC
+;; operations. Under these VC does little state caching, because local
+;; operations are assumed to be fast.  The dividing line is
 ;;
 ;; ADDING SUPPORT FOR OTHER BACKENDS
 ;;
@@ -196,7 +203,7 @@
 ;;
 ;;   Return non-nil if FILE is unchanged from the working revision.
 ;;   This function should do a brief comparison of FILE's contents
-;;   with those of the repository master of the working revision.  If
+;;   with those of the repository copy of the working revision.  If
 ;;   the backend does not have such a brief-comparison feature, the
 ;;   default implementation of this function can be used, which
 ;;   delegates to a full vc-BACKEND-diff.  (Note that vc-BACKEND-diff
@@ -263,12 +270,10 @@
 ;;
 ;; * checkin (files rev comment)
 ;;
-;;   Commit changes in FILES to this backend.  If REV is non-nil, that
-;;   should become the new revision number (not all backends do
-;;   anything with it).  COMMENT is used as a check-in comment.  The
-;;   implementation should pass the value of vc-checkin-switches to
-;;   the backend command.  (Note: in older versions of VC, this
-;;   command took a single file argument and not a list.)
+;;   Commit changes in FILES to this backend.  REV is a historical artifact
+;;   and should be ignored.  COMMENT is used as a check-in comment.
+;;   The implementation should pass the value of vc-checkin-switches to
+;;   the backend command.
 ;;
 ;; * find-revision (file rev buffer)
 ;;
@@ -344,6 +349,16 @@
 ;;   revision.  At this point START-REVISION is only required to work
 ;;   in conjunction with LIMIT = 1.
 ;;
+;; * log-outgoing (backend remote-location)
+;;
+;;   Insert in BUFFER the revision log for the changes that will be
+;;   sent when performing a push operation to REMOTE-LOCATION.
+;;
+;; * log-incoming (backend remote-location)
+;;
+;;   Insert in BUFFER the revision log for the changes that will be
+;;   received when performing a pull operation from REMOTE-LOCATION.
+;;
 ;; - log-view-mode ()
 ;;
 ;;   Mode to use for the output of print-log.  This defaults to
@@ -477,6 +492,12 @@
 ;;   Return the revision number that follows REV for FILE, or nil if no such
 ;;   revision exists.
 ;;
+;; - log-edit-mode ()
+;;
+;;   Turn on the mode used for editing the check in log.  This
+;;   defaults to `log-edit-mode'.  If changed, it should use a mode
+;;   derived from`log-edit-mode'.
+;;
 ;; - check-headers ()
 ;;
 ;;   Return non-nil if the current buffer contains any version headers.
@@ -524,6 +545,12 @@
 ;;   makes it possible to provide menu entries for functionality that
 ;;   is specific to a backend and which does not map to any of the VC
 ;;   generic concepts.
+;;
+;; - conflicted-files (dir)
+;;
+;;   Return the list of files where conflict resolution is needed in
+;;   the project that contains DIR.
+;;   FIXME: what should it do with non-text conflicts?
 
 ;;; Todo:
 
@@ -553,9 +580,6 @@
 ;;   display the branch name in the mode-line. Replace
 ;;   vc-cvs-sticky-tag with that.
 ;;
-;; - vc-create-tag and vc-retrieve-tag should update the
-;;   buffers that might be visiting the affected files.
-;;
 ;;;; Internal cleanups:
 ;;
 ;; - backends that care about vc-stay-local should try to take it into
@@ -746,7 +770,7 @@
      "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n#endif /* lint */\n"))
   "Associate static header string templates with file types.
 A \%s in the template is replaced with the first string associated with
-the file's version control type in `vc-header-alist'."
+the file's version control type in `vc-BACKEND-header'."
   :type '(repeat (cons :format "%v"
 		       (regexp :tag "File Type")
 		       (string :tag "Header String")))
@@ -767,7 +791,7 @@
 (defcustom vc-checkout-carefully (= (user-uid) 0)
   "Non-nil means be extra-careful in checkout.
 Verify that the file really is not locked
-and that its contents match what the master file says."
+and that its contents match what the repository version says."
   :type 'boolean
   :group 'vc)
 (make-obsolete-variable 'vc-checkout-carefully
@@ -889,6 +913,16 @@
     (nreverse flattened)))
 
 (defvar vc-dir-backend)
+(defvar log-view-vc-backend)
+(defvar diff-vc-backend)
+
+(defun vc-deduce-backend ()
+  (cond ((derived-mode-p 'vc-dir-mode)   vc-dir-backend)
+	((derived-mode-p 'log-view-mode) log-view-vc-backend)
+	((derived-mode-p 'diff-mode)     diff-vc-backend)
+	((derived-mode-p 'dired-mode)
+	 (vc-responsible-backend default-directory))
+	(vc-mode (vc-backend buffer-file-name))))
 
 (declare-function vc-dir-current-file "vc-dir" ())
 (declare-function vc-dir-deduce-fileset "vc-dir" (&optional state-model-only-files))
@@ -1030,8 +1064,7 @@
          (state (nth 3 vc-fileset))
          ;; The backend should check that the checkout-model is consistent
          ;; among all the `files'.
-	 (model (nth 4 vc-fileset))
-	 revision)
+	 (model (nth 4 vc-fileset)))
 
     ;; Do the right thing
     (cond
@@ -1046,11 +1079,13 @@
       (cond
        (verbose
 	;; go to a different revision
-	(setq revision (read-string "Branch, revision, or backend to move to: "))
-	(let ((revision-downcase (downcase revision)))
+	(let* ((revision
+                (read-string "Branch, revision, or backend to move to: "))
+               (revision-downcase (downcase revision)))
 	  (if (member
 	       revision-downcase
-	       (mapcar (lambda (arg) (downcase (symbol-name arg))) vc-handled-backends))
+	       (mapcar (lambda (arg) (downcase (symbol-name arg)))
+                       vc-handled-backends))
 	      (let ((vsym (intern-soft revision-downcase)))
 		(dolist (file files) (vc-transfer-file file vsym)))
 	    (dolist (file files)
@@ -1095,8 +1130,8 @@
 	    (message "No files remain to be committed")
 	  (if (not verbose)
 	      (vc-checkin ready-for-commit backend)
-	    (setq revision (read-string "New revision or backend: "))
-	    (let ((revision-downcase (downcase revision)))
+	    (let* ((revision (read-string "New revision or backend: "))
+                   (revision-downcase (downcase revision)))
 	      (if (member
 		   revision-downcase
 		   (mapcar (lambda (arg) (downcase (symbol-name arg)))
@@ -1341,7 +1376,7 @@
 (defun vc-checkin (files backend &optional rev comment initial-contents)
   "Check in FILES.
 The optional argument REV may be a string specifying the new revision
-level (if nil increment the current level).  COMMENT is a comment
+level (strongly deprecated).  COMMENT is a comment
 string; if omitted, a buffer is popped up to accept a comment.  If
 INITIAL-CONTENTS is non-nil, then COMMENT is used as the initial contents
 of the log entry buffer.
@@ -1355,26 +1390,30 @@
   (lexical-let
    ((backend backend))
    (vc-start-logentry
-    files rev comment initial-contents
+    files comment initial-contents
     "Enter a change comment."
     "*VC-log*"
-    (lambda (files rev comment)
-      (message "Checking in %s..." (vc-delistify files))
-      ;; "This log message intentionally left almost blank".
-      ;; RCS 5.7 gripes about white-space-only comments too.
-      (or (and comment (string-match "[^\t\n ]" comment))
-	  (setq comment "*** empty log message ***"))
-      (with-vc-properties
-       files
-       ;; We used to change buffers to get local value of vc-checkin-switches,
-       ;; but 'the' local buffer is not a well-defined concept for filesets.
-       (progn
-	 (vc-call-backend backend 'checkin files rev comment)
-	 (mapc 'vc-delete-automatic-version-backups files))
-       `((vc-state . up-to-date)
-	 (vc-checkout-time . ,(nth 5 (file-attributes file)))
-	 (vc-working-revision . nil)))
-      (message "Checking in %s...done" (vc-delistify files)))
+    (lambda ()
+      (vc-call-backend backend 'log-edit-mode))
+    (lexical-let ((rev rev))
+      (lambda (files comment)
+        (message "Checking in %s..." (vc-delistify files))
+        ;; "This log message intentionally left almost blank".
+        ;; RCS 5.7 gripes about white-space-only comments too.
+        (or (and comment (string-match "[^\t\n ]" comment))
+            (setq comment "*** empty log message ***"))
+        (with-vc-properties
+            files
+          ;; We used to change buffers to get local value of
+          ;; vc-checkin-switches, but 'the' local buffer is
+          ;; not a well-defined concept for filesets.
+          (progn
+            (vc-call-backend backend 'checkin files rev comment)
+            (mapc 'vc-delete-automatic-version-backups files))
+          `((vc-state . up-to-date)
+            (vc-checkout-time . ,(nth 5 (file-attributes file)))
+            (vc-working-revision . nil)))
+        (message "Checking in %s...done" (vc-delistify files))))
     'vc-checkin-hook)))
 
 ;;; Additional entry points for examining version histories
@@ -1514,7 +1553,7 @@
                   (not (string= (vc-working-revision file) "0")))
               (push file filtered)
             ;; This file is added but not yet committed;
-            ;; there is no master file to diff against.
+            ;; there is no repository version to diff against.
             (if (or rev1 rev2)
                 (error "No revisions of %s exist" file)
               ;; We regard this as "changed".
@@ -1533,6 +1572,10 @@
           (message "%s" (cdr messages))
           nil)
       (diff-mode)
+      (set (make-local-variable 'diff-vc-backend) (car vc-fileset))
+      (set (make-local-variable 'revert-buffer-function)
+	   `(lambda (ignore-auto noconfirm)
+	      (vc-diff-internal ,async ',vc-fileset ,rev1 ,rev2 ,verbose)))
       ;; Make the *vc-diff* buffer read only, the diff-mode key
       ;; bindings are nicer for read only buffers. pcl-cvs does the
       ;; same thing.
@@ -1639,18 +1682,20 @@
       ;; that's not what we want here, we want the diff for the VC root dir.
       (call-interactively 'vc-version-diff)
     (when buffer-file-name (vc-buffer-sync not-urgent))
-    (let ((backend
-	   (cond ((derived-mode-p 'vc-dir-mode)  vc-dir-backend)
-		 ((derived-mode-p 'dired-mode) (vc-responsible-backend default-directory))
-		 (vc-mode (vc-backend buffer-file-name))))
+    (let ((backend (vc-deduce-backend))
 	  rootdir working-revision)
       (unless backend
 	(error "Buffer is not version controlled"))
       (setq rootdir (vc-call-backend backend 'root default-directory))
       (setq working-revision (vc-working-revision rootdir))
-      (vc-diff-internal
-       t (list backend (list rootdir) working-revision) nil nil
-       (called-interactively-p 'interactive)))))
+      ;; VC diff for the root directory produces output that is
+      ;; relative to it.  Bind default-directory to the root directory
+      ;; here, this way the *vc-diff* buffer is setup correctly, so
+      ;; relative file names work.
+      (let ((default-directory rootdir))
+	(vc-diff-internal
+	 t (list backend (list rootdir) working-revision) nil nil
+	 (called-interactively-p 'interactive))))))
 
 ;;;###autoload
 (defun vc-revision-other-window (rev)
@@ -1754,17 +1799,19 @@
 
 (defun vc-modify-change-comment (files rev oldcomment)
   "Edit the comment associated with the given files and revision."
-  (vc-start-logentry
-   files rev oldcomment t
-   "Enter a replacement change comment."
-   "*VC-log*"
-   (lambda (files rev comment)
-     (vc-call-backend
-      ;; Less of a kluge than it looks like; log-view mode only passes
-      ;; this function a singleton list.  Arguments left in this form in
-      ;; case the more general operation ever becomes meaningful.
-      (vc-responsible-backend (car files))
-      'modify-change-comment files rev comment))))
+  ;; Less of a kluge than it looks like; log-view mode only passes
+  ;; this function a singleton list.  Arguments left in this form in
+  ;; case the more general operation ever becomes meaningful.
+  (let ((backend (vc-responsible-backend (car files))))
+    (vc-start-logentry
+     files oldcomment t
+     "Enter a replacement change comment."
+     "*VC-log*"
+     (lambda () (vc-call-backend backend 'log-edit-mode))
+     (lexical-let ((rev rev))
+       (lambda (files comment)
+         (vc-call-backend backend
+                          'modify-change-comment files rev comment))))))
 
 ;;;###autoload
 (defun vc-merge ()
@@ -1825,6 +1872,31 @@
 ;;;###autoload
 (defalias 'vc-resolve-conflicts 'smerge-ediff)
 
+;; TODO: This is OK but maybe we could integrate it better.
+;; E.g. it could be run semi-automatically (via a prompt?) when saving a file
+;; that was conflicted (i.e. upon mark-resolved).
+;; FIXME: should we add an "other-window" version?  Or maybe we should
+;; hook it inside find-file so it automatically works for
+;; find-file-other-window as well.  E.g. find-file could use a new
+;; `default-next-file' variable for its default file (M-n), and
+;; we could then set it upon mark-resolve, so C-x C-s C-x C-f M-n would
+;; automatically offer the next conflicted file.
+(defun vc-find-conflicted-file ()
+  "Visit the next conflicted file in the current project."
+  (interactive)
+  (let* ((backend (or (if buffer-file-name (vc-backend buffer-file-name))
+                      (vc-responsible-backend default-directory)
+                      (error "No VC backend")))
+         (files (vc-call-backend backend
+                                 'conflicted-files default-directory)))
+    ;; Don't try and visit the current file.
+    (if (equal (car files) buffer-file-name) (pop files))
+    (if (null files)
+        (message "No more conflicted files")
+      (find-file (pop files))
+      (message "%s more conflicted files after this one"
+               (if files (length files) "No")))))
+
 ;; Named-configuration entry points
 
 (defun vc-tag-precondition (dir)
@@ -1850,13 +1922,22 @@
 given, the tag is made as a new branch and the files are
 checked out in that new branch."
   (interactive
-   (list (read-file-name "Directory: " default-directory default-directory t)
-         (read-string "New tag name: ")
-	 current-prefix-arg))
+   (let ((granularity
+	  (vc-call-backend (vc-responsible-backend default-directory)
+			   'revision-granularity)))
+     (list
+      (if (eq granularity 'repository)
+	  ;; For VC's that do not work at file level, it's pointless
+	  ;; to ask for a directory, branches are created at repository level.
+	  default-directory
+	(read-file-name "Directory: " default-directory default-directory t))
+      (read-string (if current-prefix-arg "New branch name: " "New tag name: "))
+      current-prefix-arg)))
   (message "Making %s... " (if branchp "branch" "tag"))
   (when (file-directory-p dir) (setq dir (file-name-as-directory dir)))
   (vc-call-backend (vc-responsible-backend dir)
 		   'create-tag dir name branchp)
+  (vc-resynch-buffer dir t t t)
   (message "Making %s... done" (if branchp "branch" "tag")))
 
 ;;;###autoload
@@ -1867,8 +1948,16 @@
 locked files at or below DIR (but if NAME is empty, locked files are
 allowed and simply skipped)."
   (interactive
-   (list (read-file-name "Directory: " default-directory default-directory t)
-         (read-string "Tag name to retrieve (default latest revisions): ")))
+   (let ((granularity
+	  (vc-call-backend (vc-responsible-backend default-directory)
+			   'revision-granularity)))
+     (list
+      (if (eq granularity 'repository)
+	  ;; For VC's that do not work at file level, it's pointless
+	  ;; to ask for a directory, branches are created at repository level.
+	  default-directory
+	(read-file-name "Directory: " default-directory default-directory t))
+      (read-string "Tag name to retrieve (default latest revisions): "))))
   (let ((update (yes-or-no-p "Update any affected buffers? "))
 	(msg (if (or (not name) (string= name ""))
 		 (format "Updating %s... " (abbreviate-file-name dir))
@@ -1877,8 +1966,10 @@
     (message "%s" msg)
     (vc-call-backend (vc-responsible-backend dir)
 		     'retrieve-tag dir name update)
+    (vc-resynch-buffer dir t t t)
     (message "%s" (concat msg "done"))))
 
+
 ;; Miscellaneous other entry points
 
 ;; FIXME: this should be a defcustom
@@ -1891,9 +1982,31 @@
 If it contains `file' then show short logs for files.
 Not all VC backends support short logs!")
 
-(defvar log-view-vc-backend)
 (defvar log-view-vc-fileset)
 
+(defun vc-print-log-setup-buttons (working-revision is-start-revision limit pl-return)
+  (when (and limit (not (eq 'limit-unsupported pl-return))
+	     (not is-start-revision))
+    (goto-char (point-max))
+    (lexical-let ((working-revision working-revision)
+		  (limit limit))
+      (widget-create 'push-button
+		     :notify (lambda (&rest ignore)
+			       (vc-print-log-internal
+				log-view-vc-backend log-view-vc-fileset
+				working-revision nil (* 2 limit)))
+		     :help-echo "Show the log again, and double the number of log entries shown"
+		     "Show 2X entries")
+      (widget-insert "    ")
+      (widget-create 'push-button
+		     :notify (lambda (&rest ignore)
+			       (vc-print-log-internal
+				log-view-vc-backend log-view-vc-fileset
+				working-revision nil nil))
+		     :help-echo "Show the log again, showing all entries"
+		     "Show unlimited entries"))
+    (widget-setup)))
+
 (defun vc-print-log-internal (backend files working-revision
                                       &optional is-start-revision limit)
   ;; Don't switch to the output buffer before running the command,
@@ -1901,6 +2014,8 @@
   ;; buffer can be accessed by the command.
   (let ((dir-present nil)
 	(vc-short-log nil)
+	(buffer-name "*vc-change-log*")
+	type
 	pl-return)
     (dolist (file files)
       (when (file-directory-p file)
@@ -1909,44 +2024,78 @@
 	  (not (null (if dir-present
 			 (memq 'directory vc-log-short-style)
 		       (memq 'file vc-log-short-style)))))
+    (setq type (if vc-short-log 'short 'long))
+    (lexical-let
+	((working-revision working-revision)
+	 (backend backend)
+	 (limit limit)
+	 (shortlog vc-short-log)
+	 (files files)
+	 (is-start-revision is-start-revision))
+      (vc-log-internal-common
+       backend buffer-name files type
+       (lambda (bk buf type-arg files-arg)
+	 (vc-call-backend bk 'print-log files-arg buf
+			  shortlog (when is-start-revision working-revision) limit))
+       (lambda (bk files-arg ret)
+	 (vc-print-log-setup-buttons working-revision
+				     is-start-revision limit ret))
+       (lambda (bk)
+	 (vc-call-backend bk 'show-log-entry working-revision))
+       (lambda (ignore-auto noconfirm)
+	 (vc-print-log-internal backend files working-revision is-start-revision limit))))))
 
-    (setq pl-return (vc-call-backend
-		     backend 'print-log files "*vc-change-log*"
-		     vc-short-log (when is-start-revision working-revision) limit))
-    (pop-to-buffer "*vc-change-log*")
+(defvar vc-log-view-type nil
+  "Set this to differentiate the different types of logs.")
+(put 'vc-log-view-type 'permanent-local t)
+
+(defun vc-log-internal-common (backend
+			       buffer-name
+			       files
+			       type
+			       backend-func
+			       setup-buttons-func
+			       goto-location-func
+			       rev-buff-func)
+  (let (retval)
+    (with-current-buffer (get-buffer-create buffer-name)
+      (set (make-local-variable 'vc-log-view-type) type))
+    (setq retval (funcall backend-func backend buffer-name type files))
+    (pop-to-buffer buffer-name)
     (let ((inhibit-read-only t))
       ;; log-view-mode used to be called with inhibit-read-only bound
       ;; to t, so let's keep doing it, just in case.
-      (vc-call-backend backend 'log-view-mode))
-    (set (make-local-variable 'log-view-vc-backend) backend)
-    (set (make-local-variable 'log-view-vc-fileset) files)
-
+      (vc-call-backend backend 'log-view-mode)
+      (set (make-local-variable 'log-view-vc-backend) backend)
+      (set (make-local-variable 'log-view-vc-fileset) files)
+      (set (make-local-variable 'revert-buffer-function)
+	   rev-buff-func))
     (vc-exec-after
      `(let ((inhibit-read-only t))
-	(when (and ,limit (not ,(eq 'limit-unsupported pl-return))
-		   (not ,is-start-revision))
-	  (goto-char (point-max))
-	  (widget-create 'push-button
-			 :notify (lambda (&rest ignore)
-				   (vc-print-log-internal
-				    ',backend ',files ',working-revision nil (* 2 ,limit)))
-			 :help-echo "Show the log again, and double the number of log entries shown"
-			 "Show 2X entries")
-	  (widget-insert "    ")
-	  (widget-create 'push-button
-			 :notify (lambda (&rest ignore)
-				   (vc-print-log-internal
-				    ',backend ',files ',working-revision nil nil))
-			 :help-echo "Show the log again, showing all entries"
-			 "Show unlimited entries")
-	  (widget-setup))
-
+	(funcall ',setup-buttons-func ',backend ',files ',retval)
 	(shrink-window-if-larger-than-buffer)
-	;; move point to the log entry for the working revision
-	(vc-call-backend ',backend 'show-log-entry ',working-revision)
+	(funcall ',goto-location-func ',backend)
 	(setq vc-sentinel-movepoint (point))
 	(set-buffer-modified-p nil)))))
 
+(defun vc-incoming-outgoing-internal (backend remote-location buffer-name type)
+  (vc-log-internal-common
+   backend buffer-name nil type
+   (lexical-let
+       ((remote-location remote-location))
+     (lambda (bk buf type-arg files)
+       (vc-call-backend bk type-arg buf remote-location)))
+   (lambda (bk files-arg ret))
+   (lambda (bk)
+     (goto-char (point-min)))
+   (lexical-let
+    ((backend backend)
+     (remote-location remote-location)
+     (buffer-name buffer-name)
+     (type type))
+    (lambda (ignore-auto noconfirm)
+      (vc-incoming-outgoing-internal backend remote-location buffer-name type)))))
+
 ;;;###autoload
 (defun vc-print-log (&optional working-revision limit)
   "List the change log of the current fileset in a window.
@@ -1995,10 +2144,7 @@
        (list lim)))
     (t
      (list (when (> vc-log-show-limit 0) vc-log-show-limit)))))
-  (let ((backend
-	 (cond ((derived-mode-p 'vc-dir-mode)  vc-dir-backend)
-	       ((derived-mode-p 'dired-mode) (vc-responsible-backend default-directory))
-	       (vc-mode (vc-backend buffer-file-name))))
+  (let ((backend (vc-deduce-backend))
 	rootdir working-revision)
     (unless backend
       (error "Buffer is not version controlled"))
@@ -2007,6 +2153,32 @@
     (vc-print-log-internal backend (list rootdir) working-revision nil limit)))
 
 ;;;###autoload
+(defun vc-log-incoming (&optional remote-location)
+  "Show a log of changes that will be received with a pull operation from REMOTE-LOCATION.
+When called interactively with a prefix argument, prompt for REMOTE-LOCATION.."
+  (interactive
+   (when current-prefix-arg
+     (list (read-string "Remote location (empty for default): "))))
+  (let ((backend (vc-deduce-backend))
+	rootdir working-revision)
+    (unless backend
+      (error "Buffer is not version controlled"))
+    (vc-incoming-outgoing-internal backend remote-location "*vc-incoming*" 'log-incoming)))
+
+;;;###autoload
+(defun vc-log-outgoing (&optional remote-location)
+  "Show a log of changes that will be sent with a push operation to REMOTE-LOCATION.
+When called interactively with a prefix argument, prompt for REMOTE-LOCATION."
+  (interactive
+   (when current-prefix-arg
+     (list (read-string "Remote location (empty for default): "))))
+  (let ((backend (vc-deduce-backend))
+	rootdir working-revision)
+    (unless backend
+      (error "Buffer is not version controlled"))
+    (vc-incoming-outgoing-internal backend remote-location "*vc-outgoing*" 'log-outgoing)))
+
+;;;###autoload
 (defun vc-revert ()
   "Revert working copies of the selected fileset to their repository contents.
 This asks for confirmation if the buffer contents are not identical
@@ -2240,7 +2412,7 @@
 		(if unmodified-file
 		    (copy-file unmodified-file file
 			       'ok-if-already-exists 'keep-date)
-		  (when (y-or-n-p "Get base revision from master? ")
+		  (when (y-or-n-p "Get base revision from repository? ")
 		    (vc-revert-file file))))
 	      (vc-call-backend new-backend 'receive-file file rev))
 	  (when modified-file
@@ -2327,7 +2499,7 @@
 
 ;;;###autoload
 (defun vc-rename-file (old new)
-  "Rename file OLD to NEW, and rename its master file likewise."
+  "Rename file OLD to NEW in both work area and repository."
   (interactive "fVC rename file: \nFRename to: ")
   ;; in CL I would have said (setq new (merge-pathnames new old))
   (let ((old-base (file-name-nondirectory old)))
@@ -2451,6 +2623,10 @@
 
 (defalias 'vc-default-check-headers 'ignore)
 
+(declare-function log-edit-mode "log-edit" ())
+
+(defun vc-default-log-edit-mode (backend) (log-edit-mode))
+
 (defun vc-default-log-view-mode (backend) (log-view-mode))
 
 (defun vc-default-show-log-entry (backend rev)