From 8ea39540d951a5d5dd3a7afd4bb3af6fc4692135 Mon Sep 17 00:00:00 2001 From: Phil Jackson Date: Wed, 28 Oct 2009 20:37:35 +0000 Subject: [PATCH] A simple caching mechanism to ease the `magit-get-svn-ref-info' pain. * magit.el: Every call to `magit-get-svn-ref-info', post the first, retrieves a cached list. --- magit.el | 90 +++++++++++++++++++++++++++++------------------------ magit.etest | 6 ++-- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/magit.el b/magit.el index 975fb13f..87881d8f 100644 --- a/magit.el +++ b/magit.el @@ -1935,17 +1935,17 @@ in log buffer." "log" "--pretty=format:* %H %s" (format "%s/%s..HEAD" remote branch))) -(defun magit-insert-unpulled-svn-commits () +(defun magit-insert-unpulled-svn-commits (&optional use-cache) (magit-git-section 'svn-unpulled "Unpulled commits (SVN):" 'magit-wash-log "log" "--pretty=format:* %H %s" - (format "HEAD..%s" (magit-get-svn-ref)))) + (format "HEAD..%s" (magit-get-svn-ref use-cache)))) -(defun magit-insert-unpushed-svn-commits () +(defun magit-insert-unpushed-svn-commits (&optional use-cache) (magit-git-section 'svn-unpushed "Unpushed commits (SVN):" 'magit-wash-log "log" "--pretty=format:* %H %s" - (format "%s..HEAD" (magit-get-svn-ref)))) + (format "%s..HEAD" (magit-get-svn-ref use-cache)))) ;;; Status @@ -1954,19 +1954,19 @@ in log buffer." (magit-with-section 'status nil (let* ((branch (magit-get-current-branch)) (remote (and branch (magit-get "branch" branch "remote"))) - (svn-enabled (magit-svn-enabled)) + (svn-enabled (magit-svn-enabled)) (head (magit-git-string "log" "--max-count=1" "--abbrev-commit" "--pretty=oneline")) (no-commit (not head))) (if remote (insert (format "Remote: %s %s\n" remote (magit-get "remote" remote "url")))) - (insert (format "Local: %s %s\n" + (insert (format "Local: %s %s\n" (propertize (or branch "(detached)") 'face 'magit-branch) (abbreviate-file-name default-directory))) - (insert (format "Head: %s\n" - (if no-commit "nothing commited (yet)" head))) + (insert (format "Head: %s\n" + (if no-commit "nothing commited (yet)" head))) (let ((merge-heads (magit-file-lines ".git/MERGE_HEAD"))) (if merge-heads (insert (format "Merging: %s\n" @@ -1977,7 +1977,7 @@ in log buffer." (if rebase (insert (apply 'format "Rebasing: %s (%s of %s)\n" rebase)))) (insert "\n") - (magit-git-exit-code "update-index" "--refresh") + (magit-git-exit-code "update-index" "--refresh") (magit-insert-untracked-files) (magit-insert-stashes) (magit-insert-topics) @@ -1985,8 +1985,8 @@ in log buffer." (magit-insert-pending-commits) (when remote (magit-insert-unpulled-commits remote branch)) - (when svn-enabled - (magit-insert-unpulled-svn-commits)) + (when svn-enabled + (magit-insert-unpulled-svn-commits t)) (let ((staged (or no-commit (magit-anything-staged-p)))) (magit-insert-unstaged-changes (if staged "Unstaged changes:" "Changes:")) @@ -1994,8 +1994,8 @@ in log buffer." (magit-insert-staged-changes no-commit))) (when remote (magit-insert-unpushed-commits remote branch)) - (when svn-enabled - (magit-insert-unpushed-svn-commits)))))) + (when svn-enabled + (magit-insert-unpushed-svn-commits t)))))) (defun magit-init (dir) "Initialize git repository in specified directory" @@ -2190,40 +2190,48 @@ in log buffer." (magit-run-git-async "svn" "dcommit")) (defun magit-svn-enabled () - (not (null (magit-get "svn-remote" "svn" "fetch")))) + (not (null (magit-get-svn-ref-info)))) -(defun magit-get-svn-ref-info () +(defvar magit-get-svn-ref-info-cache nil + "As `magit-get-svn-ref-info' might be considered a quite + expensive operation a cache is taken so that `magit-status' + doesn't repeatedly call it.") + +(defun magit-get-svn-ref-info (&optional use-cache) "Gather details about the current git-svn repository (nil if there isn't one). Keys of the alist are ref-path, trunk-ref-name -and local-ref-name." - (let* ((fetch (magit-get "svn-remote" "svn" "fetch")) - (branches (magit-get "svn-remote" "svn" "fetch"))) - (when fetch - (list - (cons 'ref-path (file-name-directory - (cadr (split-string fetch ":")))) - (cons 'trunk-ref-name (file-name-nondirectory - (cadr (split-string fetch ":")))) - ;; get the local ref from the log. This is actually - ;; the way that git-svn does it. - (cons 'local-ref-name - (with-temp-buffer - (insert (magit-git-string "log" "--first-parent")) - (goto-char (point-min)) - (when (re-search-forward "git-svn-id: .+/\\(.+?\\)@" nil t) - (match-string 1)))))))) +and local-ref-name. If USE-CACHE is non-nil then return the value +of `magit-get-svn-ref-info-cache'." + (if use-cache + magit-get-svn-ref-info-cache + (let* ((fetch (magit-get "svn-remote" "svn" "fetch")) + (branches (magit-get "svn-remote" "svn" "fetch")) + (url) + (revision)) + (when fetch + (setq magit-get-svn-ref-info-cache + (list + (cons 'ref-path (file-name-directory + (cadr (split-string fetch ":")))) + (cons 'trunk-ref-name (file-name-nondirectory + (cadr (split-string fetch ":")))) + ;; get the local ref from the log. This is actually + ;; the way that git-svn does it. + (cons 'local-ref-name + (with-temp-buffer + (insert (magit-git-string "log" "--first-parent")) + (goto-char (point-min)) + (when (re-search-forward "git-svn-id: \\(.+/\\(.+?\\)\\)@\\([0-9]+\\)" nil t) + (setq url (match-string 1) + revision (match-string 3)) + (match-string 2)))) + (cons 'revision revision) + (cons 'url url))))))) -(defun magit-get-svn-trunk-ref () - "Get the best guess remote trunk ref for the current git-svn -based branch." - (let ((info (magit-get-svn-ref-info))) - (concat (cdr (assoc 'ref-path info)) - (cdr (assoc 'trunk-ref-name info))))) - -(defun magit-get-svn-ref () +(defun magit-get-svn-ref (&optional use-cache) "Get the best guess remote ref for the current git-svn based branch." - (let ((info (magit-get-svn-ref-info))) + (let ((info (magit-get-svn-ref-info use-cache))) (concat (cdr (assoc 'ref-path info)) (cdr (assoc 'local-ref-name info))))) diff --git a/magit.etest b/magit.etest index 66afcea8..56724fc1 100644 --- a/magit.etest +++ b/magit.etest @@ -7,10 +7,10 @@ (stub magit-get => "someproject/trunk:refs/remotes/hello/trunk") (magit-get-svn-ref-info))) '(trunk-ref-name . "trunk") - "correct refpath from `magit-get-svn-ref-info'") - (equal (assoc 'refpath + "correct trunk-ref-name from `magit-get-svn-ref-info'") + (equal (assoc 'ref-path (with-mock (stub magit-get => "someproject/trunk:refs/remotes/hello/trunk") (magit-get-svn-ref-info))) '(refpath . "refs/remotes/hello/") - "correct refpath from `magit-get-svn-ref-info'"))) + "correct refpath from `magit-get-svn-ref-info'"))) \ No newline at end of file