     (list (str path "@" r1) (str path "@" r2))
     (list (str "-r" r1 ":" r2) path)))
   
+(defn baseitem [item] (clojure.string/replace item #"@[0-9]+$" ""))
+
 ;; A string containing the output of "diff" on the two svn revision of item.
 
 (defn diff [r1 r2 item]
-  (let [v (vpaths r1 r2 item item)]
+  (let [item (baseitem item)
+        v (vpaths r1 r2 item item)]
     (sh "svn" "diff" "--diff-cmd" "diff" "-x" "-u0" shhh (first v) (second v))))
 
 ;; Obtain a diff from svn for the given item between the specified revisions.

;; copy to avoid following the history of a differently-named object.

(defn log [item] (:out (sh "svn" "log" shhh "--stop-on-copy" "--xml" item)))
;;(defn log [item] (slurp "xml"))

;; Try to explain why this has failed.


;; vector of the names of files where the filter term appears on a changed line.
;; If no filter term is given, a changed file automatically matches.

(defn matching-files [r1 r2 item filt]
  (let [blocks (rest (split (:out (diff r1 r2 item)) #"^Index: |\nIndex: "))]
    (remove nil?
            (into []
                  (for [block blocks]
                    (let [matching-line-in? #(re-matches (re-pattern filt) %)
                          diff-line? #(re-matches #"^[+-][^+-].*" %)
                          strip+- #(clojure.string/replace % #"^[+-]" "")
                          all-lines (split-lines block)
                          diff-lines (filter diff-line? all-lines)
                          changes (map strip+- diff-lines)
                          filename (trim (first all-lines))]
                      (if (some matching-line-in? changes) filename)))))))

;; Run "svn diff" on the file/pathname in object. The format of the file/path
;; name following "Index:" in diff's output depends on the argument: If the
;; argument is a filesystem pathname, the object name is absolute, and we can
;; simply use that. If the argument is a uri, the object name is relative to the
;; base item name. If the base item name was the uri to a file (and therefore a
;; complete pathname) we can use item; if it was the uri to a directory, we have
;; to concatenate the item and object to form a complete pathname.

(defn svndiff [r1 r2 object item]
  (let [item (baseitem item)
        r (re-pattern (str "^.*/" object "$"))
        p (if (uri? item)
            (if (re-matches r item) item (str item "/" object))
            object)
        v (vpaths r1 r2 p item)]
    (sh "svn" "diff" (first v) (second v))))

;; Given a list of revision pairs, diff those for which the given filter term
;; (if any) is present on a changed line in that pair. If no filter term is
;; given, diff all changed files from all revision pairs.

(defn diffrevpairs [item filt revpairs]
  (when (seq revpairs)
    (let [r1 (first revpairs)
          r2 (first (rest revpairs))
          mf (matching-files r1 r2 item filt)]
      (println (str "Checking: r" r1 " vs r" r2))
      (doseq [object mf] (svndiff r1 r2 object item))
      (diffrevpairs item filt (rest (rest revpairs))))))

(defn usage []
  (println (str "\nUsage: revdiff item [regex]\n"))
  (println "  item  : svn uri or name of versioned working-copy object")
  (println "  regex : only show diffs where a changed line matches regex\n"))

(defn -main [& args]
  (let [item (first args) filt (or (second args) ".*")]
    (if (not item)
      (usage)
      (do
        (diffrevpairs item filt (revpairs (revlist item) item))
        (shutdown-agents)))))
