[PATCH v3 01/03] Add helpers functions for refs and commitish to git.el
git-list-refs list refs
git-refs-build-menu is a function to build menu for refs
git-read-commitish ask the user a commitish, with completion for
branch, local and remote, and tags.
---
contrib/emacs/git.el | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index a8bf0ef..5166fca 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -1138,6 +1138,77 @@ Return the list of files that haven't been handled."
(when (eq (window-buffer) (current-buffer))
(shrink-window-if-larger-than-buffer)))
+(defun git-list-refs (&optional spec)
+ "return a list of refs using git-for-each-refs
+
+if type is nil or :all return all refs
+if it is :branches return local branches
+if it is :remotes return remote branches
+if it is :tags return tags"
+ (let ((ref-spec (cond
+ ((or (eq spec :all) (eq spec ()))
+ "*/*/*")
+ ((eq spec :branches)
+ "refs/heads")
+ ((eq spec :remotes)
+ "refs/remotes")
+ ((eq spec :tags)
+ "refs/tags")
+ (t (error "don't know what to do with %s" spec))))
+ refs)
+ (with-temp-buffer
+ (git-call-process-env t nil "for-each-ref" ref-spec "--format=%(refname)")
+ (goto-char (point-min))
+ (while (re-search-forward "^[^/]+/[^/]+/\\([^\n]*\\)$" () t)
+ (push (cons (match-string 1)
+ (match-string 0))
+ refs)))
+ (nreverse refs)))
+
+(defun git-refs-build-menu-helper (refs fcts)
+ (let ((menu ()))
+ (dolist (branch (git-list-refs refs))
+ (push (funcall fcts (car branch) (cdr branch))
+ menu))
+ (nreverse menu)))
+
+(defun git-refs-build-menu (&rest rest)
+ (let (before branch tag remote after)
+ (while (and rest
+ (cdr rest)
+ (keywordp (car rest)))
+ (cond
+ ((eq :before (car rest))
+ (setq before (cadr rest)))
+ ((eq :branch (car rest))
+ (setq branch (cadr rest)))
+ ((eq :tag (car rest))
+ (setq tag (cadr rest)))
+ ((eq :remote (car rest))
+ (setq remote (cadr rest)))
+ ((eq :after (car rest))
+ (setq after (cadr rest)))
+ ((error "git-refs-build-menu: I don't know this keyword")))
+ (setq rest (cddr rest)))
+ (unless (and (not rest)
+ remote tag branch)
+ (error "bad argument list"))
+ `(,@before
+ ,@(git-refs-build-menu-helper :branches branch)
+ "------"
+ ("Remotes" ,@(git-refs-build-menu-helper :remotes remote))
+ ("Tags" ,@(git-refs-build-menu-helper :tags remote))
+ "------"
+ ,@after)))
+
+(defun git-read-commitish (prompt &optional default)
+ "ask user a commitish, with commpletion for local branch, remote branch and tag"
+ (completing-read prompt (list* "HEAD"
+ "ORIG_HEAD"
+ "FETCH_HEAD"
+ (git-list-refs :all))
+ () () () () default))
+
(defun git-diff-file ()
"Diff the marked file(s) against HEAD."
(interactive)
--
1.5.4.1.123.gcb68-dirty