From 1b1de00325a1341c27bb25f27f5396d280643051 Mon Sep 17 00:00:00 2001 From: jorton Date: Mon, 13 Oct 2008 09:49:23 +0000 Subject: [PATCH] - update to 1.5.3 (#466674) - update psvn.el to r33557 --- .cvsignore | 2 +- psvn.el | 565 +++++++++++++++++++++++++++++++----- sources | 2 +- subversion-1.5.3.tar.gz.asc | 35 +++ subversion.spec | 8 +- upstream | 2 +- 6 files changed, 535 insertions(+), 79 deletions(-) create mode 100644 subversion-1.5.3.tar.gz.asc diff --git a/.cvsignore b/.cvsignore index 5aedbed..f7d4591 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -subversion-1.5.2.tar.gz +subversion-1.5.3.tar.gz diff --git a/psvn.el b/psvn.el index b840b59..643afa3 100644 --- a/psvn.el +++ b/psvn.el @@ -1,8 +1,8 @@ ;;; psvn.el --- Subversion interface for emacs -;; Copyright (C) 2002-2007 by Stefan Reichoer +;; Copyright (C) 2002-2008 by Stefan Reichoer ;; Author: Stefan Reichoer -;; $Id: psvn.el 26383 2007-08-29 19:04:04Z xsteve $ +;; $Id: psvn.el 33557 2008-10-08 20:01:12Z xsteve $ ;; psvn.el is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -66,6 +66,8 @@ ;; ~ - svn-status-get-specific-revision ;; E - svn-status-ediff-with-revision ;; X X - svn-status-resolve-conflicts +;; S g - svn-status-grep-files +;; S s - svn-status-search-files ;; s - svn-status-show-process-buffer ;; h - svn-status-pop-to-partner-buffer ;; e - svn-status-toggle-edit-cmd-flag @@ -80,10 +82,13 @@ ;; * ? - svn-status-mark-unknown ;; * A - svn-status-mark-added ;; * M - svn-status-mark-modified +;; * P - svn-status-mark-modified-properties ;; * D - svn-status-mark-deleted ;; * * - svn-status-mark-changed ;; * . - svn-status-mark-by-file-ext ;; * % - svn-status-mark-filename-regexp +;; * s - svn-status-store-usermarks +;; * l - svn-status-load-usermarks ;; . - svn-status-goto-root-or-return ;; f - svn-status-find-file ;; o - svn-status-find-file-other-window @@ -185,6 +190,35 @@ ;; Trac ticket links can be enabled in the *svn-log* buffers when using the following: ;; (setq svn-log-link-handlers '(trac-ticket-short)) +;; --------------------------- +;; Frequently asked questions: +;; --------------------------- + +;; Q1: I need support for user names with blanks/spaces +;; A1: Add the user names to svn-user-names-including-blanks and set the +;; svn-pre-parse-status-hook. +;; The problem is, that the user names and the file names from the svn status +;; output can both contain blanks. Blanks in file names are supported. +;; the svn-user-names-including-blanks list is used to replace the spaces +;; in the user names with - to overcome this problem + +;; Q2: My svn-update command it taking a really long time. How can I +;; see what's going on? +;; A2: In the *svn-status* buffer press "s". + +;; Q3: How do I enter a username and password? +;; A3: In the *svn-status* buffer press "s", switch to the +;; *svn-process* buffer and press enter. You will be prompted for +;; username and password. + +;; Q4: What does "?", "M", and "C" in the first column of the +;; *svn-status* buffer mean? +;; A4: "?" means the file(s) is not under Subversion control +;; "M" means you have a locally modified file +;; "C" means there is a conflict +;; "@$&#!" means someone is saying nasty things to you + + ;; Comments / suggestions and bug reports are welcome! ;; Development notes @@ -210,6 +244,7 @@ (eval-when-compile (require 'dired)) (eval-when-compile (require 'ediff-util)) +(eval-when-compile (require 'ediff-wind)) (eval-when-compile (require 'elp)) (eval-when-compile (require 'pp)) @@ -218,7 +253,7 @@ (require 'diff-mode)) (error nil)) -(defconst svn-psvn-revision "$Id: psvn.el 26383 2007-08-29 19:04:04Z xsteve $" +(defconst svn-psvn-revision "$Id: psvn.el 33557 2008-10-08 20:01:12Z xsteve $" "The revision number of psvn.") ;;; user setable variables @@ -238,6 +273,10 @@ of the `svn-log-edit-buffer-name' buffer." "*Insert the filelist to commit in the *svn-log* buffer" :type 'boolean :group 'psvn) +(defcustom svn-log-edit-show-diff-for-commit nil + "*Show the diff being committed when you run `svn-status-commit.'." + :type 'boolean + :group 'psvn) (defcustom svn-log-edit-use-log-edit-mode (and (condition-case nil (require 'log-edit) (error nil)) t) "*Use log-edit-mode as base for svn-log-edit-mode @@ -308,6 +347,11 @@ Possible values are: commit, revert." :type 'boolean :group 'psvn) +(defcustom svn-status-fancy-file-state-in-modeline t + "*Show a color dot in the modeline that describes the state of the current file." + :type 'boolean + :group 'psvn) + (defcustom svn-status-negate-meaning-of-arg-commands '() "*List of operations that should use a negated meaning of the prefix argument. The supported functions are `svn-status' and `svn-status-set-user-mark'." @@ -468,9 +512,21 @@ use the following value: :group 'psvn) (put 'svn-status-default-diff-arguments 'risky-local-variable t) +(defcustom svn-status-default-status-arguments '() + "*A list of arguments that is passed to the svn status command. +The following options are available: --ignore-externals + +" + :type '(repeat string) + :group 'psvn) +(put 'svn-status-default-status-arguments 'risky-local-variable t) + (defcustom svn-status-default-blame-arguments '("-x" "--ignore-eol-style") "*A list of arguments that is passed to the svn blame command. -See `svn-status-default-diff-arguments' for some examples.") +See `svn-status-default-diff-arguments' for some examples." + :type '(repeat string) + :group 'psvn) + (put 'svn-status-default-blame-arguments 'risky-local-variable t) (defvar svn-trac-project-root nil @@ -657,12 +713,14 @@ This is nil if the log entry is for a new commit.") (defvar svn-ediff-result) (defvar svn-status-last-diff-options nil) (defvar svn-status-blame-file-name nil) +(defvar svn-status-blame-revision nil) (defvar svn-admin-last-repository-dir nil "The last repository url for various operations.") (defvar svn-last-cmd-ring (make-ring 30) "Ring that holds the last executed svn commands (for debugging purposes)") (defvar svn-status-cached-version-string nil) (defvar svn-client-version nil "The version number of the used svn client") (defvar svn-status-get-line-information-for-file nil) (defvar svn-status-base-dir-cache (make-hash-table :test 'equal :weakness nil)) +(defvar svn-status-usermark-storage (make-hash-table :test 'equal :weakness nil)) (defvar svn-log-registered-link-handlers (make-hash-table :test 'eql :weakness nil)) (defvar svn-status-partner-buffer nil "The partner buffer for this svn related buffer") @@ -787,6 +845,21 @@ the target of the link gets either `svn-status-filename-face' or "Default face for highlighting a line in svn status blame mode." :group 'psvn-faces)) +(if svn-xemacsp + (defface svn-log-partner-highlight-face + '((((type tty) (class color)) (:foreground "yellow" :weight light)) + (((class color) (background light)) (:foreground "gold")) + (((class color) (background dark)) (:foreground "gold")) + (t (:weight bold))) + "Default face for highlighting the partner in svn log mode." + :group 'psvn-faces) + (defface svn-log-partner-highlight-face + '((((class color) (background light)) + (:background "light goldenrod" :weight bold)) + (t (:weight bold))) + "Default face for highlighting the partner in svn log mode." + :group 'psvn-faces)) + (defface svn-status-blame-rev-number-face '((((class color) (background light)) (:foreground "DarkGoldenrod")) (((class color) (background dark)) (:foreground "LightGoldenrod")) @@ -860,6 +933,11 @@ If POS is nil, use current buffer location." (forward-line 0) (1+ (count-lines start (point))))))) +(defun svn-substring-no-properties (string &optional from to) + (if (fboundp 'substring-no-properties) + (substring-no-properties string from to) + (substring string from to))) + ; xemacs ;; Evaluate the defsubst at compile time, so that the byte compiler ;; knows the definition and can inline calls. It cannot detect the @@ -906,6 +984,10 @@ Use this instead of `alist', for XEmacs 21.4 compatibility." ,value-type))))) widget)) +;; process launch functions +(defvar svn-call-process-function (if (fboundp 'process-file) 'process-file 'call-process)) +(defvar svn-start-process-function (if (fboundp 'start-file-process) 'start-file-process 'start-process)) + ;;; keymaps @@ -925,6 +1007,7 @@ To bind this to a different key, customize `svn-status-prefix-key'.") (define-key svn-global-keymap (kbd "f l") 'svn-status-show-svn-log) (define-key svn-global-keymap (kbd "f b") 'svn-status-blame) (define-key svn-global-keymap (kbd "f a") 'svn-file-add-to-changelog) + (define-key svn-global-keymap (kbd "f r") 'svn-file-revert) (define-key svn-global-keymap (kbd "c") 'svn-status-commit) (define-key svn-global-keymap (kbd "S") 'svn-status-switch-to-status-buffer) (define-key svn-global-keymap (kbd "o") 'svn-status-pop-to-status-buffer)) @@ -1075,9 +1158,7 @@ If there is no .svn directory, examine if there is CVS and run (if svn-status-verbose "-v" "") (if svn-status-verbose (if arg "-uv" "-v") - (if arg "-u" "")))) - (svn-status-edit-svn-command - (or want-edit svn-status-edit-svn-command))) + (if arg "-u" ""))))) (save-excursion (set-buffer status-buf) (setq default-directory dir) @@ -1085,7 +1166,10 @@ If there is no .svn directory, examine if there is CVS and run (setq default-directory dir svn-status-remote (when arg t)) (set-buffer cur-buf) - (svn-run t t 'status "status" status-option)))) + (if want-edit + (let (svn-status-edit-svn-command t) + (svn-run t t 'status "status" svn-status-default-status-arguments status-option)) + (svn-run t t 'status "status" svn-status-default-status-arguments status-option))))) (defun svn-status-this-directory (arg) "Run `svn-status' for the `default-directory'" @@ -1098,7 +1182,9 @@ If there is no .svn directory, examine if there is CVS and run (let* ((in-status-buffer (eq major-mode 'svn-status-mode)) (hist (if in-status-buffer (cdr svn-status-directory-history) svn-status-directory-history)) (dir (funcall svn-status-completing-read-function "svn-status on directory: " hist)) - (svn-buffer-available (with-current-buffer (get-buffer svn-status-buffer-name) (string= default-directory dir)))) + (svn-status-buffer (get-buffer svn-status-buffer-name)) + (svn-buffer-available (and svn-status-buffer + (with-current-buffer svn-status-buffer-name (string= default-directory dir))))) (if (file-directory-p dir) (if svn-buffer-available (svn-status-switch-to-status-buffer) @@ -1203,7 +1289,7 @@ The hook svn-pre-run-hook allows to monitor/modify the ARGLIST." ;; run on a TTY without $DISPLAY, this will fail; in ;; such cases, the user should start ssh-agent and ;; then run ssh-add explicitly. - (setq svn-proc (apply 'start-process "svn" proc-buf svn-exe arglist))) + (setq svn-proc (apply svn-start-process-function "svn" proc-buf svn-exe arglist))) (when svn-status-svn-process-coding-system (set-process-coding-system svn-proc svn-status-svn-process-coding-system svn-status-svn-process-coding-system)) @@ -1214,7 +1300,7 @@ The hook svn-pre-run-hook allows to monitor/modify the ARGLIST." (let ((process-environment (svn-process-environment))) ;; `call-process' ignores `process-connection-type' and ;; never opens a pseudoterminal. - (apply 'call-process svn-exe nil proc-buf nil arglist)) + (apply svn-call-process-function svn-exe nil proc-buf nil arglist)) (setq svn-status-last-output-buffer-name svn-process-buffer-name) (run-hooks 'svn-post-process-svn-output-hook) (setq svn-status-mode-line-process-status "") @@ -1309,7 +1395,9 @@ The hook svn-pre-run-hook allows to monitor/modify the ARGLIST." (run-hooks 'svn-log-edit-done-hook) (setq svn-status-files-to-commit nil svn-status-recursive-commit nil) - (message "svn: Committed revision %s." svn-status-commit-rev-number)) + (if (null svn-status-commit-rev-number) + (message "No revision to commit.") + (message "svn: Committed revision %s." svn-status-commit-rev-number))) ((eq svn-process-cmd 'update) (svn-status-show-process-output 'update t) (setq svn-status-update-list (svn-status-parse-update-output)) @@ -1333,6 +1421,7 @@ The hook svn-pre-run-hook allows to monitor/modify the ARGLIST." ((eq svn-process-cmd 'revert) (when (member 'revert svn-status-unmark-files-after-list) (svn-status-unset-all-usermarks)) + (svn-revert-some-buffers) (svn-status-update) (message "svn revert finished")) ((eq svn-process-cmd 'resolved) @@ -1370,6 +1459,7 @@ The hook svn-pre-run-hook allows to monitor/modify the ARGLIST." (message "svn process had unknown event: %s" event)) (svn-status-show-process-output nil t)))) +(defvar svn-process-handle-error-msg nil) (defun svn-process-handle-error (error-msg) (let ((svn-process-handle-error-msg error-msg)) (electric-helpify 'svn-process-help-with-error-msg))) @@ -1424,6 +1514,8 @@ To be run after a commit, an update or a merge." (string= root tree) ;; buffer is modified and in the tree TREE. svn-status-auto-revert-buffers) + (when svn-status-fancy-file-state-in-modeline + (svn-status-update-modeline)) ;; (message "svn-revert-some-buffers: %s %s" (buffer-file-name) (verify-visited-file-modtime (current-buffer))) ;; Keep the buffer if the file doesn't exist (when (and (file-exists-p file) (not (verify-visited-file-modtime (current-buffer)))) @@ -1511,7 +1603,11 @@ nb: LOCKED-MARK refers to the kind of locks you get after an error, locked-repo-mark psvn-extra-info)) -(defvar svn-user-names-including-blanks nil "A list of svn user names that include blanks.") +(defvar svn-user-names-including-blanks nil "A list of svn user names that include blanks. +To add support for the names \"feng shui\" and \"mister blank\", place the following in your .emacs: + (setq svn-user-names-including-blanks '(\"feng shui\" \"mister blank\")) + (add-hook 'svn-pre-parse-status-hook 'svn-status-parse-fixup-user-names-including-blanks) +") ;;(setq svn-user-names-including-blanks '("feng shui" "mister blank")) ;;(add-hook 'svn-pre-parse-status-hook 'svn-status-parse-fixup-user-names-including-blanks) @@ -1588,9 +1684,12 @@ The results are used to build the `svn-status-info' variable." ;; My attempt to merge the lines uses skip-double-external-dir-entry-name ;; and externals-map - (setq skip-double-external-dir-entry-name (match-string-no-properties 1)) + (setq skip-double-external-dir-entry-name (svn-match-string-no-properties 1)) ;; (message "Going to skip %s" skip-double-external-dir-entry-name) nil) + ((looking-at "--- Changelist") ; skip svn changelist header lines + ;; See: http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt + nil) (t (setq svn-marks (buffer-substring (point) (+ (point) svn-marks-length)) svn-file-mark (elt svn-marks 0) ; 1st column - M,A,C,D,G,? etc @@ -1735,6 +1834,9 @@ A and B must be line-info's." (defvar svn-status-mode-branch-map () "Subkeymap used in `svn-status-mode' for branching commands.") (put 'svn-status-mode-extension-map 'risky-local-variable t) ;for Emacs 20.7 +(defvar svn-status-mode-search-map () + "Subkeymap used in `svn-status-mode' for search commands.") +(put 'svn-status-mode-search-map 'risky-local-variable t) ;for Emacs 20.7 (when (not svn-status-mode-map) (setq svn-status-mode-map (make-sparse-keymap)) @@ -1814,18 +1916,30 @@ A and B must be line-info's." (define-key svn-status-mode-map (kbd "") 'svn-status-next-line) (define-key svn-status-mode-map (kbd "") 'svn-status-previous-line) (define-key svn-status-mode-map (kbd "C-x C-j") 'svn-status-dired-jump) - (define-key svn-status-mode-map [down-mouse-3] 'svn-status-popup-menu) + (define-key svn-status-mode-map [down-mouse-3] 'svn-status-popup-menu)) + +(when (not svn-status-mode-mark-map) (setq svn-status-mode-mark-map (make-sparse-keymap)) (define-key svn-status-mode-map (kbd "*") svn-status-mode-mark-map) (define-key svn-status-mode-mark-map (kbd "!") 'svn-status-unset-all-usermarks) (define-key svn-status-mode-mark-map (kbd "?") 'svn-status-mark-unknown) (define-key svn-status-mode-mark-map (kbd "A") 'svn-status-mark-added) (define-key svn-status-mode-mark-map (kbd "M") 'svn-status-mark-modified) + (define-key svn-status-mode-mark-map (kbd "P") 'svn-status-mark-modified-properties) (define-key svn-status-mode-mark-map (kbd "D") 'svn-status-mark-deleted) (define-key svn-status-mode-mark-map (kbd "*") 'svn-status-mark-changed) (define-key svn-status-mode-mark-map (kbd ".") 'svn-status-mark-by-file-ext) (define-key svn-status-mode-mark-map (kbd "%") 'svn-status-mark-filename-regexp) + (define-key svn-status-mode-mark-map (kbd "s") 'svn-status-store-usermarks) + (define-key svn-status-mode-mark-map (kbd "l") 'svn-status-load-usermarks) (define-key svn-status-mode-mark-map (kbd "u") 'svn-status-show-svn-diff-for-marked-files)) + +(when (not svn-status-mode-search-map) + (setq svn-status-mode-search-map (make-sparse-keymap)) + (define-key svn-status-mode-search-map (kbd "g") 'svn-status-grep-files) + (define-key svn-status-mode-search-map (kbd "s") 'svn-status-search-files) + (define-key svn-status-mode-map (kbd "S") svn-status-mode-search-map)) + (when (not svn-status-mode-property-map) (setq svn-status-mode-property-map (make-sparse-keymap)) (define-key svn-status-mode-property-map (kbd "l") 'svn-status-property-list) @@ -1897,6 +2011,10 @@ A and B must be line-info's." ["svn ediff current file" svn-status-ediff-with-revision t] ["svn resolve conflicts" svn-status-resolve-conflicts] ) + ("Search" + ["Grep marked files" svn-status-grep-files t] + ["Search marked files" svn-status-search-files t] + ) ["svn cat ..." svn-status-get-specific-revision t] ["svn add" svn-status-add-file t] ["svn add recursively" svn-status-add-file-recursively t] @@ -1968,12 +2086,15 @@ A and B must be line-info's." ["Unmark all" svn-status-unset-all-usermarks t] "---" ["Mark/Unmark unknown" svn-status-mark-unknown t] - ["Mark/Unmark added" svn-status-mark-added t] ["Mark/Unmark modified" svn-status-mark-modified t] + ["Mark/Unmark modified properties" svn-status-mark-modified-properties t] + ["Mark/Unmark added" svn-status-mark-added t] ["Mark/Unmark deleted" svn-status-mark-deleted t] ["Mark/Unmark modified/added/deleted" svn-status-mark-changed t] ["Mark/Unmark filename by extension" svn-status-mark-by-file-ext t] ["Mark/Unmark filename by regexp" svn-status-mark-filename-regexp t] + ["Store Usermarks" svn-status-store-usermarks t] + ["Load Usermarks" svn-status-load-usermarks t] ) ["Hide Unknown" svn-status-toggle-hide-unknown :style toggle :selected svn-status-hide-unknown] @@ -2200,7 +2321,7 @@ repository than the working copy." "Return whether LINE-INFO represents a locked file. This is column three of the `svn status' output. The result will be nil or \"L\". -\(A file becomes locked when an operation is interupted; run \\[svn-status-cleanup]' +\(A file becomes locked when an operation is interrupted; run \\[svn-status-cleanup]' to unlock it.\)" (nth 8 line-info)) (defun svn-status-line-info->historymark (line-info) @@ -2980,7 +3101,7 @@ The string in parentheses is shown in the status line to show the state." When called with a prefix argument advance the given number of lines." (interactive "p") (while (progn - (next-line nr-of-lines) + (forward-line nr-of-lines) (and (not (eobp)) (not (svn-status-get-line-information))))) (when (svn-status-get-line-information) @@ -2991,7 +3112,7 @@ When called with a prefix argument advance the given number of lines." When called with a prefix argument go back the given number of lines." (interactive "p") (while (progn - (previous-line nr-of-lines) + (forward-line (- nr-of-lines)) (and (not (bobp)) (not (svn-status-get-line-information))))) (when (svn-status-get-line-information) @@ -3001,10 +3122,14 @@ When called with a prefix argument go back the given number of lines." "Jump to a dired buffer, containing the file at point." (interactive) (let* ((line-info (svn-status-get-line-information)) - (file-full-path (svn-status-line-info->full-path line-info))) + (file-full-path (if line-info + (svn-status-line-info->full-path line-info) + default-directory))) (let ((default-directory (file-name-as-directory - (expand-file-name (svn-status-line-info->directory-containing-line-info line-info t))))) + (expand-file-name (if line-info + (svn-status-line-info->directory-containing-line-info line-info t) + default-directory))))) (if (fboundp 'dired-jump-back) (dired-jump-back) (dired-jump))) ;; Xemacs uses dired-jump-back (dired-goto-file file-full-path))) @@ -3233,12 +3358,22 @@ If the function is called with a prefix ARG, unmark all these files." (defun svn-status-mark-modified (arg) "Mark all modified files. These are the files marked with 'M' in the `svn-status-buffer-name' buffer. +Changed properties are considered. If the function is called with a prefix ARG, unmark all these files." (interactive "P") (svn-status-apply-usermark-checked '(lambda (info) (or (eq (svn-status-line-info->filemark info) ?M) (eq (svn-status-line-info->filemark info) - svn-status-file-modified-after-save-flag))) + svn-status-file-modified-after-save-flag) + (eq (svn-status-line-info->propmark info) ?M))) + (not arg))) + +(defun svn-status-mark-modified-properties (arg) + "Mark all files and directories with modified properties. +If the function is called with a prefix ARG, unmark all these entries." + (interactive "P") + (svn-status-apply-usermark-checked + '(lambda (info) (or (eq (svn-status-line-info->propmark info) ?M))) (not arg))) (defun svn-status-mark-deleted (arg) @@ -3267,6 +3402,22 @@ If called with a prefix ARG, unmark all such files." (interactive) (svn-status-apply-usermark-checked '(lambda (info) t) nil)) +(defun svn-status-store-usermarks (arg) + "Store the current usermarks in `svn-status-usermark-storage'. +When called with a prefix argument it is possible to store different sets of marks." + (interactive "P") + (let ((file-list (svn-status-get-file-list-names t))) + (svn-puthash arg file-list svn-status-usermark-storage) + (message "psvn stored %d user marks" (length file-list)))) + +(defun svn-status-load-usermarks (arg) + "Load previously stored user marks from `svn-status-usermark-storage'. +When called with a prefix argument it is possible to store/load different sets of marks." + (interactive "P") + (let ((file-list (gethash arg svn-status-usermark-storage))) + (svn-status-apply-usermark-checked + '(lambda (info) (member (svn-status-line-info->filename info) file-list)) t))) + (defvar svn-status-regexp-history nil "History list of regular expressions used in svn status commands.") @@ -3524,7 +3675,7 @@ At the moment a list containing the last changed author is returned." (svn-status-message 7 "last-changed-author for '%s': %s" path last-changed-author) (list last-changed-author))) -(defun svn-status-blame (revision) +(defun svn-status-blame (revision &optional file-name) "Run `svn blame' on the current file. When called with a prefix argument, ask the user for the REVISION to use. When called from a file buffer, go to the current line in the resulting blame output." @@ -3532,19 +3683,35 @@ When called from a file buffer, go to the current line in the resulting blame ou (when current-prefix-arg (setq revision (svn-status-read-revision-string "Blame for version: " "BASE"))) (unless revision (setq revision "BASE")) - (setq svn-status-blame-file-name (svn-status-line-info->filename (svn-status-get-file-information))) + (setq svn-status-blame-revision revision) + (setq svn-status-blame-file-name (if file-name + file-name + (svn-status-line-info->filename (svn-status-get-file-information)))) (svn-run t t 'blame "blame" svn-status-default-blame-arguments "-r" revision svn-status-blame-file-name)) +(defun svn-blame-blame-again (arg) + "Run svn blame again, using the revision before the change at point. +When point is at revision 3472, run it with 3471." + (interactive "P") + (let ((rev (svn-blame-rev-at-point))) + (setq rev (number-to-string (- (string-to-number rev) 1))) + (when current-prefix-arg + (setq rev (svn-status-read-revision-string (format "Svn blame for rev#? ") rev))) + (svn-status-blame rev svn-status-blame-file-name))) + (defun svn-status-show-svn-diff (arg) "Run `svn diff' on the current file. If the current file is a directory, compare it recursively. If there is a newer revision in the repository, the diff is done against HEAD, otherwise compare the working copy with BASE. -If ARG then prompt for revision to diff against." +If ARG then prompt for revision to diff against (unless arg is '-) +When called with a negative prefix argument, do a non recursive diff." (interactive "P") - (svn-status-ensure-cursor-on-file) - (svn-status-show-svn-diff-internal (list (svn-status-get-line-information)) t - (if arg :ask :auto))) + (let ((non-recursive (or (and (numberp arg) (< arg 0)) (eq arg '-))) + (revision (if (and (not (eq arg '-)) arg) :ask :auto))) + (svn-status-ensure-cursor-on-file) + (svn-status-show-svn-diff-internal (list (svn-status-get-line-information)) (not non-recursive) + revision))) (defun svn-file-show-svn-diff (arg) "Run `svn diff' on the current file. @@ -3567,15 +3734,15 @@ If ARG then prompt for revision to diff against, else compare working copy with (not (svn-status-some-files-marked-p)) (if arg :ask "BASE"))) -(defun svn-status-diff-show-changeset (rev &optional user-confirmation) +(defun svn-status-diff-show-changeset (rev &optional user-confirmation rev-against) "Show the changeset for a given log entry. When called with a prefix argument, ask the user for the revision." - (let* ((upper-rev rev) - (lower-rev (number-to-string (- (string-to-number upper-rev) 1))) + (let* ((upper-rev (if rev-against rev-against rev)) + (lower-rev (if rev-against rev (number-to-string (- (string-to-number upper-rev) 1)))) (rev-arg (concat lower-rev ":" upper-rev))) (when user-confirmation (setq rev-arg (read-string "Revision for changeset: " rev-arg))) - (svn-run nil t 'diff "diff" (concat "-r" rev-arg)) + (svn-run nil t 'diff "diff" svn-status-default-diff-arguments (concat "-r" rev-arg)) (svn-status-activate-diff-mode))) (defun svn-status-show-svn-diff-internal (line-infos recursive revision) @@ -3826,6 +3993,7 @@ user can enter a new file name, or an existing directory: this is used as the ar ((eq original-filemarks ??) ;original is unversioned: use fallback (if (yes-or-no-p (format "%s is unversioned. Use `%s -i -- %s %s'? " original-name fallback original-name dest)) + ;; TODO: consider svn-call-process-function here also... (progn (call-process fallback nil (get-buffer-create svn-process-buffer-name) nil "-i" "--" original-name dest) (setq moved t)) @@ -3893,6 +4061,12 @@ See `svn-status-marked-files' for what counts as selected." (svn-status-create-arg-file svn-status-temp-arg-file "" (svn-status-marked-files) "") (svn-run t t 'revert "revert" "--targets" svn-status-temp-arg-file)))) +(defun svn-file-revert () + "Run `svn revert' on the current file." + (interactive) + (when (y-or-n-p (format "Revert %s? " buffer-file-name)) + (svn-run t t 'revert "revert" buffer-file-name))) + (defun svn-status-rm (force) "Run `svn rm' on all selected files. See `svn-status-marked-files' for what counts as selected. @@ -3940,7 +4114,7 @@ When called with a negative prefix argument, only update the selected files." (message "Running svn-update for %s" default-directory) (svn-run t t 'update "update" (when rev (list "-r" rev)) - (list "--non-interactive"))))) + (list "--non-interactive") (expand-file-name default-directory))))) (defun svn-status-commit () "Commit selected files. @@ -3956,7 +4130,9 @@ If no files have been marked, commit recursively the file at point." (svn-log-edit-show-files-to-commit) (svn-status-pop-to-commit-buffer) (when svn-log-edit-insert-files-to-commit - (svn-log-edit-insert-files-to-commit)))) + (svn-log-edit-insert-files-to-commit)) + (when svn-log-edit-show-diff-for-commit + (svn-log-edit-svn-diff nil)))) (defun svn-status-pop-to-commit-buffer () "Pop to the svn commit buffer. @@ -4101,6 +4277,104 @@ Recommended values are ?m or ?M.") (add-hook 'after-save-hook 'svn-status-after-save-hook) +;; -------------------------------------------------------------------------------- +;; vc-svn integration +;; -------------------------------------------------------------------------------- +(defvar svn-status-state-mark-modeline t) ; modeline mark display or not +(defvar svn-status-state-mark-tooltip nil) ; modeline tooltip display + +(defun svn-status-state-mark-modeline-dot (color) + (propertize " " + 'help-echo 'svn-status-state-mark-tooltip + 'display + `(image :type xpm + :data ,(format "/* XPM */ +static char * data[] = { +\"18 13 3 1\", +\" c None\", +\"+ c #000000\", +\". c %s\", +\" \", +\" +++++ \", +\" +.....+ \", +\" +.......+ \", +\" +.........+ \", +\" +.........+ \", +\" +.........+ \", +\" +.........+ \", +\" +.........+ \", +\" +.......+ \", +\" +.....+ \", +\" +++++ \", +\" \"};" + color) + :ascent center))) + +(defun svn-status-install-state-mark-modeline (color) + (push `(svn-status-state-mark-modeline + ,(svn-status-state-mark-modeline-dot color)) + mode-line-format) + (force-mode-line-update t)) + +(defun svn-status-uninstall-state-mark-modeline () + (setq mode-line-format + (remove-if #'(lambda (mode) (eq (car-safe mode) + 'svn-status-state-mark-modeline)) + mode-line-format)) + (force-mode-line-update t)) + +(defun svn-status-update-state-mark-tooltip (tooltip) + (setq svn-status-state-mark-tooltip tooltip)) + +(defun svn-status-update-state-mark (color) + (svn-status-uninstall-state-mark-modeline) + (svn-status-install-state-mark-modeline color)) + +(defsubst svn-status-in-vc-mode? () + "Is vc-svn active?" + (and vc-mode (string-match "^ SVN" (svn-substring-no-properties vc-mode)))) + +(when svn-status-fancy-file-state-in-modeline + (defadvice vc-find-file-hook (after svn-status-vc-svn-find-file-hook activate) + "vc-find-file-hook advice for synchronizing psvn with vc-svn interface" + (when (svn-status-in-vc-mode?) (svn-status-update-modeline))) + + (defadvice vc-after-save (after svn-status-vc-svn-after-save activate) + "vc-after-save advice for synchronizing psvn when saving buffer" + (when (svn-status-in-vc-mode?) (svn-status-update-modeline))) + + (defadvice ediff-refresh-mode-lines + (around svn-modeline-ediff-fixup activate compile) + "Fixup svn file status in the modeline when using ediff" + (ediff-with-current-buffer ediff-buffer-A + (svn-status-uninstall-state-mark-modeline)) + (ediff-with-current-buffer ediff-buffer-B + (svn-status-uninstall-state-mark-modeline)) + ad-do-it + (ediff-with-current-buffer ediff-buffer-A + (svn-status-update-modeline)) + (ediff-with-current-buffer ediff-buffer-B + (svn-status-update-modeline)))) + +(defun svn-status-update-modeline () + "Update modeline state dot mark properly" + (when (and buffer-file-name (svn-status-in-vc-mode?)) + (svn-status-update-state-mark + (svn-status-interprete-state-mode-color + (vc-svn-state buffer-file-name))))) + +(defsubst svn-status-interprete-state-mode-color (stat) + "Interpret vc-svn-state symbol to mode line color" + (case stat + ('edited "tomato" ) + ('up-to-date "GreenYellow" ) + ;; what is missing here?? + ;; ('unknown "gray" ) + ;; ('added "blue" ) + ;; ('deleted "red" ) + ;; ('unmerged "purple" ) + (t "red"))) + ;; -------------------------------------------------------------------------------- ;; Getting older revisions ;; -------------------------------------------------------------------------------- @@ -4113,10 +4387,9 @@ When the function is called without a prefix argument: get all marked files. With a prefix argument: get only the actual file." (interactive "P") (svn-status-get-specific-revision-internal - (svn-status-get-file-list (not arg)) - :ask)) + (svn-status-get-file-list (not arg)) :ask t)) -(defun svn-status-get-specific-revision-internal (line-infos revision) +(defun svn-status-get-specific-revision-internal (line-infos revision handle-relative-svn-status-dir) "Retrieve older revisions of files. LINE-INFOS is a list of line-info structures (see `svn-status-get-line-information'). @@ -4167,15 +4440,24 @@ names are relative to the directory where `svn-status' was run." ;; and if users often want to know the revision numbers of such ;; files, they can use svn:keywords. (file-name-with-revision (concat (file-name-nondirectory file-name) ".~" revision "~")) - (default-directory (concat (svn-status-base-dir) (file-name-directory file-name)))) + (default-directory (concat (svn-status-base-dir) + (if handle-relative-svn-status-dir + (file-relative-name default-directory (svn-status-base-dir)) + "") + (file-name-directory file-name)))) ;; `add-to-list' would unnecessarily check for duplicates. - (push (cons file-name (concat (file-name-directory file-name) file-name-with-revision)) svn-status-get-specific-revision-file-info) - ;; (message "file-name-with-revision: %s %S" file-name-with-revision (file-exists-p file-name-with-revision)) + (push (cons file-name (concat (file-name-directory file-name) file-name-with-revision)) + svn-status-get-specific-revision-file-info) + (svn-status-message 3 "svn-status-get-specific-revision-internal: file: %s, default-directory: %s" + file-name default-directory) + (svn-status-message 3 "svn-status-get-specific-revision-internal: file-name-with-revision: %s %S" + file-name-with-revision (file-exists-p file-name-with-revision)) (save-excursion (if (or (not (file-exists-p file-name-with-revision)) ;; file does not exist (not (string= (number-to-string (string-to-number revision)) revision))) ;; revision is not a number (progn - (message "getting revision %s for %s" revision file-name) + (message "Getting revision %s of %s, target: %s" revision file-name + (expand-file-name(concat default-directory file-name-with-revision))) (let ((content (with-temp-buffer (if (string= revision "BASE") @@ -4184,7 +4466,8 @@ names are relative to the directory where `svn-status' was run." (file-name-nondirectory file-name) ".svn-base")) (progn - (svn-run nil t 'cat "cat" "-r" revision (file-name-nondirectory file-name)) + (svn-run nil t 'cat "cat" "-r" revision + (concat default-directory (file-name-nondirectory file-name))) ;;todo: error processing ;;svn: Filesystem has no item ;;svn: file not found: revision `15', path `/trunk/file.txt' @@ -4195,7 +4478,9 @@ names are relative to the directory where `svn-status' was run." (erase-buffer) ;Widen, because we'll save the whole buffer. (insert content) (goto-char (point-min)) - (save-buffer))) + (let ((write-file-functions nil) + (require-final-newline nil)) + (save-buffer)))) (find-file file-name-with-revision))))) ;;(message "default-directory: %s revision-file-info: %S" default-directory svn-status-get-specific-revision-file-info) (nreverse svn-status-get-specific-revision-file-info))) @@ -4214,7 +4499,8 @@ If ARG then prompt for revision to diff against." (svn-status-base-dir)) nil nil nil nil nil nil (svn-status-line-info->update-available (svn-status-get-line-information)))) - (if arg :ask :auto))) + (if arg :ask :auto) + nil)) (ediff-after-quit-destination-buffer (current-buffer)) (default-directory (svn-status-base-dir)) (my-buffer (find-file-noselect (caar svn-status-get-specific-revision-file-info))) @@ -4302,6 +4588,25 @@ When called with a prefix argument, read the data from user as password." (list s use-passwd))) (svn-process-send-string (concat string "\n") send-passwd)) +;; -------------------------------------------------------------------------------- +;; Search interface +;; -------------------------------------------------------------------------------- + +(defun svn-status-grep-files (regexp) + "Run grep on selected file(s). +See `svn-status-marked-files' for what counts as selected." + (interactive "sGrep files for: ") + (unless grep-command + (grep-compute-defaults)) + (grep (format "%s %s %s" grep-command (shell-quote-argument regexp) + (mapconcat 'identity (svn-status-marked-file-names) " ")))) + +(defun svn-status-search-files (search-string) + "Search selected file(s) for a fixed SEARCH-STRING. +See `svn-status-marked-files' for what counts as selected." + (interactive "sSearch files for: ") + (svn-status-grep-files (regexp-quote search-string))) + ;; -------------------------------------------------------------------------------- ;; Property List stuff ;; -------------------------------------------------------------------------------- @@ -4560,10 +4865,16 @@ When called with the prefix arg -, remove Date from the svn:keywords property." (mapcar 'list '("native" "CRLF" "LF" "CR")) nil t))) -(defun svn-status-property-set-executable () - "Set the svn:executable property on the marked files." - (interactive) - (svn-status-property-set-property (svn-status-marked-files) "svn:executable" "*")) +(defun svn-status-property-set-executable (&optional unset) + "Set the svn:executable property on the marked files. +When called with a prefix argument: unset the svn:executable property." + (interactive "P") + (if unset + (progn + (svn-run nil t 'propdel (append (list "propdel" "svn:executable") (svn-status-marked-file-names))) + (message "Unset the svn:executable property for %s" (svn-status-marked-file-names)) + (svn-status-update)) + (svn-status-property-set-property (svn-status-marked-files) "svn:executable" "*"))) (defun svn-status-property-set-mime-type () "Set the svn:mime-type property on the marked files." @@ -4972,8 +5283,11 @@ entry for file with defun. (define-key svn-log-view-mode-map (kbd "p") 'svn-log-view-prev) (define-key svn-log-view-mode-map (kbd "n") 'svn-log-view-next) (define-key svn-log-view-mode-map (kbd "~") 'svn-log-get-specific-revision) + (define-key svn-log-view-mode-map (kbd "f") 'svn-log-get-specific-revision) (define-key svn-log-view-mode-map (kbd "E") 'svn-log-ediff-specific-revision) (define-key svn-log-view-mode-map (kbd "=") 'svn-log-view-diff) + (define-key svn-log-view-mode-map (kbd "#") 'svn-log-mark-partner-revision) + (define-key svn-log-view-mode-map (kbd "x") 'svn-log-exchange-partner-mark-with-point) (define-key svn-log-view-mode-map (kbd "TAB") 'svn-log-next-link) (define-key svn-log-view-mode-map [backtab] 'svn-log-prev-link) (define-key svn-log-view-mode-map (kbd "RET") 'svn-log-find-file-at-point) @@ -4994,6 +5308,8 @@ entry for file with defun. ["Show Changeset" svn-log-view-diff t] ["Ediff file at point" svn-log-ediff-specific-revision t] ["Find file at point" svn-log-find-file-at-point t] + ["Mark as diff against revision" svn-log-mark-partner-revision t] + ["Get older revision for file at point" svn-log-get-specific-revision t] ["Edit log message" svn-log-edit-log-entry t])) (defun svn-log-view-popup-menu (event) @@ -5012,6 +5328,7 @@ entry for file with defun. "Basic keywords in `svn-log-view-mode'.") (put 'svn-log-view-font-basic-lock-keywords 'risky-local-variable t) ;for Emacs 20.7 +(defvar svn-log-view-font-lock-keywords) (define-derived-mode svn-log-view-mode fundamental-mode "svn-log-view" "Major Mode to show the output from svn log. Commands: @@ -5038,6 +5355,50 @@ Commands: (unless (looking-at "Changed paths:") (beginning-of-line 1)))) +(defun svn-log-mark-partner-revision () + "Mark the revision at point to be used as diff against revision." + (interactive) + (let ((start-pos) + (point-at-partner-rev)) + (dolist (ov (overlays-in (point-min) (point-max))) + (when (overlay-get ov 'svn-log-partner-revision) + (setq point-at-partner-rev (and (>= (point) (overlay-start ov)) + (<= (point) (overlay-end ov)))) + (delete-overlay ov))) + (unless point-at-partner-rev + (save-excursion + (when (re-search-backward "^r[0-9]+" nil t 1) + (setq start-pos (point)) + (re-search-forward "^---------------") + (setq overlay (make-overlay start-pos (line-beginning-position 0))) + (overlay-put overlay 'face 'svn-log-partner-highlight-face) + (overlay-put overlay 'svn-log-partner-revision t)))))) + +(defun svn-log-exchange-partner-mark-with-point () + (interactive) + (let ((cur-pos (point)) + (dest-pos)) + (dolist (ov (overlays-in (point-min) (point-max))) + (when (overlay-get ov 'svn-log-partner-revision) + (setq dest-pos (overlay-start ov)))) + (when dest-pos + (svn-log-mark-partner-revision) + (goto-char dest-pos) + (forward-line 3) + (svn-log-view-prev) + (svn-log-view-next)))) + +(defun svn-log-revision-for-diff () + (let ((rev)) + (dolist (ov (overlays-in (point-min) (point-max))) + (when (overlay-get ov 'svn-log-partner-revision) + (save-excursion + (unless (and (>= (point) (overlay-start ov)) + (<= (point) (overlay-end ov))) + (goto-char (overlay-start ov)) + (setq rev (svn-log-revision-at-point)))))) + rev)) + (defun svn-log-revision-at-point () (save-excursion (end-of-line) @@ -5047,19 +5408,26 @@ Commands: (defun svn-log-file-name-at-point (respect-checkout-prefix-path) (let ((full-file-name) (file-name) - (checkout-prefix-path (when respect-checkout-prefix-path (svn-status-checkout-prefix-path)))) + (checkout-prefix-path (if respect-checkout-prefix-path + (url-unhex-string + (svn-status-checkout-prefix-path)) + ""))) (save-excursion (beginning-of-line) (when (looking-at " [MA] /\\(.+\\)$") (setq full-file-name (svn-match-string-no-properties 1)))) (when (string= checkout-prefix-path "") (setq checkout-prefix-path "/")) - (setq file-name - (if (eq (string-match (regexp-quote (substring checkout-prefix-path 1)) full-file-name) 0) - (substring full-file-name (- (length checkout-prefix-path) (if (string= checkout-prefix-path "/") 1 0))) - full-file-name)) - ;; (message "svn-log-file-name-at-point %s prefix: '%s', full-file-name: %s" file-name checkout-prefix-path full-file-name) - file-name)) + (if (null full-file-name) + (progn + (message "No file at point") + nil) + (setq file-name + (if (eq (string-match (regexp-quote (substring checkout-prefix-path 1)) full-file-name) 0) + (substring full-file-name (- (length checkout-prefix-path) (if (string= checkout-prefix-path "/") 1 0))) + full-file-name)) + ;; (message "svn-log-file-name-at-point %s prefix: '%s', full-file-name: %s" file-name checkout-prefix-path full-file-name) + file-name))) (defun svn-log-find-file-at-point () (interactive) @@ -5089,32 +5457,50 @@ Commands: "Show the changeset for a given log entry. When called with a prefix argument, ask the user for the revision." (interactive "P") - (svn-status-diff-show-changeset (svn-log-revision-at-point) arg)) + (svn-status-diff-show-changeset (svn-log-revision-at-point) arg (svn-log-revision-for-diff))) (defun svn-log-get-specific-revision () "Get an older revision of the file at point via svn cat." (interactive) ;; (message "%S" (svn-status-make-line-info (svn-log-file-name-at-point t))) - (let ((default-directory (svn-status-base-dir))) - (svn-status-get-specific-revision-internal - (list (svn-status-make-line-info (svn-log-file-name-at-point nil))) - (svn-log-revision-at-point)))) + (let ((default-directory (svn-status-base-dir)) + (file-name (svn-log-file-name-at-point t))) + (if file-name + (svn-status-get-specific-revision-internal + (list (svn-status-make-line-info file-name)) + (svn-log-revision-at-point) + nil) + (message "No file at point")))) -(defun svn-log-ediff-specific-revision () - "Call ediff for the file at point to view a changeset" - (interactive) +(defun svn-log-ediff-specific-revision (&optional user-confirmation) + "Call ediff for the file at point to view a changeset. +When called with a prefix argument, ask the user for the revision." + (interactive "P") ;; (message "svn-log-ediff-specific-revision: %s" (svn-log-file-name-at-point t)) (let* ((cur-buf (current-buffer)) - (upper-rev (svn-log-revision-at-point)) - (lower-rev (number-to-string (- (string-to-number upper-rev) 1))) + (diff-rev (svn-log-revision-for-diff)) + (upper-rev (if diff-rev + diff-rev + (svn-log-revision-at-point))) + (lower-rev (if diff-rev + (svn-log-revision-at-point) + (number-to-string (- (string-to-number upper-rev) 1)))) (file-name (svn-log-file-name-at-point t)) (default-directory (svn-status-base-dir)) - (upper-rev-file-name (when file-name + (upper-rev-file-name) + (lower-rev-file-name) + (rev-arg)) + (when user-confirmation + (setq rev-arg (read-string "Revision for changeset: " (concat lower-rev ":" upper-rev))) + (setq lower-rev (car (split-string rev-arg ":"))) + (setq upper-rev (cadr (split-string rev-arg ":")))) + ;;(message "lower-rev: %s, upper-rev: %s" lower-rev upper-rev) + (setq upper-rev-file-name (when file-name (cdar (svn-status-get-specific-revision-internal - (list (svn-status-make-line-info file-name)) upper-rev)))) - (lower-rev-file-name (when file-name + (list (svn-status-make-line-info file-name)) upper-rev nil)))) + (setq lower-rev-file-name (when file-name (cdar (svn-status-get-specific-revision-internal - (list (svn-status-make-line-info file-name)) lower-rev))))) + (list (svn-status-make-line-info file-name)) lower-rev nil)))) ;;(message "%S %S" upper-rev-file-name lower-rev-file-name) (if file-name (let* ((ediff-after-quit-destination-buffer cur-buf) @@ -5193,7 +5579,7 @@ HANDLER-FUNCTION is called with the match of LINK-REGEXP when the user clicks at (defun svn-log-resolve-trac-ticket-short (link-name) "Show the trac ticket specified by LINK-NAME via `svn-trac-browse-ticket'." (interactive) - (let ((ticket-nr (string-to-number (substring-no-properties link-name 1)))) + (let ((ticket-nr (string-to-number (svn-substring-no-properties link-name 1)))) (svn-trac-browse-ticket ticket-nr))) ;; register the out of the box provided link handlers @@ -5240,6 +5626,8 @@ Currently is the output from the svn update command known." (progn (beginning-of-line) (re-search-forward ".. +") (point)) (line-end-position))) (pos)) + (when (eq system-type 'windows-nt) + (setq file-name (replace-regexp-in-string "\\\\" "/" file-name))) (goto-char cur-pos) (with-current-buffer svn-status-buffer-name (setq pos (svn-status-get-file-name-buffer-position file-name))) @@ -5253,8 +5641,8 @@ Currently is the output from the svn update command known." (unless (assq 'svn-blame-mode minor-mode-alist) (setq minor-mode-alist - (cons (list 'svn-blame-mode " SvnBlame") - minor-mode-alist))) + (cons (list 'svn-blame-mode " SvnBlame") + minor-mode-alist))) (defvar svn-blame-mode-map () "Keymap used in `svn-blame-mode' buffers.") (put 'svn-blame-mode-map 'risky-local-variable t) ;for Emacs 20.7 @@ -5269,6 +5657,8 @@ Currently is the output from the svn update command known." (define-key svn-blame-mode-map (kbd "r") 'svn-blame-highlight-revision) (define-key svn-blame-mode-map (kbd "=") 'svn-blame-show-changeset) (define-key svn-blame-mode-map (kbd "l") 'svn-blame-show-log) + (define-key svn-blame-mode-map (kbd "b") 'svn-blame-blame-again) + (define-key svn-blame-mode-map (kbd "s") 'svn-blame-show-statistics) (define-key svn-blame-mode-map [?q] 'bury-buffer)) (easy-menu-define svn-blame-mode-menu svn-blame-mode-map @@ -5277,12 +5667,14 @@ Currently is the output from the svn update command known." ["Jump to source location" svn-blame-open-source-file t] ["Show changeset" svn-blame-show-changeset t] ["Show log" svn-blame-show-log t] + ["Show blame again" svn-blame-blame-again t] + ["Show statistics" svn-blame-show-statistics t] ["Highlight by author" svn-blame-highlight-author t] ["Highlight by revision" svn-blame-highlight-revision t])) (or (assq 'svn-blame-mode minor-mode-map-alist) (setq minor-mode-map-alist - (cons (cons 'svn-blame-mode svn-blame-mode-map) minor-mode-map-alist))) + (cons (cons 'svn-blame-mode svn-blame-mode-map) minor-mode-map-alist))) (make-variable-buffer-local 'svn-blame-mode) @@ -5330,7 +5722,9 @@ The current buffer must contain a valid output from svn blame" (delete-region (svn-point-at-bol) (+ (svn-point-at-bol) info-end-col)) (forward-line) (setq line (1+ line))))) - (let* ((buf-name (format "*svn-blame: %s*" (file-relative-name svn-status-blame-file-name))) + (let* ((buf-name (format "*svn-blame: %s <%s>*" + (file-relative-name svn-status-blame-file-name) + svn-status-blame-revision)) (buffer (get-buffer buf-name))) (when buffer (kill-buffer buffer)) @@ -5405,6 +5799,29 @@ The optional prefix argument ARG determines which switches are passed to `svn lo (overlay-put hl-ov 'face 'svn-status-blame-highlight-face)))) (forward-line))))) +(defun svn-blame-show-statistics () + "Show statistics for the current blame buffer." + (interactive) + (let ((author-map (make-hash-table :test 'equal)) + (author-list) + (author)) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (dolist (ov (overlays-in (svn-point-at-bol) (line-end-position))) + (when (overlay-get ov 'svn-blame-line-info) + (setq author (cadr (overlay-get ov 'rev-info))) + (svn-puthash author + (+ (gethash author author-map 0) 1) + author-map))) + (forward-line)) + (maphash '(lambda (key value) (add-to-list 'author-list (list key value))) author-map) + (pop-to-buffer (get-buffer-create (replace-regexp-in-string "svn-blame:" "svn-blame-statistics:" (buffer-name)))) + (erase-buffer) + (dolist (line (sort author-list '(lambda (v1 v2) (> (cadr v1) (cadr v2))))) + (insert (format "%s: %s line%s\n" (car line) (cadr line) (if (eq (cadr line) 1) "" "s")))) + (goto-char (point-min))))) + (defun svn-blame-highlight-author-field (ov) (cadr (overlay-get ov 'rev-info))) diff --git a/sources b/sources index 8d13330..ebd009b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -ec3ae55d43ee87c1c1f57e2411009459 subversion-1.5.2.tar.gz +6a57efcc9e487e9bffc554931c98d3a0 subversion-1.5.3.tar.gz diff --git a/subversion-1.5.3.tar.gz.asc b/subversion-1.5.3.tar.gz.asc new file mode 100644 index 0000000..1369790 --- /dev/null +++ b/subversion-1.5.3.tar.gz.asc @@ -0,0 +1,35 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQBI7Y4MCwOubk4kUXwRApWvAKDV/bGoUIh8BGZpXmC5esCrZPaJpQCeOJ5b +5DIq+fMMkT+MdkzurImGZ7g= +=c5Pp +-----END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.2 (GNU/Linux) + +iD8DBQBI7eIDNR8z5DU+JbwRAu2MAJ9zbxncg+HinohwP5Ar+kKOIcoB6QCbBsiB +bLlGmJiG9HmPCzg19sGwXtk= +=smmB +-----END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.9 (FreeBSD) + +iEYEABECAAYFAkjvYhQACgkQ/P1jBZgh97Jr8gCbBgK1YupuALSuJCs+FT4uIOyM +jwYAn3hystxtjbJS7p7q3mTR36BpEtwo +=LaHL +-----END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQBI7wms9o1G+2zNQDgRAjmnAJ4iaMgPTOytDHd2NOw2FW+B/zCr3wCgrlCj ++egZQjk1zwPmNHuGdIiwvBA= +=IFK3 +-----END PGP SIGNATURE----- +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.9 (Darwin) + +iEYEABECAAYFAkjvfkwACgkQJl34oANalqkVqQCgguM0c7CvRQZXq46KGG9n4zfZ +25kAoL5cSuwQr+tT7P9vm62X18Mv5zLm +=uY5a +-----END PGP SIGNATURE----- diff --git a/subversion.spec b/subversion.spec index eefbc74..6e18479 100644 --- a/subversion.spec +++ b/subversion.spec @@ -14,8 +14,8 @@ Summary: Modern Version Control System designed to replace CVS Name: subversion -Version: 1.5.2 -Release: 3 +Version: 1.5.3 +Release: 2 License: ASL 1.1 Group: Development/Tools URL: http://subversion.tigris.org/ @@ -277,6 +277,10 @@ rm -rf ${RPM_BUILD_ROOT} %endif %changelog +* Mon Oct 13 2008 Joe Orton 1.5.3-2 +- update to 1.5.3 (#466674) +- update psvn.el to r33557 + * Tue Sep 30 2008 Joe Orton 1.5.2-3 - enable SASL support (#464267) diff --git a/upstream b/upstream index 5aedbed..f7d4591 100644 --- a/upstream +++ b/upstream @@ -1 +1 @@ -subversion-1.5.2.tar.gz +subversion-1.5.3.tar.gz