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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html