         (push (match-string 1) files)))
     files))
 
+(defun git-read-commit-name (prompt &optional default)
+  "Ask for a commit name, with completion for local branch, remote branch and tag."
+  (completing-read prompt
+                   (list* "HEAD" "ORIG_HEAD" "FETCH_HEAD" (mapcar #'car (git-for-each-ref)))
+		   nil nil nil nil default))
+
+(defun git-checkout (branch &optional merge)
+  "Checkout a branch, tag, or any commit.
+Use a prefix arg if git should merge while checking out."
+  (interactive
+   (list (git-read-commit-name "Checkout: ")
+         current-prefix-arg))
+  (unless git-status (error "Not in git-status buffer."))
+  (let ((args (list branch "--")))
+    (when merge (push "-m" args))
+    (when (apply #'git-call-process-display-error "checkout" args)
+      (git-update-status-files))))
+
 (defun git-amend-commit ()
   "Undo the last commit on HEAD, and set things up to commit an
 amended version of it."

;;  - renaming files from the status buffer
;;  - creating tags
;;  - fetch/pull
;;  - switching branches
;;  - revlist browser
;;  - git-show-branch browser
;;  - menus
;;

(eval-when-compile (require 'cl))

    `("Git"
      ["Refresh" git-refresh-status t]
      ["Commit" git-commit-file t]
      ["Checkout..." git-checkout t]
      ("Merge"
	["Next Unmerged File" git-next-unmerged-file t]
	["Prev Unmerged File" git-prev-unmerged-file t]
