Skip to content

Commit c375e9d

Browse files
committed
git.el: Add a checkout command.
Prompts for a branch name and checks it out. Bound to C-c C-o by default. Based on a patch by Rémi Vanicat <vanicat@debian.org>. Signed-off-by: Alexandre Julliard <julliard@winehq.org>
1 parent ba743d1 commit c375e9d

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

contrib/emacs/git.el

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,8 @@
3939
;; - renaming files from the status buffer
4040
;; - creating tags
4141
;; - fetch/pull
42-
;; - switching branches
4342
;; - revlist browser
4443
;; - git-show-branch browser
45-
;; - menus
4644
;;
4745

4846
(eval-when-compile (require 'cl))
@@ -397,6 +395,17 @@ the process output as a string, or nil if the git command failed."
397395
(unless newval (push "-d" args))
398396
(apply 'git-call-process-display-error "update-ref" args)))
399397

398+
(defun git-for-each-ref (&rest specs)
399+
"Return a list of refs using git-for-each-ref.
400+
Each entry is a cons of (SHORT-NAME . FULL-NAME)."
401+
(let (refs)
402+
(with-temp-buffer
403+
(apply #'git-call-process t "for-each-ref" "--format=%(refname)" specs)
404+
(goto-char (point-min))
405+
(while (re-search-forward "^[^/\n]+/[^/\n]+/\\(.+\\)$" nil t)
406+
(push (cons (match-string 1) (match-string 0)) refs)))
407+
(nreverse refs)))
408+
400409
(defun git-read-tree (tree &optional index-file)
401410
"Read a tree into the index file."
402411
(let ((process-environment
@@ -1356,6 +1365,24 @@ Return the list of files that haven't been handled."
13561365
(push (match-string 1) files)))
13571366
files))
13581367

1368+
(defun git-read-commit-name (prompt &optional default)
1369+
"Ask for a commit name, with completion for local branch, remote branch and tag."
1370+
(completing-read prompt
1371+
(list* "HEAD" "ORIG_HEAD" "FETCH_HEAD" (mapcar #'car (git-for-each-ref)))
1372+
nil nil nil nil default))
1373+
1374+
(defun git-checkout (branch &optional merge)
1375+
"Checkout a branch, tag, or any commit.
1376+
Use a prefix arg if git should merge while checking out."
1377+
(interactive
1378+
(list (git-read-commit-name "Checkout: ")
1379+
current-prefix-arg))
1380+
(unless git-status (error "Not in git-status buffer."))
1381+
(let ((args (list branch "--")))
1382+
(when merge (push "-m" args))
1383+
(when (apply #'git-call-process-display-error "checkout" args)
1384+
(git-update-status-files))))
1385+
13591386
(defun git-amend-commit ()
13601387
"Undo the last commit on HEAD, and set things up to commit an
13611388
amended version of it."
@@ -1471,6 +1498,7 @@ amended version of it."
14711498
(define-key map "\M-\C-?" 'git-unmark-all)
14721499
; the commit submap
14731500
(define-key commit-map "\C-a" 'git-amend-commit)
1501+
(define-key commit-map "\C-o" 'git-checkout)
14741502
; the diff submap
14751503
(define-key diff-map "b" 'git-diff-file-base)
14761504
(define-key diff-map "c" 'git-diff-file-combined)
@@ -1491,6 +1519,7 @@ amended version of it."
14911519
`("Git"
14921520
["Refresh" git-refresh-status t]
14931521
["Commit" git-commit-file t]
1522+
["Checkout..." git-checkout t]
14941523
("Merge"
14951524
["Next Unmerged File" git-next-unmerged-file t]
14961525
["Prev Unmerged File" git-prev-unmerged-file t]

0 commit comments

Comments
 (0)